Skip to content

Commit 8018432

Browse files
Added login start packet UUID parsing
An issue has been detected for clients version 1.19.*
1 parent 7796e12 commit 8018432

File tree

9 files changed

+45
-16
lines changed

9 files changed

+45
-16
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ tracing = "0.1.41"
2323
tracing-subscriber = "0.3.19"
2424
base64_light = "0.1.5"
2525
toml = "0.8.20"
26+
uuid = "1.13.1"

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,8 @@ bad_session = "§cFailed to login: Invalid session (Try restarting your game and
118118
### 🚀 Running
119119
After configuring, run the compiled binary file through the console.
120120

121+
## Known issues
122+
- For Minecraft 1.19.* clients, encryption does not work correctly
123+
121124
---
122125
**Created by AndcoolSystems with ❤, 3 February, 2025**

config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ code_life_time = 300
66
[server]
77
addr = "0.0.0.0"
88
port = 25566
9-
timeout = 10
9+
timeout = 20
1010

1111
[server.config]
1212
protocol = 0

src/byte_buf_utils.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use anyhow::Error;
12
use bytes::{Buf, BufMut, BytesMut};
23
use std::io::{self, ErrorKind};
4+
use uuid::Uuid;
35

46
pub fn read_utf8(buf: &mut BytesMut) -> io::Result<String> {
57
let len = read_varint(buf)?;
@@ -76,3 +78,18 @@ pub fn read_unsigned_short(buf: &mut BytesMut) -> io::Result<u16> {
7678
}
7779
Ok(buf.get_u16())
7880
}
81+
82+
pub fn try_get_uuid(buf: &mut BytesMut) -> anyhow::Result<Uuid> {
83+
let len = buf.len();
84+
if len < 16 {
85+
return Err(Error::msg("Not enough data"));
86+
}
87+
88+
if len > 16 {
89+
buf.advance(len - 16); // Normalize uuid length
90+
}
91+
92+
let mut bytes = [0u8; 16];
93+
buf.copy_to_slice(&mut bytes);
94+
Ok(uuid::Uuid::from_slice(&bytes)?)
95+
}

src/client_sessions.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
// use std::collections::HashMap;
2-
// use std::net::SocketAddr;
3-
// use std::sync::Arc;
4-
// use tokio::sync::Mutex;
5-
61
use aes::Aes128;
72
use cfb8::Encryptor;
3+
use uuid::Uuid;
84

95
use crate::generators::keys::generate_verify_token;
106

@@ -21,6 +17,7 @@ pub struct Session {
2117
pub proto_ver: Option<usize>,
2218
pub next_state: NextStateEnum,
2319
pub nickname: Option<String>,
20+
pub uuid: Option<Uuid>,
2421
pub secret: Option<Vec<u8>>, // Shared secret,
2522
pub verify_token: [u8; 4],
2623
pub cipher: Option<Encryptor<Aes128>>,
@@ -33,11 +30,10 @@ impl Session {
3330
proto_ver: None,
3431
next_state: NextStateEnum::Unknown,
3532
nickname: None,
33+
uuid: None,
3634
secret: None,
3735
verify_token: generate_verify_token(),
3836
cipher: None,
3937
}
4038
}
4139
}
42-
43-
//pub type SessionMap = Arc<Mutex<HashMap<SocketAddr, Session>>>;

src/handlers/client_handler.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ pub async fn handle(mut stream: TcpStream, keys: Arc<rsa::RsaPrivateKey>) -> Res
5555
}
5656
NextStateEnum::Login => {
5757
debug!("Received encryption response");
58-
encryption_response::handle(session, &mut buffer, keys.clone())?;
58+
encryption_response::handle(session, &mut buffer, keys.clone())
59+
.expect("Encryption response handling error");
5960

6061
let player_data = mojang::join(session, keys.clone()).await?;
6162
if player_data.is_none() {

src/handlers/login_start.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::{client_sessions::Session, packets::login_start::LoginStartPacket};
22
use bytes::BytesMut;
3-
use tokio::io;
43

5-
pub fn handle(session: &mut Session, buff: &mut BytesMut) -> Result<(), io::Error> {
4+
pub fn handle(session: &mut Session, buff: &mut BytesMut) -> anyhow::Result<()> {
65
let packet = LoginStartPacket::parse(buff)?;
76
session.nickname = Some(packet.name);
7+
session.uuid = packet.uuid;
88
Ok(())
99
}

src/mojang/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::sync::Arc;
44

55
use anyhow::Result;
66
use sha1::{Digest, Sha1};
7+
use tracing::debug;
78

89
use crate::{client_sessions::Session, config};
910
use rsa::pkcs8::EncodePublicKey;
@@ -20,6 +21,8 @@ pub async fn join(
2021
digest.update(keys.to_public_key().to_public_key_der()?.as_bytes());
2122
let hash = BigInt::from_signed_bytes_be(&digest.finalize()).to_str_radix(16);
2223

24+
debug!("Creating request to Mojang API with hash: {hash}");
25+
2326
let config = config::get_config().await;
2427
let response = reqwest::get(
2528
config
@@ -31,6 +34,11 @@ pub async fn join(
3134
)
3235
.await?;
3336

37+
debug!(
38+
"Mojang API responded with code: {}",
39+
response.status().as_u16()
40+
);
41+
3442
if response.status().as_u16() != 200 {
3543
return Ok(None);
3644
}

src/packets/login_start.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
use bytes::BytesMut;
2-
use tokio::io;
2+
use uuid::Uuid;
33

4-
use crate::byte_buf_utils::read_utf8;
4+
use crate::byte_buf_utils::{read_utf8, try_get_uuid};
55

66
#[allow(dead_code)]
77
pub struct LoginStartPacket {
88
pub name: String,
9-
pub uuid: String,
9+
pub uuid: Option<Uuid>,
1010
}
1111

1212
impl LoginStartPacket {
13-
pub fn parse(buff: &mut BytesMut) -> Result<Self, io::Error> {
13+
pub fn parse(buff: &mut BytesMut) -> anyhow::Result<Self> {
1414
Ok(Self {
1515
name: read_utf8(buff)?,
16-
uuid: "".to_string(),
16+
uuid: match try_get_uuid(buff) {
17+
Ok(uuid) => Some(uuid),
18+
Err(_) => None,
19+
},
1720
})
1821
}
1922
}

0 commit comments

Comments
 (0)