Move AccountSecrets from package context to components

This commit is contained in:
Him188 2021-07-28 10:57:39 +08:00
parent 2995e47f40
commit 3772861e17
6 changed files with 89 additions and 116 deletions

View File

@ -19,8 +19,8 @@ import kotlinx.io.core.toByteArray
import net.mamoe.mirai.data.OnlineStatus
import net.mamoe.mirai.internal.BotAccount
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.components.AccountSecrets
import net.mamoe.mirai.internal.network.components.SsoSession
import net.mamoe.mirai.internal.network.context.AccountSecrets
import net.mamoe.mirai.internal.network.protocol.SyncingCacheList
import net.mamoe.mirai.internal.network.protocol.data.jce.FileStoragePushFSSvcList
import net.mamoe.mirai.internal.network.protocol.packet.Tlv

View File

@ -9,20 +9,25 @@
package net.mamoe.mirai.internal.network.components
import kotlinx.io.core.toByteArray
import kotlinx.serialization.Serializable
import net.mamoe.mirai.Bot
import net.mamoe.mirai.internal.BotAccount
import net.mamoe.mirai.internal.network.LoginExtraData
import net.mamoe.mirai.internal.network.WLoginSigInfo
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.context.AccountSecrets
import net.mamoe.mirai.internal.network.context.AccountSecretsImpl
import net.mamoe.mirai.internal.network.getRandomByteArray
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.get_mpasswd
import net.mamoe.mirai.internal.utils.actualCacheDir
import net.mamoe.mirai.internal.utils.crypto.ECDHInitialPublicKey
import net.mamoe.mirai.internal.utils.crypto.TEA
import net.mamoe.mirai.internal.utils.crypto.defaultInitialPublicKey
import net.mamoe.mirai.internal.utils.io.ProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.DeviceInfo
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.info
import net.mamoe.mirai.utils.*
import java.io.File
import java.util.concurrent.CopyOnWriteArraySet
/**
* For a [Bot].
@ -39,6 +44,79 @@ internal interface AccountSecretsManager {
companion object : ComponentKey<AccountSecretsManager>
}
/**
* Secrets for authentication with server. (login)
*/
internal interface AccountSecrets {
var wLoginSigInfoField: WLoginSigInfo?
val wLoginSigInfoInitialized get() = wLoginSigInfoField != null
var wLoginSigInfo: WLoginSigInfo
get() = wLoginSigInfoField ?: error("wLoginSigInfoField is not yet initialized")
set(value) {
wLoginSigInfoField = value
}
/**
* t537
*/
var loginExtraData: MutableSet<LoginExtraData>
var G: ByteArray // sigInfo[2]
var dpwd: ByteArray
var randSeed: ByteArray // t403
/**
* t108 时更新
*/
var ksid: ByteArray
var tgtgtKey: ByteArray
val randomKey: ByteArray
var ecdhInitialPublicKey: ECDHInitialPublicKey
}
@Suppress("ArrayInDataClass") // for `copy`
@Serializable
internal data class AccountSecretsImpl(
override var loginExtraData: MutableSet<LoginExtraData>,
override var wLoginSigInfoField: WLoginSigInfo?,
override var G: ByteArray,
override var dpwd: ByteArray = get_mpasswd().toByteArray(),
override var randSeed: ByteArray,
override var ksid: ByteArray,
override var tgtgtKey: ByteArray,
override val randomKey: ByteArray,
override var ecdhInitialPublicKey: ECDHInitialPublicKey,
) : AccountSecrets, ProtoBuf
internal fun AccountSecretsImpl(
other: AccountSecrets,
): AccountSecretsImpl = other.run {
AccountSecretsImpl(
loginExtraData, wLoginSigInfoField, G, dpwd,
randSeed, ksid, tgtgtKey, randomKey, ecdhInitialPublicKey
)
}
internal fun AccountSecretsImpl(
device: DeviceInfo, account: BotAccount,
): AccountSecretsImpl {
return AccountSecretsImpl(
loginExtraData = CopyOnWriteArraySet(),
wLoginSigInfoField = null,
G = device.guid,
dpwd = get_mpasswd().toByteArray(),
randSeed = EMPTY_BYTE_ARRAY,
ksid = EMPTY_BYTE_ARRAY,
tgtgtKey = (account.passwordMd5 + ByteArray(4) + account.id.toInt().toByteArray()).md5(),
randomKey = getRandomByteArray(16),
ecdhInitialPublicKey = defaultInitialPublicKey
)
}
internal fun AccountSecretsManager.getSecretsOrCreate(account: BotAccount, device: DeviceInfo): AccountSecrets {
var secrets = getSecrets(account)
if (secrets == null) {
@ -95,7 +173,7 @@ internal class FileCacheAccountSecretsManager(
val loaded = kotlin.runCatching {
TEA.decrypt(file.readBytes(), account.passwordMd5).loadAs(AccountSecretsImpl.serializer())
}.getOrElse { e ->
if (e.message == "Field 'ecdhInitialPublicKey' is required for type with serial name 'net.mamoe.mirai.internal.network.context.AccountSecretsImpl', but it was missing") {
if (e.message == "Field 'ecdhInitialPublicKey' is required for type with serial name 'net.mamoe.mirai.internal.network.components.AccountSecretsImpl', but it was missing") {
logger.info { "Detected old account secrets, invalidating..." }
} else {
logger.error("Failed to load account secrets from local cache. Invalidating cache...", e)

View File

@ -14,7 +14,6 @@ import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.WLoginSigInfo
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.context.AccountSecretsImpl
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType

View File

@ -1,104 +0,0 @@
/*
* Copyright 2019-2021 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/master/LICENSE
*/
package net.mamoe.mirai.internal.network.context
import kotlinx.io.core.toByteArray
import kotlinx.serialization.Serializable
import net.mamoe.mirai.internal.BotAccount
import net.mamoe.mirai.internal.network.LoginExtraData
import net.mamoe.mirai.internal.network.WLoginSigInfo
import net.mamoe.mirai.internal.network.getRandomByteArray
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.get_mpasswd
import net.mamoe.mirai.internal.utils.crypto.ECDHInitialPublicKey
import net.mamoe.mirai.internal.utils.crypto.defaultInitialPublicKey
import net.mamoe.mirai.internal.utils.io.ProtoBuf
import net.mamoe.mirai.utils.DeviceInfo
import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY
import net.mamoe.mirai.utils.md5
import net.mamoe.mirai.utils.toByteArray
import java.util.concurrent.CopyOnWriteArraySet
/**
* Secrets for authentication with server. (login)
*/
internal interface AccountSecrets {
var wLoginSigInfoField: WLoginSigInfo?
val wLoginSigInfoInitialized get() = wLoginSigInfoField != null
var wLoginSigInfo: WLoginSigInfo
get() = wLoginSigInfoField ?: error("wLoginSigInfoField is not yet initialized")
set(value) {
wLoginSigInfoField = value
}
/**
* t537
*/
var loginExtraData: MutableSet<LoginExtraData>
var G: ByteArray // sigInfo[2]
var dpwd: ByteArray
var randSeed: ByteArray // t403
/**
* t108 时更新
*/
var ksid: ByteArray
var tgtgtKey: ByteArray
val randomKey: ByteArray
var ecdhInitialPublicKey: ECDHInitialPublicKey
}
@Suppress("ArrayInDataClass") // for `copy`
@Serializable
internal data class AccountSecretsImpl(
override var loginExtraData: MutableSet<LoginExtraData>,
override var wLoginSigInfoField: WLoginSigInfo?,
override var G: ByteArray,
override var dpwd: ByteArray = get_mpasswd().toByteArray(),
override var randSeed: ByteArray,
override var ksid: ByteArray,
override var tgtgtKey: ByteArray,
override val randomKey: ByteArray,
override var ecdhInitialPublicKey: ECDHInitialPublicKey,
) : AccountSecrets, ProtoBuf
internal fun AccountSecretsImpl(
other: AccountSecrets,
): AccountSecretsImpl = other.run {
AccountSecretsImpl(
loginExtraData,
wLoginSigInfoField,
G,
dpwd,
randSeed,
ksid,
tgtgtKey,
randomKey,
ecdhInitialPublicKey
)
}
internal fun AccountSecretsImpl(
device: DeviceInfo, account: BotAccount,
): AccountSecretsImpl {
return AccountSecretsImpl(
loginExtraData = CopyOnWriteArraySet(),
wLoginSigInfoField = null,
G = device.guid,
dpwd = get_mpasswd().toByteArray(),
randSeed = EMPTY_BYTE_ARRAY,
ksid = EMPTY_BYTE_ARRAY,
tgtgtKey = (account.passwordMd5 + ByteArray(4) + account.id.toInt().toByteArray()).md5(),
randomKey = getRandomByteArray(16),
ecdhInitialPublicKey = defaultInitialPublicKey
)
}

View File

@ -11,10 +11,10 @@ package net.mamoe.mirai.internal.network.framework.components
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.components.AccountSecretsImpl
import net.mamoe.mirai.internal.network.components.SsoProcessor
import net.mamoe.mirai.internal.network.components.SsoSession
import net.mamoe.mirai.internal.network.components.createDeviceInfo
import net.mamoe.mirai.internal.network.context.AccountSecretsImpl
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.handler.logger
import net.mamoe.mirai.internal.network.protocol.data.jce.SvcRespRegister

View File

@ -13,9 +13,9 @@ import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.WLoginSigInfo
import net.mamoe.mirai.internal.network.components.AccountSecrets
import net.mamoe.mirai.internal.network.components.AccountSecretsImpl
import net.mamoe.mirai.internal.network.components.SsoSession
import net.mamoe.mirai.internal.network.context.AccountSecrets
import net.mamoe.mirai.internal.network.context.AccountSecretsImpl
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY