Add lock for updating cookies
This commit is contained in:
parent
1d3ef74817
commit
d70ddb415b
8 changed files with 61 additions and 41 deletions
|
@ -36,14 +36,57 @@ type AuthData struct {
|
|||
// Unknown encryption key, not used for anything
|
||||
WebEncryptionKey []byte `json:"web_encryption_key,omitempty"`
|
||||
|
||||
SessionID uuid.UUID `json:"session_id,omitempty"`
|
||||
DestRegID uuid.UUID `json:"dest_reg_id,omitempty"`
|
||||
PairingID uuid.UUID `json:"pairing_id,omitempty"`
|
||||
Cookies map[string]string `json:"cookies,omitempty"`
|
||||
SessionID uuid.UUID `json:"session_id,omitempty"`
|
||||
DestRegID uuid.UUID `json:"dest_reg_id,omitempty"`
|
||||
PairingID uuid.UUID `json:"pairing_id,omitempty"`
|
||||
|
||||
Cookies map[string]string `json:"cookies,omitempty"`
|
||||
CookiesLock sync.RWMutex `json:"-"`
|
||||
}
|
||||
|
||||
func (ad *AuthData) SetCookies(cookies map[string]string) {
|
||||
ad.CookiesLock.Lock()
|
||||
ad.Cookies = cookies
|
||||
ad.CookiesLock.Unlock()
|
||||
}
|
||||
|
||||
func (ad *AuthData) AddCookiesToRequest(req *http.Request) {
|
||||
ad.CookiesLock.RLock()
|
||||
defer ad.CookiesLock.RUnlock()
|
||||
if ad.Cookies == nil {
|
||||
return
|
||||
}
|
||||
for name, value := range ad.Cookies {
|
||||
req.AddCookie(&http.Cookie{Name: name, Value: value})
|
||||
}
|
||||
sapisid, ok := ad.Cookies["SAPISID"]
|
||||
if ok {
|
||||
req.Header.Set("Authorization", sapisidHash(util.MessagesBaseURL, sapisid))
|
||||
}
|
||||
}
|
||||
|
||||
func (ad *AuthData) UpdateCookiesFromResponse(resp *http.Response) {
|
||||
ad.CookiesLock.Lock()
|
||||
defer ad.CookiesLock.Unlock()
|
||||
if ad.Cookies == nil {
|
||||
return
|
||||
}
|
||||
for _, cookie := range resp.Cookies() {
|
||||
ad.Cookies[cookie.Name] = cookie.Value
|
||||
}
|
||||
}
|
||||
|
||||
func (ad *AuthData) HasCookies() bool {
|
||||
if ad == nil {
|
||||
return false
|
||||
}
|
||||
ad.CookiesLock.RLock()
|
||||
defer ad.CookiesLock.RUnlock()
|
||||
return ad.Cookies != nil
|
||||
}
|
||||
|
||||
func (ad *AuthData) AuthNetwork() string {
|
||||
if ad.Cookies != nil {
|
||||
if ad.HasCookies() {
|
||||
return util.GoogleNetwork
|
||||
}
|
||||
return ""
|
||||
|
@ -253,11 +296,11 @@ func (c *Client) FetchConfig() (*gmproto.Config, error) {
|
|||
req.Header.Set("sec-fetch-site", "same-origin")
|
||||
req.Header.Del("x-user-agent")
|
||||
req.Header.Del("origin")
|
||||
c.AddCookieHeaders(req)
|
||||
c.AuthData.AddCookiesToRequest(req)
|
||||
|
||||
resp, err := c.http.Do(req)
|
||||
if resp != nil {
|
||||
c.HandleCookieUpdates(resp)
|
||||
c.AuthData.UpdateCookiesFromResponse(resp)
|
||||
}
|
||||
config, err := typedHTTPResponse[*gmproto.Config](resp, err)
|
||||
if err != nil {
|
||||
|
|
|
@ -112,7 +112,7 @@ func main() {
|
|||
|
||||
func saveSession() {
|
||||
file := mustReturn(os.OpenFile("session.json", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600))
|
||||
must(json.NewEncoder(file).Encode(sess))
|
||||
must(json.NewEncoder(file).Encode(&sess))
|
||||
_ = file.Close()
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ func (c *Client) makeProtobufHTTPRequestContext(ctx context.Context, url string,
|
|||
return nil, err
|
||||
}
|
||||
util.BuildRelayHeaders(req, contentType, "*/*")
|
||||
c.AddCookieHeaders(req)
|
||||
c.AuthData.AddCookiesToRequest(req)
|
||||
client := c.http
|
||||
if longPoll {
|
||||
client = c.lphttp
|
||||
|
@ -56,32 +56,10 @@ func (c *Client) makeProtobufHTTPRequestContext(ctx context.Context, url string,
|
|||
if reqErr != nil {
|
||||
return res, reqErr
|
||||
}
|
||||
c.HandleCookieUpdates(res)
|
||||
c.AuthData.UpdateCookiesFromResponse(res)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) AddCookieHeaders(req *http.Request) {
|
||||
if c.AuthData == nil || c.AuthData.Cookies == nil {
|
||||
return
|
||||
}
|
||||
for k, v := range c.AuthData.Cookies {
|
||||
req.AddCookie(&http.Cookie{Name: k, Value: v})
|
||||
}
|
||||
sapisid, ok := c.AuthData.Cookies["SAPISID"]
|
||||
if ok {
|
||||
req.Header.Set("Authorization", sapisidHash(util.MessagesBaseURL, sapisid))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) HandleCookieUpdates(resp *http.Response) {
|
||||
if c.AuthData.Cookies == nil {
|
||||
return
|
||||
}
|
||||
for _, cookie := range resp.Cookies() {
|
||||
c.AuthData.Cookies[cookie.Name] = cookie.Value
|
||||
}
|
||||
}
|
||||
|
||||
func sapisidHash(origin, sapisid string) string {
|
||||
ts := time.Now().Unix()
|
||||
hash := sha1.Sum([]byte(fmt.Sprintf("%d %s %s", ts, sapisid, origin)))
|
||||
|
|
|
@ -289,9 +289,8 @@ func (c *Client) doLongPoll(loggedIn bool, onFirstConnect func()) {
|
|||
},
|
||||
}
|
||||
url := util.ReceiveMessagesURL
|
||||
if c.AuthData.Cookies != nil {
|
||||
if c.AuthData.HasCookies() {
|
||||
url = util.ReceiveMessagesURLGoogle
|
||||
payload.Auth.Network = util.GoogleNetwork
|
||||
}
|
||||
resp, err := c.makeProtobufHTTPRequestContext(ctx, url, payload, ContentTypePBLite, true)
|
||||
if err != nil {
|
||||
|
|
|
@ -152,7 +152,7 @@ func (c *Client) UnpairBugle() (*gmproto.RevokeRelayPairingResponse, error) {
|
|||
}
|
||||
|
||||
func (c *Client) Unpair() (err error) {
|
||||
if c.AuthData.Cookies != nil {
|
||||
if c.AuthData.HasCookies() {
|
||||
err = c.UnpairGaia()
|
||||
} else {
|
||||
_, err = c.UnpairBugle()
|
||||
|
|
|
@ -255,7 +255,7 @@ type primaryDeviceID struct {
|
|||
}
|
||||
|
||||
func (c *Client) DoGaiaPairing(ctx context.Context, emojiCallback func(string)) error {
|
||||
if len(c.AuthData.Cookies) == 0 {
|
||||
if !c.AuthData.HasCookies() {
|
||||
return ErrNoCookies
|
||||
}
|
||||
sigResp, err := c.signInGaiaGetToken(ctx)
|
||||
|
|
|
@ -38,7 +38,7 @@ func (s *SessionHandler) sendMessageNoResponse(params SendMessageParams) error {
|
|||
}
|
||||
|
||||
url := util.SendMessageURL
|
||||
if s.client.AuthData.Cookies != nil {
|
||||
if s.client.AuthData.HasCookies() {
|
||||
url = util.SendMessageURLGoogle
|
||||
}
|
||||
_, err = typedHTTPResponse[*gmproto.OutgoingRPCResponse](
|
||||
|
@ -55,7 +55,7 @@ func (s *SessionHandler) sendAsyncMessage(params SendMessageParams) (<-chan *Inc
|
|||
|
||||
ch := s.waitResponse(requestID)
|
||||
url := util.SendMessageURL
|
||||
if s.client.AuthData.Cookies != nil {
|
||||
if s.client.AuthData.HasCookies() {
|
||||
url = util.SendMessageURLGoogle
|
||||
}
|
||||
_, err = typedHTTPResponse[*gmproto.OutgoingRPCResponse](
|
||||
|
@ -100,7 +100,7 @@ func (s *SessionHandler) receiveResponse(msg *IncomingRPCMessage) bool {
|
|||
if msg.Message == nil {
|
||||
return false
|
||||
}
|
||||
if s.client.AuthData.Cookies != nil {
|
||||
if s.client.AuthData.HasCookies() {
|
||||
switch msg.Message.Action {
|
||||
case gmproto.ActionType_CREATE_GAIA_PAIRING_CLIENT_INIT, gmproto.ActionType_CREATE_GAIA_PAIRING_CLIENT_FINISHED:
|
||||
default:
|
||||
|
@ -291,7 +291,7 @@ func (s *SessionHandler) sendAckRequest() {
|
|||
Acks: ackMessages,
|
||||
}
|
||||
url := util.AckMessagesURL
|
||||
if s.client.AuthData.Cookies != nil {
|
||||
if s.client.AuthData.HasCookies() {
|
||||
url = util.AckMessagesURLGoogle
|
||||
}
|
||||
_, err := typedHTTPResponse[*gmproto.OutgoingRPCResponse](
|
||||
|
|
2
user.go
2
user.go
|
@ -555,7 +555,7 @@ func (user *User) LoginGoogle(ctx context.Context, cookies map[string]string, em
|
|||
user.pairSuccessChan = nil
|
||||
}()
|
||||
authData := libgm.NewAuthData()
|
||||
authData.Cookies = cookies
|
||||
authData.SetCookies(cookies)
|
||||
user.createClient(authData)
|
||||
Analytics.Track(user.MXID, "$login_start", map[string]any{"mode": "google"})
|
||||
user.Client.GaiaHackyDeviceSwitcher = user.gaiaHackyDeviceSwitcher
|
||||
|
|
Loading…
Reference in a new issue