diff --git a/pkg/tapo/client.go b/pkg/tapo/client.go index 6955fa4d..ed79e500 100644 --- a/pkg/tapo/client.go +++ b/pkg/tapo/client.go @@ -75,6 +75,12 @@ func (c *Client) newConn() (net.Conn, error) { return nil, err } + query := u.Query() + + if deviceId := query.Get("deviceId"); deviceId != "" { + req.URL.RawQuery = "deviceId=" + deviceId + } + req.URL.User = u.User req.Header.Set("Content-Type", "multipart/mixed; boundary=--client-stream-boundary--") @@ -91,7 +97,6 @@ func (c *Client) newConn() (net.Conn, error) { c.newDectypter(res) } - query := u.Query() channel := query.Get("channel") if channel == "" { channel = "0" @@ -277,6 +282,7 @@ func dial(req *http.Request) (net.Conn, *http.Response, error) { if err != nil { return nil, nil, err } + _ = res.Body.Close() // ignore response body auth := res.Header.Get("WWW-Authenticate") @@ -301,14 +307,19 @@ func dial(req *http.Request) (net.Conn, *http.Response, error) { ha1 := tcp.HexMD5(username, realm, password) ha2 := tcp.HexMD5(req.Method, uri) nc := "00000001" - cnonce := "00000001" + cnonce := core.RandString(32, 64) response := tcp.HexMD5(ha1, nonce, nc, cnonce, qop, ha2) + // https://datatracker.ietf.org/doc/html/rfc7616 header := fmt.Sprintf( `Digest username="%s", realm="%s", nonce="%s", uri="%s", qop=%s, nc=%s, cnonce="%s", response="%s"`, username, realm, nonce, uri, qop, nc, cnonce, response, ) + if opaque := tcp.Between(auth, `opaque="`, `"`); opaque != "" { + header += fmt.Sprintf(`, opaque="%s", algorithm=MD5`, opaque) + } + req.Header.Set("Authorization", header) if err = req.Write(conn); err != nil {