mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-25 03:30:15 +08:00
[core] decode SsoEstablishShareKey
This commit is contained in:
parent
ff96dce35d
commit
1dacce61cd
@ -18,6 +18,7 @@ import net.mamoe.mirai.internal.network.components.PacketCodecException.Kind.*
|
||||
import net.mamoe.mirai.internal.network.handler.selector.NetworkException
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.sso.PREFIX_TRPC_SSO
|
||||
import net.mamoe.mirai.internal.utils.crypto.Ecdh
|
||||
import net.mamoe.mirai.internal.utils.crypto.TEA
|
||||
import net.mamoe.mirai.utils.*
|
||||
@ -95,6 +96,17 @@ internal class PacketCodecException(
|
||||
// }
|
||||
}
|
||||
|
||||
internal enum class IncomingPacketType(val value: Int) {
|
||||
Login(0x0A),
|
||||
Simple(0x0B),
|
||||
Unknown(-1)
|
||||
;
|
||||
|
||||
companion object {
|
||||
internal fun of(value: Int) = enumValues<IncomingPacketType>().find { it.value == value } ?: Unknown
|
||||
}
|
||||
}
|
||||
|
||||
internal class PacketCodecImpl : PacketCodec {
|
||||
|
||||
override fun decodeRaw(
|
||||
@ -102,15 +114,15 @@ internal class PacketCodecImpl : PacketCodec {
|
||||
input: ByteReadPacket
|
||||
): RawIncomingPacket = input.run {
|
||||
// packet type
|
||||
val type = readInt()
|
||||
val packetType = IncomingPacketType.of(readInt())
|
||||
|
||||
PacketLogger.verbose { "开始处理一个包" }
|
||||
|
||||
val encryptMethod = readByte().toInt()
|
||||
val encryptMethod = PacketEncryptType.of(readByte().toInt())
|
||||
val flag3 = readByte().toInt()
|
||||
val flag3Exception = if (flag3 != 0) {
|
||||
PacketCodecException(
|
||||
"Illegal flag3. Expected 0, whereas got $flag3. packet type=$type, encrypt method=$encryptMethod. ",
|
||||
"Illegal flag3. Expected 0, whereas got $flag3. packet type=$packetType, encrypt method=$encryptMethod. ",
|
||||
kind = PROTOCOL_UPDATED
|
||||
)
|
||||
} else null
|
||||
@ -122,10 +134,8 @@ internal class PacketCodecImpl : PacketCodec {
|
||||
|
||||
val raw = try {
|
||||
when (encryptMethod) {
|
||||
// empty key
|
||||
2 -> TEA.decrypt(buffer, DECRYPTER_16_ZERO, size)
|
||||
// d2 key
|
||||
1 -> {
|
||||
PacketEncryptType.Empty -> TEA.decrypt(buffer, DECRYPTER_16_ZERO, size)
|
||||
PacketEncryptType.D2 -> {
|
||||
TEA.decrypt(buffer, kotlin.runCatching { client.wLoginSigInfo.d2Key }.getOrElse {
|
||||
throw PacketCodecException(
|
||||
"Received packet needed d2Key to decrypt but d2Key doesn't existed, ignoring. Please report to https://github.com/mamoe/mirai/issues/new/choose if you see anything abnormal",
|
||||
@ -133,17 +143,18 @@ internal class PacketCodecImpl : PacketCodec {
|
||||
)
|
||||
}, size)
|
||||
}
|
||||
// no encrypt
|
||||
0 -> buffer
|
||||
|
||||
PacketEncryptType.NoEncrypt -> buffer
|
||||
else -> throw PacketCodecException("Unknown encrypt type=$encryptMethod", PROTOCOL_UPDATED)
|
||||
}.let { decryptedData ->
|
||||
when (type) {
|
||||
// login
|
||||
0x0A -> parseSsoFrame(client, decryptedData)
|
||||
// simple
|
||||
0x0B -> parseSsoFrame(client, decryptedData) // 这里可能是 uni?? 但测试时候发现结构跟 sso 一样.
|
||||
when (packetType) {
|
||||
IncomingPacketType.Login -> parseSsoFrame(client, decryptedData)
|
||||
IncomingPacketType.Simple -> parseSsoFrame(
|
||||
client,
|
||||
decryptedData
|
||||
) // 这里可能是 uni?? 但测试时候发现结构跟 sso 一样.
|
||||
else -> throw PacketCodecException(
|
||||
"unknown packet type: ${type.toByte().toUHexString()}",
|
||||
"unknown packet type: ${packetType.value.toUHexString()}",
|
||||
PROTOCOL_UPDATED
|
||||
)
|
||||
}
|
||||
@ -163,24 +174,38 @@ internal class PacketCodecImpl : PacketCodec {
|
||||
"which may means protocol is updated.",
|
||||
flag3Exception
|
||||
)
|
||||
} else if (raw.commandName.startsWith(PREFIX_TRPC_SSO)) {
|
||||
PacketLogger.verbose { "received a trpc native packet: ${raw.commandName}" }
|
||||
} else {
|
||||
throw flag3Exception
|
||||
}
|
||||
}
|
||||
|
||||
when (encryptMethod) {
|
||||
0, 1 -> RawIncomingPacket(raw.commandName, raw.sequenceId, raw.body.readBytes())
|
||||
2 -> RawIncomingPacket(
|
||||
PacketEncryptType.NoEncrypt,
|
||||
PacketEncryptType.D2 -> RawIncomingPacket(
|
||||
raw.commandName,
|
||||
raw.sequenceId,
|
||||
raw.body.readBytes()
|
||||
)
|
||||
|
||||
PacketEncryptType.Empty -> {
|
||||
RawIncomingPacket(
|
||||
raw.commandName,
|
||||
raw.sequenceId,
|
||||
raw.body.withUse {
|
||||
if (raw.commandName.startsWith(PREFIX_TRPC_SSO)) {
|
||||
readBytes()
|
||||
} else {
|
||||
try {
|
||||
parseOicqResponse(client, raw.commandName)
|
||||
} catch (e: Throwable) {
|
||||
throw PacketCodecException(e, PacketCodecException.Kind.OTHER)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
else -> error("unreachable")
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import net.mamoe.mirai.internal.network.*
|
||||
import net.mamoe.mirai.internal.network.components.EcdhInitialPublicKeyUpdater
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.SSOReserveField
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.sso.SsoEstablishShareKey
|
||||
import net.mamoe.mirai.internal.spi.EncryptService
|
||||
import net.mamoe.mirai.internal.spi.EncryptServiceContext
|
||||
import net.mamoe.mirai.internal.utils.io.encryptAndWrite
|
||||
@ -75,25 +75,34 @@ internal class IncomingPacket private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
internal enum class PacketEncryptType {
|
||||
NoEncrypt { // 0x00
|
||||
internal enum class PacketEncryptType(val value: Int) {
|
||||
NoEncrypt(0x00) { // 0x00
|
||||
override fun defaultKey(client: QQAndroidClient): ByteArray = NO_ENCRYPT
|
||||
},
|
||||
D2 { //0x01
|
||||
D2(0x01) { //0x01
|
||||
override fun defaultKey(client: QQAndroidClient): ByteArray {
|
||||
return client.wLoginSigInfo.d2Key
|
||||
}
|
||||
},
|
||||
Empty { // 16 zeros,// 0x02
|
||||
Empty(0x02) { // 16 zeros,// 0x02
|
||||
override fun defaultKey(client: QQAndroidClient): ByteArray {
|
||||
return KEY_16_ZEROS
|
||||
}
|
||||
},
|
||||
Unknown(-1) {
|
||||
override fun defaultKey(client: QQAndroidClient): ByteArray {
|
||||
error("unreachable")
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
inline val codec: Byte get() = ordinal.toByte()
|
||||
|
||||
abstract fun defaultKey(client: QQAndroidClient): ByteArray
|
||||
|
||||
companion object {
|
||||
internal fun of(value: Int) = enumValues<PacketEncryptType>().find { it.value == value } ?: Unknown
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -251,9 +260,9 @@ internal fun createChannelProxy(client: QQAndroidClient): EncryptService.Channel
|
||||
uin: Long,
|
||||
data: ByteArray
|
||||
): EncryptService.ChannelResult? {
|
||||
if (commandName == "trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey") {
|
||||
val packet = client.bot.network.sendAndExpect<Packet>(
|
||||
WtLogin.Login.buildLoginOutgoingPacket(
|
||||
if (commandName == SsoEstablishShareKey.commandName) {
|
||||
val packet = client.bot.network.sendAndExpect(
|
||||
SsoEstablishShareKey.buildLoginOutgoingPacket(
|
||||
client = client,
|
||||
encryptMethod = PacketEncryptType.Empty,
|
||||
uin = uin.toString(),
|
||||
@ -268,7 +277,7 @@ internal fun createChannelProxy(client: QQAndroidClient): EncryptService.Channel
|
||||
)
|
||||
}
|
||||
)
|
||||
TODO("parse packet to ChannelResult")
|
||||
return EncryptService.ChannelResult(SsoEstablishShareKey.commandName, packet.data)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
@ -26,11 +26,11 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.ConfigPushSvc
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.Heartbeat
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.sso.SsoEstablishShareKey
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.summarycard.ChangeFriendRemark
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.summarycard.SummaryCard
|
||||
import net.mamoe.mirai.utils.DeprecatedSinceMirai
|
||||
import net.mamoe.mirai.utils.MiraiLoggerWithSwitch
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
internal sealed class PacketFactory<TPacket : Packet?> {
|
||||
/**
|
||||
@ -132,6 +132,7 @@ internal object KnownPacketFactories {
|
||||
WtLogin.Login,
|
||||
WtLogin.ExchangeEmp,
|
||||
WtLogin.TransEmp,
|
||||
SsoEstablishShareKey,
|
||||
StatSvc.Register,
|
||||
StatSvc.GetOnlineStatus,
|
||||
StatSvc.SimpleGet,
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2019-2023 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.protocol.packet.sso
|
||||
|
||||
import io.ktor.utils.io.core.*
|
||||
import net.mamoe.mirai.internal.QQAndroidBot
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory
|
||||
|
||||
internal object SsoEstablishShareKey : OutgoingPacketFactory<SsoEstablishShareKey.RawData>(
|
||||
"trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey"
|
||||
) {
|
||||
internal class RawData(val data: ByteArray) : Packet
|
||||
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): RawData {
|
||||
return RawData(readBytes())
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2019-2023 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.protocol.packet.sso
|
||||
|
||||
internal const val PREFIX_TRPC_SSO = "trpc.o3"
|
@ -72,8 +72,6 @@ public interface EncryptService : BaseService {
|
||||
public class ChannelResult(
|
||||
public val cmd: String,
|
||||
public val data: ByteArray,
|
||||
public val success: Int,
|
||||
public val callbackId: Long
|
||||
)
|
||||
|
||||
public interface ChannelProxy {
|
||||
|
Loading…
Reference in New Issue
Block a user