mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
feat: token login.
This commit is contained in:
parent
ede433b4f6
commit
369e834557
@ -1,6 +1,7 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@ -352,6 +353,53 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
|||||||
return seq, packet
|
return seq, packet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) buildRequestChangeSigPacket() (uint16, []byte) {
|
||||||
|
seq := c.nextSeq()
|
||||||
|
req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) {
|
||||||
|
w.WriteUInt16(11)
|
||||||
|
w.WriteUInt16(17)
|
||||||
|
|
||||||
|
w.Write(tlv.T100(c.version.SSOVersion, 100, c.version.MainSigMap))
|
||||||
|
w.Write(tlv.T10A(c.sigInfo.tgt))
|
||||||
|
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||||
|
w.Write(tlv.T108(SystemDeviceInfo.IMEI))
|
||||||
|
h := md5.Sum(c.sigInfo.d2Key)
|
||||||
|
w.Write(tlv.T144(
|
||||||
|
SystemDeviceInfo.AndroidId,
|
||||||
|
SystemDeviceInfo.GenDeviceInfoData(),
|
||||||
|
SystemDeviceInfo.OSType,
|
||||||
|
SystemDeviceInfo.Version.Release,
|
||||||
|
SystemDeviceInfo.SimInfo,
|
||||||
|
SystemDeviceInfo.APN,
|
||||||
|
false, true, false, tlv.GuidFlag(),
|
||||||
|
SystemDeviceInfo.Model,
|
||||||
|
SystemDeviceInfo.Guid,
|
||||||
|
SystemDeviceInfo.Brand,
|
||||||
|
h[:],
|
||||||
|
))
|
||||||
|
w.Write(tlv.T143(c.sigInfo.d2))
|
||||||
|
w.Write(tlv.T142(c.version.ApkId))
|
||||||
|
w.Write(tlv.T154(seq))
|
||||||
|
w.Write(tlv.T18(16, uint32(c.Uin)))
|
||||||
|
w.Write(tlv.T141(SystemDeviceInfo.SimInfo, SystemDeviceInfo.APN))
|
||||||
|
w.Write(tlv.T8(2052))
|
||||||
|
w.Write(tlv.T147(16, []byte(c.version.SortVersionName), c.version.ApkSign))
|
||||||
|
w.Write(tlv.T177(c.version.BuildTime, c.version.SdkVersion))
|
||||||
|
w.Write(tlv.T187(SystemDeviceInfo.MacAddress))
|
||||||
|
w.Write(tlv.T188(SystemDeviceInfo.AndroidId))
|
||||||
|
w.Write(tlv.T194(SystemDeviceInfo.IMSIMd5))
|
||||||
|
w.Write(tlv.T511([]string{
|
||||||
|
"tenpay.com", "openmobile.qq.com", "docs.qq.com", "connect.qq.com",
|
||||||
|
"qzone.qq.com", "vip.qq.com", "qun.qq.com", "game.qq.com", "qqweb.qq.com",
|
||||||
|
"office.qq.com", "ti.qq.com", "mail.qq.com", "qzone.com", "mma.qq.com",
|
||||||
|
}))
|
||||||
|
//w.Write(tlv.T202(SystemDeviceInfo.WifiBSSID, SystemDeviceInfo.WifiSSID))
|
||||||
|
})
|
||||||
|
sso := packets.BuildSsoPacket(seq, c.version.AppId, "wtlogin.exchange_emp", SystemDeviceInfo.IMEI, c.sigInfo.tgt, c.OutGoingPacketSessionId, req, c.ksid)
|
||||||
|
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{})
|
||||||
|
return seq, packet
|
||||||
|
}
|
||||||
|
|
||||||
// StatSvc.register
|
// StatSvc.register
|
||||||
func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
|
func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
|
@ -263,6 +263,38 @@ func (c *QQClient) Login() (*LoginResponse, error) {
|
|||||||
return &l, nil
|
return &l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) TokenLogin(token []byte) error {
|
||||||
|
if c.Online {
|
||||||
|
return ErrAlreadyOnline
|
||||||
|
}
|
||||||
|
if c.Conn == nil {
|
||||||
|
err := c.connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go c.netLoop()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
r := binary.NewReader(token)
|
||||||
|
c.Uin = r.ReadInt64()
|
||||||
|
c.sigInfo.d2 = r.ReadBytesShort()
|
||||||
|
c.sigInfo.d2Key = r.ReadBytesShort()
|
||||||
|
c.sigInfo.tgt = r.ReadBytesShort()
|
||||||
|
c.sigInfo.srmToken = r.ReadBytesShort()
|
||||||
|
c.sigInfo.t133 = r.ReadBytesShort()
|
||||||
|
c.sigInfo.encryptedA1 = r.ReadBytesShort()
|
||||||
|
c.sigInfo.wtSessionTicketKey = r.ReadBytesShort()
|
||||||
|
c.OutGoingPacketSessionId = r.ReadBytesShort()
|
||||||
|
SystemDeviceInfo.TgtgtKey = r.ReadBytesShort()
|
||||||
|
}
|
||||||
|
_, err := c.sendAndWait(c.buildRequestChangeSigPacket())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.init()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *QQClient) FetchQRCode() (*QRCodeLoginResponse, error) {
|
func (c *QQClient) FetchQRCode() (*QRCodeLoginResponse, error) {
|
||||||
if c.Online {
|
if c.Online {
|
||||||
return nil, ErrAlreadyOnline
|
return nil, ErrAlreadyOnline
|
||||||
@ -384,6 +416,21 @@ func (c *QQClient) init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) GenToken() []byte {
|
||||||
|
return binary.NewWriterF(func(w *binary.Writer) {
|
||||||
|
w.WriteUInt64(uint64(c.Uin))
|
||||||
|
w.WriteBytesShort(c.sigInfo.d2)
|
||||||
|
w.WriteBytesShort(c.sigInfo.d2Key)
|
||||||
|
w.WriteBytesShort(c.sigInfo.tgt)
|
||||||
|
w.WriteBytesShort(c.sigInfo.srmToken)
|
||||||
|
w.WriteBytesShort(c.sigInfo.t133)
|
||||||
|
w.WriteBytesShort(c.sigInfo.encryptedA1)
|
||||||
|
w.WriteBytesShort(c.sigInfo.wtSessionTicketKey)
|
||||||
|
w.WriteBytesShort(c.OutGoingPacketSessionId)
|
||||||
|
w.WriteBytesShort(SystemDeviceInfo.TgtgtKey)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (c *QQClient) GetVipInfo(target int64) (*VipInfo, error) {
|
func (c *QQClient) GetVipInfo(target int64) (*VipInfo, error) {
|
||||||
b, err := utils.HttpGetBytes(fmt.Sprintf("https://h5.vip.qq.com/p/mc/cardv2/other?platform=1&qq=%d&adtag=geren&aid=mvip.pingtai.mobileqq.androidziliaoka.fromqita", target), c.getCookiesWithDomain("h5.vip.qq.com"))
|
b, err := utils.HttpGetBytes(fmt.Sprintf("https://h5.vip.qq.com/p/mc/cardv2/other?platform=1&qq=%d&adtag=geren&aid=mvip.pingtai.mobileqq.androidziliaoka.fromqita", target), c.getCookiesWithDomain("h5.vip.qq.com"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -53,7 +53,7 @@ func decodeLoginResponse(c *QQClient, _ *incomingPacketInfo, payload []byte) (in
|
|||||||
if m.Exists(0x403) {
|
if m.Exists(0x403) {
|
||||||
c.randSeed = m[0x403]
|
c.randSeed = m[0x403]
|
||||||
}
|
}
|
||||||
c.decodeT119(m[0x119])
|
c.decodeT119(m[0x119], SystemDeviceInfo.TgtgtKey)
|
||||||
return LoginResponse{
|
return LoginResponse{
|
||||||
Success: true,
|
Success: true,
|
||||||
}, nil
|
}, nil
|
||||||
@ -204,11 +204,15 @@ func decodeExchangeEmpResponse(c *QQClient, _ *incomingPacketInfo, payload []byt
|
|||||||
m := reader.ReadTlvMap(2)
|
m := reader.ReadTlvMap(2)
|
||||||
if t != 0 {
|
if t != 0 {
|
||||||
c.Error("exchange_emp error: %v", t)
|
c.Error("exchange_emp error: %v", t)
|
||||||
return nil, nil
|
return nil, errors.New("exchange_emp failed")
|
||||||
}
|
}
|
||||||
if cmd == 15 { // TODO: 免密登录
|
if cmd == 15 {
|
||||||
c.decodeT119R(m[0x119])
|
c.decodeT119R(m[0x119])
|
||||||
}
|
}
|
||||||
|
if cmd == 11 {
|
||||||
|
h := md5.Sum(c.sigInfo.d2Key)
|
||||||
|
c.decodeT119(m[0x119], h[:])
|
||||||
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
@ -19,8 +20,8 @@ func (c *QQClient) decodeT161(data []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) decodeT119(data []byte) {
|
func (c *QQClient) decodeT119(data, ek []byte) {
|
||||||
tea := binary.NewTeaCipher(SystemDeviceInfo.TgtgtKey)
|
tea := binary.NewTeaCipher(ek)
|
||||||
reader := binary.NewReader(tea.Decrypt(data))
|
reader := binary.NewReader(tea.Decrypt(data))
|
||||||
reader.ReadBytes(2)
|
reader.ReadBytes(2)
|
||||||
m := reader.ReadTlvMap(2)
|
m := reader.ReadTlvMap(2)
|
||||||
@ -85,9 +86,9 @@ func (c *QQClient) decodeT119(data []byte) {
|
|||||||
|
|
||||||
c.sigInfo = &loginSigInfo{
|
c.sigInfo = &loginSigInfo{
|
||||||
loginBitmap: 0,
|
loginBitmap: 0,
|
||||||
srmToken: m[0x16a],
|
srmToken: utils.Select(m[0x16a], c.sigInfo.srmToken),
|
||||||
t133: m[0x133],
|
t133: utils.Select(m[0x133], c.sigInfo.t133),
|
||||||
encryptedA1: m[0x106],
|
encryptedA1: utils.Select(m[0x106], c.sigInfo.encryptedA1),
|
||||||
tgt: m[0x10a],
|
tgt: m[0x10a],
|
||||||
tgtKey: m[0x10d],
|
tgtKey: m[0x10d],
|
||||||
userStKey: m[0x10e],
|
userStKey: m[0x10e],
|
||||||
@ -96,18 +97,20 @@ func (c *QQClient) decodeT119(data []byte) {
|
|||||||
sKeyExpiredTime: time.Now().Unix() + 21600,
|
sKeyExpiredTime: time.Now().Unix() + 21600,
|
||||||
d2: m[0x143],
|
d2: m[0x143],
|
||||||
d2Key: m[0x305],
|
d2Key: m[0x305],
|
||||||
wtSessionTicketKey: m[0x134],
|
wtSessionTicketKey: utils.Select(m[0x134], c.sigInfo.wtSessionTicketKey),
|
||||||
deviceToken: m[0x322],
|
deviceToken: m[0x322],
|
||||||
|
|
||||||
psKeyMap: psKeyMap,
|
psKeyMap: psKeyMap,
|
||||||
pt4TokenMap: pt4TokenMap,
|
pt4TokenMap: pt4TokenMap,
|
||||||
}
|
}
|
||||||
key := md5.Sum(append(append(c.PasswordMd5[:], []byte{0x00, 0x00, 0x00, 0x00}...), binary.NewWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(c.Uin)) })...))
|
if len(c.PasswordMd5[:]) > 0 {
|
||||||
decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sigInfo.encryptedA1)
|
key := md5.Sum(append(append(c.PasswordMd5[:], []byte{0x00, 0x00, 0x00, 0x00}...), binary.NewWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(c.Uin)) })...))
|
||||||
if len(decrypted) > 51+16 {
|
decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sigInfo.encryptedA1)
|
||||||
dr := binary.NewReader(decrypted)
|
if len(decrypted) > 51+16 {
|
||||||
dr.ReadBytes(51)
|
dr := binary.NewReader(decrypted)
|
||||||
SystemDeviceInfo.TgtgtKey = dr.ReadBytes(16)
|
dr.ReadBytes(51)
|
||||||
|
SystemDeviceInfo.TgtgtKey = dr.ReadBytes(16)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.Nickname = nick
|
c.Nickname = nick
|
||||||
c.Age = age
|
c.Age = age
|
||||||
|
@ -56,3 +56,12 @@ func MultiReadSeeker(r ...io.ReadSeeker) io.ReadSeeker {
|
|||||||
readers: r,
|
readers: r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Select 如果A为nil 将会返回 B 否则返回A
|
||||||
|
// 对应 ?? 语法
|
||||||
|
func Select(a, b []byte) []byte {
|
||||||
|
if a == nil {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user