diff --git a/main.go b/main.go index fd67887..bbd4781 100644 --- a/main.go +++ b/main.go @@ -22,5 +22,11 @@ func main() { if err != nil { panic(err) } + + err = wndc.ServerCredentials(context.TODO()) + if err != nil { + panic(err) + } fmt.Printf("wndc=%#v\n", wndc) + fmt.Printf("Username = %s\nPassword = %s\n", wndc.ProxyUsername, wndc.ProxyPassword) } diff --git a/wndclient/messages.go b/wndclient/messages.go index dd77470..4188670 100644 --- a/wndclient/messages.go +++ b/wndclient/messages.go @@ -31,3 +31,10 @@ type UsersResponse struct { LocationHash string `json:"loc_hash"` } `json:"data"` } + +type ServerCredentialsResponse struct { + Data *struct { + Username []byte `json:"username"` + Password []byte `json:"password"` + } `json:"data"` +} diff --git a/wndclient/wndclient.go b/wndclient/wndclient.go index 2fbffd7..064813e 100644 --- a/wndclient/wndclient.go +++ b/wndclient/wndclient.go @@ -9,7 +9,8 @@ import ( "io" "io/ioutil" "net/http" - //"net/url" + "net/url" + "strconv" "sync" ) @@ -74,6 +75,8 @@ type WndClient struct { UserID string SessionAuthHash string Mux sync.Mutex + ProxyUsername string + ProxyPassword string } type StrKV map[string]string @@ -167,6 +170,38 @@ func (c *WndClient) Users(ctx context.Context) error { return nil } +func (c *WndClient) ServerCredentials(ctx context.Context) error { + c.Mux.Lock() + defer c.Mux.Unlock() + + clientAuthHash, authTime := MakeAuthHash(c.Settings.ClientAuthSecret) + + requestUrl, err := url.Parse(c.Settings.Endpoints.ServerCredentials) + if err != nil { + return err + } + queryValues := requestUrl.Query() + queryValues.Set("client_auth_hash", clientAuthHash) + queryValues.Set("session_auth_hash", c.SessionAuthHash) + queryValues.Set("time", strconv.FormatInt(authTime, 10)) + requestUrl.RawQuery = queryValues.Encode() + + var output ServerCredentialsResponse + + err = c.getJSON(ctx, requestUrl.String(), &output) + if err != nil { + return err + } + if output.Data == nil { + return ErrNoDataInResponse + } + + c.ProxyUsername = string(output.Data.Username) + c.ProxyPassword = string(output.Data.Password) + + return nil +} + func (c *WndClient) postJSON(ctx context.Context, endpoint string, input, output interface{}) error { var reqBuf bytes.Buffer reqEncoder := json.NewEncoder(&reqBuf) @@ -209,6 +244,40 @@ func (c *WndClient) postJSON(ctx context.Context, endpoint string, input, output return nil } +func (c *WndClient) getJSON(ctx context.Context, requestUrl string, output interface{}) error { + req, err := http.NewRequestWithContext( + ctx, + "GET", + requestUrl, + nil, + ) + if err != nil { + return err + } + + c.populateRequest(req) + req.Header.Set("Accept", "*/*") + + resp, err := c.httpClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode < 200 || resp.StatusCode > 299 { + return fmt.Errorf("bad http status: %s, headers: %#v", resp.Status, resp.Header) + } + + decoder := json.NewDecoder(resp.Body) + err = decoder.Decode(output) + cleanupBody(resp.Body) + + if err != nil { + return err + } + + return nil +} + func (c *WndClient) populateRequest(req *http.Request) { req.Header.Set("User-Agent", c.Settings.UserAgent) req.Header.Set("Origin", c.Settings.Origin)