use random session id in auth process
This commit is contained in:
+36
-9
@@ -1,6 +1,7 @@
|
|||||||
package wyze
|
package wyze
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -310,7 +311,7 @@ func (c *Client) doAVLogin() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) doKAuth() error {
|
func (c *Client) doKAuth() error {
|
||||||
// Step 1: K10000 -> K10001
|
// Step 1: K10000 -> K10001 (Challenge)
|
||||||
data, err := c.conn.WriteAndWaitIOCtrl(KCmdAuth, c.buildK10000(), KCmdChallenge, 10*time.Second)
|
data, err := c.conn.WriteAndWaitIOCtrl(KCmdAuth, c.buildK10000(), KCmdChallenge, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("wyze: K10001 failed: %w", err)
|
return fmt.Errorf("wyze: K10001 failed: %w", err)
|
||||||
@@ -321,16 +322,36 @@ func (c *Client) doKAuth() error {
|
|||||||
return fmt.Errorf("wyze: K10001 parse failed: %w", err)
|
return fmt.Errorf("wyze: K10001 parse failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: K10002 -> K10009
|
if c.verbose {
|
||||||
data, err = c.conn.WriteAndWaitIOCtrl(KCmdChallengeResp, c.buildK10002(challenge, status), KCmdAuthResult, 10*time.Second)
|
fmt.Printf("[Wyze] K10001 challenge received, status=%d\n", status)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("wyze: K10009 failed: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
authResp, _ := c.parseK10003(data)
|
// Step 2: K10002 -> K10003 (Auth)
|
||||||
|
data, err = c.conn.WriteAndWaitIOCtrl(KCmdChallengeResp, c.buildK10002(challenge, status), KCmdAuthResult, 10*time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("wyze: K10002 failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse K10003 response
|
||||||
|
authResp, err := c.parseK10003(data)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("wyze: K10003 parse failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.verbose && authResp != nil {
|
||||||
|
if jsonBytes, err := json.MarshalIndent(authResp, "", " "); err == nil {
|
||||||
|
fmt.Printf("[Wyze] K10003 response:\n%s\n", jsonBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract audio capability from cameraInfo
|
||||||
if authResp != nil && authResp.CameraInfo != nil {
|
if authResp != nil && authResp.CameraInfo != nil {
|
||||||
if audio, ok := authResp.CameraInfo["audio"].(bool); ok {
|
if channelResult, ok := authResp.CameraInfo["channelRequestResult"].(map[string]any); ok {
|
||||||
c.hasAudio = audio
|
if audio, ok := channelResult["audio"].(string); ok {
|
||||||
|
c.hasAudio = audio == "1"
|
||||||
|
} else {
|
||||||
|
c.hasAudio = true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c.hasAudio = true
|
c.hasAudio = true
|
||||||
}
|
}
|
||||||
@@ -338,6 +359,10 @@ func (c *Client) doKAuth() error {
|
|||||||
c.hasAudio = true
|
c.hasAudio = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.verbose {
|
||||||
|
fmt.Printf("[Wyze] K10003 auth success\n")
|
||||||
|
}
|
||||||
|
|
||||||
if avResp := c.conn.GetAVLoginResponse(); avResp != nil {
|
if avResp := c.conn.GetAVLoginResponse(); avResp != nil {
|
||||||
c.hasIntercom = avResp.TwoWayStreaming == 1
|
c.hasIntercom = avResp.TwoWayStreaming == 1
|
||||||
}
|
}
|
||||||
@@ -362,13 +387,15 @@ func (c *Client) buildK10000() []byte {
|
|||||||
|
|
||||||
func (c *Client) buildK10002(challenge []byte, status byte) []byte {
|
func (c *Client) buildK10002(challenge []byte, status byte) []byte {
|
||||||
resp := crypto.GenerateChallengeResponse(challenge, c.enr, status)
|
resp := crypto.GenerateChallengeResponse(challenge, c.enr, status)
|
||||||
|
sessionID := make([]byte, 4)
|
||||||
|
rand.Read(sessionID)
|
||||||
b := make([]byte, 38)
|
b := make([]byte, 38)
|
||||||
copy(b, "HL") // magic
|
copy(b, "HL") // magic
|
||||||
b[2] = 5 // version
|
b[2] = 5 // version
|
||||||
binary.LittleEndian.PutUint16(b[4:], KCmdChallengeResp) // 10002
|
binary.LittleEndian.PutUint16(b[4:], KCmdChallengeResp) // 10002
|
||||||
b[6] = 22 // payload len
|
b[6] = 22 // payload len
|
||||||
copy(b[16:], resp[:16]) // challenge response
|
copy(b[16:], resp[:16]) // challenge response
|
||||||
copy(b[32:], c.uid[:4]) // UID prefix
|
copy(b[32:], sessionID) // random session ID
|
||||||
b[36] = 1 // video enabled
|
b[36] = 1 // video enabled
|
||||||
b[37] = 1 // audio enabled
|
b[37] = 1 // audio enabled
|
||||||
return b
|
return b
|
||||||
|
|||||||
Reference in New Issue
Block a user