From a9cdff3dca998208afdfa85942a864223e4a789d Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 22 Jun 2022 23:33:38 -0700 Subject: [PATCH] Get authentication working again --- src/client.rs | 1 + src/packets.rs | 28 ++++++++++++++++++++++++++-- src/server.rs | 36 +++++++++++++++++++++--------------- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/client.rs b/src/client.rs index bcee83d..9d4634d 100644 --- a/src/client.rs +++ b/src/client.rs @@ -719,6 +719,7 @@ impl<'a> ClientMut<'a> { } C2sPlayPacket::QueryBlockNbt(_) => {} C2sPlayPacket::SetDifficulty(_) => {} + C2sPlayPacket::ChatCommand(_) => {} C2sPlayPacket::ChatMessageServerbound(_) => {} C2sPlayPacket::ChatPreview(_) => {} C2sPlayPacket::ClientStatus(_) => {} diff --git a/src/packets.rs b/src/packets.rs index d5c5e26..c6f2f27 100644 --- a/src/packets.rs +++ b/src/packets.rs @@ -409,7 +409,15 @@ pub mod login { LoginSuccess 0x02 { uuid: Uuid, username: BoundedString<3, 16>, - null_byte: u8, // TODO: Why is this needed? + properties: Vec, + } + } + + def_struct! { + Property { + name: String, + value: String, + signature: Option, } } @@ -441,7 +449,21 @@ pub mod login { def_struct! { EncryptionResponse 0x01 { shared_secret: BoundedArray, - verify_token: BoundedArray, + token_or_sig: VerifyTokenOrMsgSig, + } + } + + def_enum! { + VerifyTokenOrMsgSig: u8 { + VerifyToken: BoundedArray = 1, + MsgSig: MessageSignature = 0, + } + } + + def_struct! { + MessageSignature { + salt: u64, + sig: Vec, // TODO: bounds? } } } @@ -1224,6 +1246,7 @@ pub mod play { def_struct! { ChatMessageServerbound 0x04 { message: BoundedString<0, 256> + // TODO: } } @@ -1804,6 +1827,7 @@ pub mod play { TeleportConfirm, QueryBlockNbt, SetDifficulty, + ChatCommand, ChatMessageServerbound, ChatPreview, ClientStatus, diff --git a/src/server.rs b/src/server.rs index dfc6f0a..876868e 100644 --- a/src/server.rs +++ b/src/server.rs @@ -30,7 +30,7 @@ use crate::codec::{Decoder, Encoder}; use crate::config::{Config, ServerListPing}; use crate::packets::handshake::{Handshake, HandshakeNextState}; use crate::packets::login; -use crate::packets::login::c2s::{EncryptionResponse, LoginStart}; +use crate::packets::login::c2s::{EncryptionResponse, LoginStart, VerifyTokenOrMsgSig}; use crate::packets::login::s2c::{EncryptionRequest, LoginSuccess, SetCompression}; use crate::packets::play::c2s::C2sPlayPacket; use crate::packets::play::s2c::S2cPlayPacket; @@ -578,19 +578,19 @@ async fn handle_login( ensure!(valid_username(&username), "invalid username '{username}'"); - let (uuid, skin_blob) = if server.0.online_mode { - let verify_token: [u8; 16] = rand::random(); + let (uuid, _skin_blob) = if server.0.online_mode { + let my_verify_token: [u8; 16] = rand::random(); c.0.write_packet(&EncryptionRequest { server_id: Default::default(), // Always empty public_key: server.0.public_key_der.to_vec(), - verify_token: verify_token.to_vec().into(), + verify_token: my_verify_token.to_vec().into(), }) .await?; let EncryptionResponse { shared_secret: BoundedArray(encrypted_shared_secret), - verify_token: BoundedArray(encrypted_verify_token), + token_or_sig, } = c.1.read_packet().await?; let shared_secret = server @@ -599,16 +599,22 @@ async fn handle_login( .decrypt(PaddingScheme::PKCS1v15Encrypt, &encrypted_shared_secret) .context("failed to decrypt shared secret")?; - let new_verify_token = server - .0 - .rsa_key - .decrypt(PaddingScheme::PKCS1v15Encrypt, &encrypted_verify_token) - .context("failed to decrypt verify token")?; + let _opt_signature = match token_or_sig { + VerifyTokenOrMsgSig::VerifyToken(BoundedArray(encrypted_verify_token)) => { + let verify_token = server + .0 + .rsa_key + .decrypt(PaddingScheme::PKCS1v15Encrypt, &encrypted_verify_token) + .context("failed to decrypt verify token")?; - ensure!( - verify_token.as_slice() == new_verify_token, - "verify tokens do not match" - ); + ensure!( + my_verify_token.as_slice() == verify_token, + "verify tokens do not match" + ); + None + } + VerifyTokenOrMsgSig::MsgSig(sig) => Some(sig), + }; let crypt_key: [u8; 16] = shared_secret .as_slice() @@ -690,7 +696,7 @@ async fn handle_login( c.0.write_packet(&LoginSuccess { uuid: npd.uuid, username: npd.username.clone().into(), - null_byte: 0, + properties: Vec::new(), }) .await?;