Get authentication working again

This commit is contained in:
Ryan 2022-06-22 23:33:38 -07:00
parent 69ba704352
commit a9cdff3dca
3 changed files with 48 additions and 17 deletions

View file

@ -719,6 +719,7 @@ impl<'a> ClientMut<'a> {
} }
C2sPlayPacket::QueryBlockNbt(_) => {} C2sPlayPacket::QueryBlockNbt(_) => {}
C2sPlayPacket::SetDifficulty(_) => {} C2sPlayPacket::SetDifficulty(_) => {}
C2sPlayPacket::ChatCommand(_) => {}
C2sPlayPacket::ChatMessageServerbound(_) => {} C2sPlayPacket::ChatMessageServerbound(_) => {}
C2sPlayPacket::ChatPreview(_) => {} C2sPlayPacket::ChatPreview(_) => {}
C2sPlayPacket::ClientStatus(_) => {} C2sPlayPacket::ClientStatus(_) => {}

View file

@ -409,7 +409,15 @@ pub mod login {
LoginSuccess 0x02 { LoginSuccess 0x02 {
uuid: Uuid, uuid: Uuid,
username: BoundedString<3, 16>, username: BoundedString<3, 16>,
null_byte: u8, // TODO: Why is this needed? properties: Vec<Property>,
}
}
def_struct! {
Property {
name: String,
value: String,
signature: Option<String>,
} }
} }
@ -441,7 +449,21 @@ pub mod login {
def_struct! { def_struct! {
EncryptionResponse 0x01 { EncryptionResponse 0x01 {
shared_secret: BoundedArray<u8, 16, 128>, shared_secret: BoundedArray<u8, 16, 128>,
verify_token: BoundedArray<u8, 16, 128>, token_or_sig: VerifyTokenOrMsgSig,
}
}
def_enum! {
VerifyTokenOrMsgSig: u8 {
VerifyToken: BoundedArray<u8, 16, 128> = 1,
MsgSig: MessageSignature = 0,
}
}
def_struct! {
MessageSignature {
salt: u64,
sig: Vec<u8>, // TODO: bounds?
} }
} }
} }
@ -1224,6 +1246,7 @@ pub mod play {
def_struct! { def_struct! {
ChatMessageServerbound 0x04 { ChatMessageServerbound 0x04 {
message: BoundedString<0, 256> message: BoundedString<0, 256>
// TODO:
} }
} }
@ -1804,6 +1827,7 @@ pub mod play {
TeleportConfirm, TeleportConfirm,
QueryBlockNbt, QueryBlockNbt,
SetDifficulty, SetDifficulty,
ChatCommand,
ChatMessageServerbound, ChatMessageServerbound,
ChatPreview, ChatPreview,
ClientStatus, ClientStatus,

View file

@ -30,7 +30,7 @@ use crate::codec::{Decoder, Encoder};
use crate::config::{Config, ServerListPing}; use crate::config::{Config, ServerListPing};
use crate::packets::handshake::{Handshake, HandshakeNextState}; use crate::packets::handshake::{Handshake, HandshakeNextState};
use crate::packets::login; 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::login::s2c::{EncryptionRequest, LoginSuccess, SetCompression};
use crate::packets::play::c2s::C2sPlayPacket; use crate::packets::play::c2s::C2sPlayPacket;
use crate::packets::play::s2c::S2cPlayPacket; use crate::packets::play::s2c::S2cPlayPacket;
@ -578,19 +578,19 @@ async fn handle_login(
ensure!(valid_username(&username), "invalid username '{username}'"); ensure!(valid_username(&username), "invalid username '{username}'");
let (uuid, skin_blob) = if server.0.online_mode { let (uuid, _skin_blob) = if server.0.online_mode {
let verify_token: [u8; 16] = rand::random(); let my_verify_token: [u8; 16] = rand::random();
c.0.write_packet(&EncryptionRequest { c.0.write_packet(&EncryptionRequest {
server_id: Default::default(), // Always empty server_id: Default::default(), // Always empty
public_key: server.0.public_key_der.to_vec(), 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?; .await?;
let EncryptionResponse { let EncryptionResponse {
shared_secret: BoundedArray(encrypted_shared_secret), shared_secret: BoundedArray(encrypted_shared_secret),
verify_token: BoundedArray(encrypted_verify_token), token_or_sig,
} = c.1.read_packet().await?; } = c.1.read_packet().await?;
let shared_secret = server let shared_secret = server
@ -599,16 +599,22 @@ async fn handle_login(
.decrypt(PaddingScheme::PKCS1v15Encrypt, &encrypted_shared_secret) .decrypt(PaddingScheme::PKCS1v15Encrypt, &encrypted_shared_secret)
.context("failed to decrypt shared secret")?; .context("failed to decrypt shared secret")?;
let new_verify_token = server let _opt_signature = match token_or_sig {
VerifyTokenOrMsgSig::VerifyToken(BoundedArray(encrypted_verify_token)) => {
let verify_token = server
.0 .0
.rsa_key .rsa_key
.decrypt(PaddingScheme::PKCS1v15Encrypt, &encrypted_verify_token) .decrypt(PaddingScheme::PKCS1v15Encrypt, &encrypted_verify_token)
.context("failed to decrypt verify token")?; .context("failed to decrypt verify token")?;
ensure!( ensure!(
verify_token.as_slice() == new_verify_token, my_verify_token.as_slice() == verify_token,
"verify tokens do not match" "verify tokens do not match"
); );
None
}
VerifyTokenOrMsgSig::MsgSig(sig) => Some(sig),
};
let crypt_key: [u8; 16] = shared_secret let crypt_key: [u8; 16] = shared_secret
.as_slice() .as_slice()
@ -690,7 +696,7 @@ async fn handle_login(
c.0.write_packet(&LoginSuccess { c.0.write_packet(&LoginSuccess {
uuid: npd.uuid, uuid: npd.uuid,
username: npd.username.clone().into(), username: npd.username.clone().into(),
null_byte: 0, properties: Vec::new(),
}) })
.await?; .await?;