mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2025-01-24 22:01:49 +01:00
parent
0337ad93f2
commit
6d436f3417
@ -66,6 +66,7 @@ class HandshakeState : MinecraftConnectionState {
|
||||
it.frontOnline = frontOnline
|
||||
it.backName = parsed.username
|
||||
it.backAddress = HostAndPort.fromParts(packet.address, packet.port)
|
||||
it.extraData = extraData
|
||||
}
|
||||
|
||||
val playerAddr = handler.data.frontHandler.endRemoteAddress
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.viaversion.aas.handler.state
|
||||
|
||||
import com.google.common.net.HostAndPort
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.viaversion.aas.*
|
||||
import com.viaversion.aas.codec.CompressionCodec
|
||||
import com.viaversion.aas.codec.CryptoCodec
|
||||
@ -28,6 +28,7 @@ class LoginState : MinecraftConnectionState {
|
||||
var frontOnline: Boolean? = null
|
||||
lateinit var frontName: String
|
||||
lateinit var backAddress: HostAndPort
|
||||
var extraData: String? = null
|
||||
var backName: String? = null
|
||||
var started = false
|
||||
override val state: State
|
||||
@ -92,7 +93,7 @@ class LoginState : MinecraftConnectionState {
|
||||
val backPublicKey = cryptoRequest.publicKey
|
||||
val backToken = cryptoRequest.token
|
||||
|
||||
if (frontOnline == null) {
|
||||
if (!callbackPlayerId.isDone) {
|
||||
authenticateOnlineFront(handler.data.frontChannel)
|
||||
}
|
||||
val frontHandler = handler.data.frontHandler
|
||||
@ -105,6 +106,7 @@ class LoginState : MinecraftConnectionState {
|
||||
val backKey = generate128Bits()
|
||||
val backHash = generateServerHash(backServerId, backKey, backPublicKey)
|
||||
|
||||
mcLogger.info("Session req: ${handler.data.frontHandler.endRemoteAddress} ($playerId $frontName) $backName")
|
||||
viaWebServer.requestSessionJoin(
|
||||
playerId,
|
||||
backName!!,
|
||||
@ -112,6 +114,7 @@ class LoginState : MinecraftConnectionState {
|
||||
frontHandler.endRemoteAddress,
|
||||
handler.data.backHandler!!.endRemoteAddress
|
||||
).await()
|
||||
if (!handler.data.frontChannel.isActive) return@launch
|
||||
|
||||
val cryptoResponse = CryptoResponse()
|
||||
cryptoResponse.encryptedKey = encryptRsa(backPublicKey, backKey)
|
||||
@ -163,36 +166,31 @@ class LoginState : MinecraftConnectionState {
|
||||
frontName = loginStart.username
|
||||
backName = backName ?: frontName
|
||||
|
||||
val connect = {
|
||||
connectBack(handler, backAddress.host, backAddress.port, State.LOGIN) {
|
||||
loginStart.username = backName!!
|
||||
send(handler.data.backChannel!!, loginStart, true)
|
||||
}
|
||||
}
|
||||
|
||||
callbackPlayerId.whenComplete { id, e ->
|
||||
if (e != null) {
|
||||
handler.data.frontChannel.pipeline().fireExceptionCaught(StacklessException("Profile error: $e", e))
|
||||
} else {
|
||||
mcLogger.info("Login: ${handler.endRemoteAddress} $frontName $id")
|
||||
GlobalScope.launch {
|
||||
try {
|
||||
if (frontOnline != null) {
|
||||
connect()
|
||||
when (frontOnline) {
|
||||
false -> callbackPlayerId.complete(generateOfflinePlayerUuid(frontName))
|
||||
true -> authenticateOnlineFront(handler.data.frontChannel) // forced
|
||||
}
|
||||
val id = callbackPlayerId.await()
|
||||
mcLogger.info("Login: ${handler.endRemoteAddress} $frontName $id")
|
||||
}
|
||||
connectBack(handler, backAddress.host, backAddress.port, State.LOGIN, extraData) {
|
||||
loginStart.username = backName!!
|
||||
send(handler.data.backChannel!!, loginStart, true)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
handler.data.frontChannel.pipeline().fireExceptionCaught(StacklessException("Login error: $e", e))
|
||||
}
|
||||
}
|
||||
|
||||
when (frontOnline) {
|
||||
false -> callbackPlayerId.complete(generateOfflinePlayerUuid(frontName))
|
||||
true -> authenticateOnlineFront(handler.data.frontChannel) // forced
|
||||
null -> connect() // Connect then authenticate
|
||||
}
|
||||
}
|
||||
|
||||
override fun disconnect(handler: MinecraftHandler, msg: String) {
|
||||
super.disconnect(handler, msg)
|
||||
|
||||
val packet = LoginDisconnect()
|
||||
packet.msg = Gson().toJson("[VIAaaS] §c$msg")
|
||||
packet.msg = JsonPrimitive("[VIAaaS] §c$msg").toString()
|
||||
writeFlushClose(handler.data.frontChannel, packet)
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ import java.util.concurrent.CompletableFuture
|
||||
private fun createBackChannel(
|
||||
handler: MinecraftHandler,
|
||||
socketAddr: InetSocketAddress,
|
||||
state: State
|
||||
state: State,
|
||||
extraData: String?
|
||||
): CompletableFuture<Channel> {
|
||||
val future = CompletableFuture<Channel>()
|
||||
val loop = handler.data.frontChannel.eventLoop()
|
||||
@ -71,7 +72,7 @@ private fun createBackChannel(
|
||||
val packet = Handshake()
|
||||
packet.nextState = state
|
||||
packet.protocolId = handler.data.frontVer!!
|
||||
packet.address = socketAddr.hostString
|
||||
packet.address = socketAddr.hostString + if (extraData != null) 0.toChar() + extraData else ""
|
||||
packet.port = socketAddr.port
|
||||
|
||||
forward(handler, packet, true)
|
||||
@ -90,10 +91,12 @@ private suspend fun tryBackAddresses(
|
||||
handler: MinecraftHandler,
|
||||
addresses: Iterable<InetSocketAddress>,
|
||||
state: State,
|
||||
extraData: String?
|
||||
) {
|
||||
var latestException: Exception? = null
|
||||
for (socketAddr in addresses) {
|
||||
try {
|
||||
if (!handler.data.frontChannel.isActive) return
|
||||
if ((socketAddr.address != null && checkLocalAddress(socketAddr.address))
|
||||
|| matchesAddress(socketAddr, VIAaaSConfig.blockedBackAddresses)
|
||||
|| !matchesAddress(socketAddr, VIAaaSConfig.allowedBackAddresses)
|
||||
@ -101,7 +104,7 @@ private suspend fun tryBackAddresses(
|
||||
throw StacklessException("Not allowed")
|
||||
}
|
||||
|
||||
createBackChannel(handler, socketAddr, state).await()
|
||||
createBackChannel(handler, socketAddr, state, extraData).await()
|
||||
return // Finally it worked!
|
||||
} catch (e: Exception) {
|
||||
latestException = e
|
||||
@ -126,7 +129,7 @@ private fun resolveBackendAddresses(hostAndPort: HostAndPort): List<InetSocketAd
|
||||
}
|
||||
}
|
||||
|
||||
fun connectBack(handler: MinecraftHandler, address: String, port: Int, state: State, success: () -> Unit) {
|
||||
fun connectBack(handler: MinecraftHandler, address: String, port: Int, state: State, extraData: String? = null, success: () -> Unit) {
|
||||
handler.data.frontChannel.setAutoRead(false)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
@ -134,7 +137,7 @@ fun connectBack(handler: MinecraftHandler, address: String, port: Int, state: St
|
||||
|
||||
if (addresses.isEmpty()) throw StacklessException("Hostname has no IP address")
|
||||
|
||||
tryBackAddresses(handler, addresses, state)
|
||||
tryBackAddresses(handler, addresses, state, extraData)
|
||||
success()
|
||||
} catch (e: Exception) {
|
||||
handler.data.frontChannel.eventLoop().submit {
|
||||
|
@ -11,7 +11,10 @@ object AspirinInjector : ViaInjector {
|
||||
override fun getDecoderName() = "via-codec"
|
||||
override fun getDump(): JsonObject = JsonObject()
|
||||
override fun getServerProtocolVersions(): IntSortedSet = IntLinkedOpenHashSet(
|
||||
sortedSetOf(ProtocolVersion.v1_16_4.version, ProtocolVersion.v1_7_1.version)
|
||||
sortedSetOf(
|
||||
ProtocolVersion.getProtocols().maxOf { it.originalVersion },
|
||||
ProtocolVersion.v1_7_1.version
|
||||
)
|
||||
)
|
||||
|
||||
override fun getServerProtocolVersion(): Int = ProtocolVersion.v1_7_1.version
|
||||
|
@ -38,9 +38,8 @@ class WebDashboardServer {
|
||||
fun generateToken(account: UUID): String {
|
||||
return JWT.create()
|
||||
.withExpiresAt(Date.from(Instant.now().plus(Duration.ofDays(30))))
|
||||
.withSubject("mc_account")
|
||||
.withClaim("can_listen", true)
|
||||
.withClaim("mc_uuid", account.toString())
|
||||
.withSubject(account.toString())
|
||||
.withAudience("viaaas_listen")
|
||||
.withIssuer("viaaas")
|
||||
.sign(jwtAlgorithm)
|
||||
}
|
||||
@ -48,13 +47,10 @@ class WebDashboardServer {
|
||||
fun checkToken(token: String): UUID? {
|
||||
return try {
|
||||
val verified = JWT.require(jwtAlgorithm)
|
||||
.withSubject("mc_account")
|
||||
.withClaim("can_listen", true)
|
||||
.withClaimPresence("mc_uuid")
|
||||
.withAnyOfAudience("viaaas_listen")
|
||||
.build()
|
||||
.verify(token)
|
||||
|
||||
UUID.fromString(verified.getClaim("mc_uuid").asString())
|
||||
UUID.fromString(verified.subject)
|
||||
} catch (e: JWTVerificationException) {
|
||||
null
|
||||
}
|
||||
@ -89,17 +85,17 @@ class WebDashboardServer {
|
||||
future.completeExceptionally(StacklessException("No browser listening"))
|
||||
} else {
|
||||
val info = withContext(Dispatchers.IO) {
|
||||
(address as? InetSocketAddress).let {
|
||||
(address as? InetSocketAddress)?.let {
|
||||
try {
|
||||
it?.address?.hostName // resolve it
|
||||
ipInfo.lookupIP(it?.address?.hostAddress?.substringBefore("%"))
|
||||
it.address?.hostName // resolve it
|
||||
ipInfo.lookupIP(it.address?.hostAddress?.substringBefore("%"))
|
||||
} catch (ignored: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
val msg =
|
||||
"Client: $address (${info?.org}, ${info?.city}, ${info?.region}, ${info?.countryCode})\nBackend: $backAddress"
|
||||
val msg = """Requester: $id $address (${info?.org}, ${info?.city}, ${info?.region}, ${info?.countryCode})
|
||||
Backend: $backAddress"""
|
||||
listeners[id]?.forEach {
|
||||
it.ws.send(
|
||||
JsonObject().also {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.viaversion.aas.web
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.viaversion.aas.*
|
||||
import com.viaversion.aas.util.StacklessException
|
||||
import io.ktor.client.request.forms.*
|
||||
@ -20,7 +20,7 @@ class WebLogin : WebState {
|
||||
}
|
||||
|
||||
override suspend fun onMessage(webClient: WebClient, msg: String) {
|
||||
val obj = Gson().fromJson(msg, JsonObject::class.java)
|
||||
val obj = JsonParser.parseString(msg) as JsonObject
|
||||
|
||||
when (obj.getAsJsonPrimitive("action").asString) {
|
||||
"offline_login" -> {
|
||||
|
@ -53,7 +53,9 @@ function confirmJoin(hash) {
|
||||
}
|
||||
|
||||
function handleJoinRequest(parsed) {
|
||||
authNotification("Allow auth impersonation from VIAaaS instance?\nUsername: " + parsed.user + "\nSession Hash: " + parsed.session_hash + "\nServer Message: '" + parsed.message + "'", () => {
|
||||
authNotification("Allow auth impersonation from VIAaaS instance?\nAccount: "
|
||||
+ parsed.user + "\nServer Message: \n"
|
||||
+ parsed.message.split(/[\r\n]+/).map(it => "> " + it).join('\n'), () => {
|
||||
let account = findAccountByMcName(parsed.user);
|
||||
if (account) {
|
||||
getMcUserToken(account).then(data => {
|
||||
|
Loading…
Reference in New Issue
Block a user