From 4cef62e8e4aa04e44048eb67e5091c12a73d2a09 Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Sun, 16 Oct 2022 22:54:54 -0500 Subject: Microsoft Authentication (#29) * a * try to do more work on auth signing (untested) * well auth works when i remove the d= so * auth stuff * sessionserver stuff * add auth in azalea-protocol/client * caching* refreshing microsoft auth tokens isn't implemented yet, also i haven't tested it * how did i not notice that i had the code duplicated * fix cache * add refreshing msa token * replace some printlns with log::trace * auth works! * Update main.rs * fix clippy warnings --- azalea-auth/src/sessionserver.rs | 79 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 azalea-auth/src/sessionserver.rs (limited to 'azalea-auth/src/sessionserver.rs') diff --git a/azalea-auth/src/sessionserver.rs b/azalea-auth/src/sessionserver.rs new file mode 100644 index 00000000..31857bc0 --- /dev/null +++ b/azalea-auth/src/sessionserver.rs @@ -0,0 +1,79 @@ +//! Tell Mojang you're joining a multiplayer server. +//! +use serde::Deserialize; +use serde_json::json; +use thiserror::Error; +use uuid::Uuid; + +#[derive(Debug, Error)] +pub enum SessionServerError { + #[error("Error sending HTTP request to sessionserver: {0}")] + HttpError(#[from] reqwest::Error), + #[error("Multiplayer is not enabled for this account")] + MultiplayerDisabled, + #[error("This account has been banned from multiplayer")] + Banned, + #[error("Unknown sessionserver error: {0}")] + Unknown(String), + #[error("Unexpected response from sessionserver (status code {status_code}): {body}")] + UnexpectedResponse { status_code: u16, body: String }, +} + +#[derive(Deserialize)] +pub struct ForbiddenError { + pub error: String, + pub path: String, +} + +/// Tell Mojang's servers that you are going to join a multiplayer server, +/// which is required to join online-mode servers. The server ID is an empty +/// string. +pub async fn join( + access_token: &str, + public_key: &[u8], + private_key: &[u8], + uuid: &Uuid, + server_id: &str, +) -> Result<(), SessionServerError> { + let client = reqwest::Client::new(); + + let server_hash = azalea_crypto::hex_digest(&azalea_crypto::digest_data( + server_id.as_bytes(), + public_key, + private_key, + )); + + let mut encode_buffer = Uuid::encode_buffer(); + let undashed_uuid = uuid.simple().encode_lower(&mut encode_buffer); + + let data = json!({ + "accessToken": access_token, + "selectedProfile": undashed_uuid, + "serverId": server_hash + }); + println!("data: {:?}", data); + let res = client + .post("https://sessionserver.mojang.com/session/minecraft/join") + .json(&data) + .send() + .await?; + + match res.status() { + reqwest::StatusCode::NO_CONTENT => Ok(()), + reqwest::StatusCode::FORBIDDEN => { + let forbidden = res.json::().await?; + match forbidden.error.as_str() { + "InsufficientPrivilegesException" => Err(SessionServerError::MultiplayerDisabled), + "UserBannedException" => Err(SessionServerError::Banned), + _ => Err(SessionServerError::Unknown(forbidden.error)), + } + } + status_code => { + let body = res.text().await?; + Err(SessionServerError::UnexpectedResponse { + status_code: status_code.as_u16(), + body, + }) + } + } +} -- cgit v1.2.3