From dbcb3c80522eb720a14c0ca171dd95cbe5daca44 Mon Sep 17 00:00:00 2001 From: Snowiiii Date: Sun, 4 Aug 2024 17:10:25 +0200 Subject: [PATCH] fix: Authentication --- Cargo.lock | 19 ++++++++++++------- pumpkin-protocol/src/bytebuf/mod.rs | 4 +++- pumpkin-protocol/src/client/login/mod.rs | 10 +++++----- pumpkin/Cargo.toml | 4 +--- pumpkin/src/client/authentication.rs | 9 ++++----- pumpkin/src/client/client_packet.rs | 11 +++++------ pumpkin/src/client/mod.rs | 9 +-------- pumpkin/src/configuration.rs | 2 +- pumpkin/src/server.rs | 6 +++--- 9 files changed, 35 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7aff4c16..c9eac86dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -455,6 +455,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -463,6 +464,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + [[package]] name = "futures-sink" version = "0.3.30" @@ -482,9 +489,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", + "futures-io", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -1094,12 +1105,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "pollster" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" - [[package]] name = "powerfmt" version = "0.2.0" @@ -1146,7 +1151,6 @@ dependencies = [ "log", "mio", "num-bigint", - "pollster", "pumpkin-protocol", "pumpkin-registry", "pumpkin-world", @@ -1255,6 +1259,7 @@ dependencies = [ "base64", "bytes", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2", diff --git a/pumpkin-protocol/src/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs index 81489192e..2b38bc7f0 100644 --- a/pumpkin-protocol/src/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -112,7 +112,9 @@ impl ByteBuffer { } pub fn put_uuid(&mut self, v: uuid::Uuid) { - self.buffer.put_slice(v.as_bytes()); + let pair = v.as_u64_pair(); + self.put_u64(pair.0); + self.put_u64(pair.1); } pub fn put_string(&mut self, val: &str) { diff --git a/pumpkin-protocol/src/client/login/mod.rs b/pumpkin-protocol/src/client/login/mod.rs index 238ef4e1b..e000c7c90 100644 --- a/pumpkin-protocol/src/client/login/mod.rs +++ b/pumpkin-protocol/src/client/login/mod.rs @@ -86,8 +86,10 @@ impl<'a> CLoginSuccess<'a> { #[derive(Deserialize, Clone, Debug)] pub struct Property { pub name: String, + // base 64 pub value: String, - pub signature: String, + // base 64 + pub signature: Option, } impl<'a> ClientPacket for CLoginSuccess<'a> { @@ -100,10 +102,8 @@ impl<'a> ClientPacket for CLoginSuccess<'a> { p.put_string(&v.name); p.put_string(&v.value); // has signature ? - p.put_bool(true); - // option - p.put_bool(true); - p.put_string(&v.signature); + p.put_bool(false); + // p.put_option(&v.signature, |p,v| p.put_string(v)); }); bytebuf.put_bool(self.strict_error_handling); } diff --git a/pumpkin/Cargo.toml b/pumpkin/Cargo.toml index d590cc202..c4835a583 100644 --- a/pumpkin/Cargo.toml +++ b/pumpkin/Cargo.toml @@ -13,8 +13,6 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" toml = "0.8.19" -pollster = "0.3.0" - rand = "0.8.5" num-bigint = "0.4.6" @@ -26,7 +24,7 @@ rsa-der = "0.3.0" flate2 = "1.0.30" # authentication -reqwest = { version = "0.12.5", features = ["json"]} +reqwest = { version = "0.12.5", features = ["json", "blocking"]} sha1 = "0.10.6" digest = "=0.11.0-pre.9" diff --git a/pumpkin/src/client/authentication.rs b/pumpkin/src/client/authentication.rs index dd69e5480..edf7e3807 100644 --- a/pumpkin/src/client/authentication.rs +++ b/pumpkin/src/client/authentication.rs @@ -1,4 +1,4 @@ -use std::{error, net::IpAddr}; +use std::{net::IpAddr}; use num_bigint::BigInt; use pumpkin_protocol::client::login::Property; @@ -9,14 +9,14 @@ use uuid::Uuid; use crate::server::Server; -#[derive(Deserialize, Clone)] +#[derive(Deserialize, Clone, Debug)] pub struct GameProfile { pub id: Uuid, pub name: String, pub properties: Vec, } -pub async fn authenticate( +pub fn authenticate( username: &str, server_hash: &str, ip: &IpAddr, @@ -34,14 +34,13 @@ pub async fn authenticate( .unwrap() .get(address) .send() - .await .map_err(|_| AuthError::FailedResponse)?; match response.status() { StatusCode::OK => {} StatusCode::NO_CONTENT => Err(AuthError::UnverifiedUsername)?, other => Err(AuthError::UnknownStatusCode(other.as_str().to_string()))?, } - let profile: GameProfile = response.json().await.map_err(|_| AuthError::FailedParse)?; + let profile: GameProfile = response.json().map_err(|_| AuthError::FailedParse)?; Ok(profile) } diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index 1688ce192..386c3e338 100644 --- a/pumpkin/src/client/client_packet.rs +++ b/pumpkin/src/client/client_packet.rs @@ -94,7 +94,7 @@ impl ClientPacketProcessor for Client { properties: vec![], }); - // we want encryption + // todo: check config for encryption let verify_token: [u8; 4] = rand::random(); let public_key_der = &server.public_key_der; let packet = CEncryptionRequest::new( @@ -117,6 +117,8 @@ impl ClientPacketProcessor for Client { .decrypt(Pkcs1v15Encrypt, &encryption_response.shared_secret) .map_err(|_| EncryptionError::FailedDecrypt) .unwrap(); + self.enable_encryption(&shared_secret) + .unwrap_or_else(|e| self.kick(&e.to_string())); if server.base_config.online_mode { let hash = Sha1::new() @@ -125,20 +127,17 @@ impl ClientPacketProcessor for Client { .finalize(); let hash = auth_digest(&hash); let ip = self.address.ip(); - match pollster::block_on(authentication::authenticate( + match authentication::authenticate( &self.gameprofile.as_ref().unwrap().name, &hash, &ip, server, - )) { + ) { Ok(p) => self.gameprofile = Some(p), Err(e) => self.kick(&e.to_string()), } } - self.enable_encryption(server, shared_secret) - .unwrap_or_else(|e| self.kick(&e.to_string())); - if let Some(profile) = self.gameprofile.as_ref().cloned() { let packet = CLoginSuccess::new(profile.id, profile.name, &profile.properties, false); self.send_packet(packet) diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 13fc061ec..dca85f2b9 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -32,7 +32,6 @@ use pumpkin_protocol::{ ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket, }; -use rsa::Pkcs1v15Encrypt; use std::io::Read; use thiserror::Error; @@ -99,16 +98,10 @@ impl Client { /// enables encryption pub fn enable_encryption( &mut self, - server: &mut Server, - shared_secret: Vec, // decrypted + shared_secret: &[u8], // decrypted ) -> Result<(), EncryptionError> { self.encrytion = true; - let shared_secret = server - .private_key - .decrypt(Pkcs1v15Encrypt, &shared_secret) - .map_err(|_| EncryptionError::FailedDecrypt)?; let crypt_key: [u8; 16] = shared_secret - .as_slice() .try_into() .map_err(|_| EncryptionError::SharedWrongLength)?; self.dec.enable_encryption(&crypt_key); diff --git a/pumpkin/src/configuration.rs b/pumpkin/src/configuration.rs index 0cc0cd39c..32c2f7373 100644 --- a/pumpkin/src/configuration.rs +++ b/pumpkin/src/configuration.rs @@ -68,7 +68,7 @@ impl Default for BasicConfiguration { server_address: "127.0.0.1".to_string(), server_port: 25565, seed: "".to_string(), - max_players: 0, + max_players: 100000, view_distances: 10, simulation_distance: 10, resource_pack: "".to_string(), diff --git a/pumpkin/src/server.rs b/pumpkin/src/server.rs index 8785ec9c0..34b1b6ffe 100644 --- a/pumpkin/src/server.rs +++ b/pumpkin/src/server.rs @@ -47,7 +47,7 @@ pub struct Server { pub advanced_config: AdvancedConfiguration, /// Used for Authentication, None is Online mode is disabled - pub auth_client: Option, + pub auth_client: Option, } impl Server { @@ -67,7 +67,7 @@ impl Server { ) .into_boxed_slice(); let auth_client = if config.0.online_mode { - Some(reqwest::Client::new()) + Some(reqwest::blocking::Client::new()) } else { None }; @@ -163,7 +163,7 @@ impl Server { } pub fn build_brand() -> Vec { - let brand = "pumpkin"; + let brand = "Pumpkin"; let mut buf = vec![]; let _ = VarInt32(brand.len() as i32).encode(&mut buf); buf.extend_from_slice(brand.as_bytes());