From db6589d361ee163b71c9f28de8867ba56f01ed20 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 22 Jun 2026 11:55:53 +0200 Subject: [PATCH] use nexact server --- Cargo.lock | 1 + rnex-core/Cargo.toml | 1 + rnex-core/src/grpc/account.rs | 213 ++++++++++++------------------ rnex-core/src/kerberos/mod.rs | 6 +- rnex-core/src/nex/auth_handler.rs | 4 +- 5 files changed, 95 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6245ab0..62a64e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2741,6 +2741,7 @@ dependencies = [ "sqlx 0.8.6", "thiserror", "tokio", + "tonic", "typenum", "ureq", "urlencoding", diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 0c37372..1f4e52b 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -38,6 +38,7 @@ futures = "0.3.32" async-trait = "0.1.89" ctor = "1.0.7" nex-account = { version = "0.1.3", registry = "spbr" } +tonic = "0.14.6" [dev-dependencies] # criterion = "0.7.0" diff --git a/rnex-core/src/grpc/account.rs b/rnex-core/src/grpc/account.rs index 70aca04..e782d7b 100644 --- a/rnex-core/src/grpc/account.rs +++ b/rnex-core/src/grpc/account.rs @@ -5,8 +5,13 @@ use rnex_core::PID; use std::array::TryFromSliceError; use std::ops::Deref; use std::{env, result}; +use std::sync::LazyLock; use thiserror::Error; use tokio::task::{JoinError, spawn_blocking}; +use nex_account::grpc::nex_account_service_client::NexAccountServiceClient; +use nex_account::grpc::Pid; +use tonic::transport::Channel; + static API_KEY: Lazy = Lazy::new(|| { let key = env::var("ACCOUNT_GQL_API_KEY").expect("no graphql ip specified"); @@ -26,8 +31,10 @@ pub enum Error { RequestError(#[from] ureq::Error), #[error(transparent)] Json(#[from] json::Error), - //#[error(transparent)] - //Status(#[from] tonic::Status), + #[error(transparent)] + Status(#[from] tonic::Status), + #[error(transparent)] + Transport(#[from] tonic::transport::Error), #[error("invalid password size: {0}")] PasswordConversion(#[from] TryFromSliceError), #[error("something happened")] @@ -38,141 +45,97 @@ pub enum Error { pub type Result = result::Result; -pub struct Client; //(reqwest::Client); +static NEX_ACCOUNT_URL: LazyLock = + LazyLock::new(|| env::var("NEX_ACCOUNT_ENDPOINT").expect("NEX_ACCOUNT_ENDPOINT not set")); + +pub struct Client(NexAccountServiceClient); //(reqwest::Client); impl Client { pub async fn new() -> Result { - //Ok(Self(reqwest::ClientBuilder::new().build()?)) - Ok(Self) - } - - async fn do_request(&self, request_data: JsonValue) -> Result { - let request = ureq::post(CLIENT_URI.as_str()) - .header("X-API-Key", API_KEY.deref()) - .content_type("application/json"); - let mut response = spawn_blocking(move || request.send(request_data.to_string())).await??; - - let str_body = response.body_mut().read_to_string()?; - Ok(json::parse(&str_body)?) - /* - let mut request = reqwest::Request::new(Method::POST, Url::from_str(CLIENT_URI.as_str()).unwrap()); - - *(request.body_mut()) = Some(Body::from(request_data.to_string())); - request.headers_mut().insert("X-API-Key", HeaderValue::from_str(&API_KEY).unwrap()); - request.headers_mut().insert("Content-Type", HeaderValue::from_str("application/json").unwrap()); - - let response = self.0.execute(request).await?; - - Ok(json::parse(&response.text().await?)?) - - */ - } - - pub async fn get_nex_password(&mut self, pid: PID) -> Result<[u8; 16]> { - let req = self - .do_request(object! { - "query": r"query($pid: Int!){ - userByPid(pid: $pid){ - nexPassword - } - }", - "variables": { - "pid": pid - } - }) + let client = NexAccountServiceClient::connect(NEX_ACCOUNT_URL.as_str()) .await?; + Ok(Self(client)) + } - let Some(val) = req - .entries() - .find(|v| v.0 == "data") - .ok_or(SomethingHappened)? - .1 - .entries() - .find(|v| v.0 == "userByPid") - .ok_or(SomethingHappened)? - .1 - .entries() - .find(|v| v.0 == "nexPassword") - .ok_or(SomethingHappened)? - .1 - .as_str() - else { - return Err(SomethingHappened); - }; + pub async fn get_nex_key(&mut self, pid: PID) -> Result<[u8; 16]> { + let prekey = self.0.get_nex_key_by_pid(Pid{pid}).await?.into_inner(); - Ok(val.as_bytes().try_into().map_err(|_| SomethingHappened)?) + let nexkey: [u8; 16] = prekey.key.try_into().map_err(|_| Error::SomethingHappened)?; + + Ok(nexkey) } pub async fn get_user_level(&mut self, pid: PID) -> Result { - let req = self - .do_request(object! { - "query": r"query($pid: Int!){ - userByPid(pid: $pid){ - accountLevel - } - }", - "variables": { - "pid": pid - } - }) - .await?; + // let req = self + // .do_request(object! { + // "query": r"query($pid: Int!){ + // userByPid(pid: $pid){ + // accountLevel + // } + // }", + // "variables": { + // "pid": pid + // } + // }) + // .await?; + // + // let Some(val) = req + // .entries() + // .find(|v| v.0 == "data") + // .ok_or(SomethingHappened)? + // .1 + // .entries() + // .find(|v| v.0 == "userByPid") + // .ok_or(SomethingHappened)? + // .1 + // .entries() + // .find(|v| v.0 == "accountLevel") + // .ok_or(SomethingHappened)? + // .1 + // .as_i32() + // else { + // return Err(SomethingHappened); + // }; - let Some(val) = req - .entries() - .find(|v| v.0 == "data") - .ok_or(SomethingHappened)? - .1 - .entries() - .find(|v| v.0 == "userByPid") - .ok_or(SomethingHappened)? - .1 - .entries() - .find(|v| v.0 == "accountLevel") - .ok_or(SomethingHappened)? - .1 - .as_i32() - else { - return Err(SomethingHappened); - }; - - Ok(val) + // everyone is tester until this is implemented + Ok(0) } - pub async fn get_pid_from_token(&mut self, token: String) -> Result { - let req = self - .do_request(object! { - "query": - r"query($token: String!){ - token(tokenData: $token){ - pid - } - }", - "variables": { - "token": token - } - }) - .await?; - // this breaks switch nex servers and should be fixed eventually - let Some(val) = req - .entries() - .find(|v| v.0 == "data") - .ok_or(SomethingHappened)? - .1 - .entries() - .find(|v| v.0 == "token") - .ok_or(SomethingHappened)? - .1 - .entries() - .find(|v| v.0 == "pid") - .ok_or(SomethingHappened)? - .1 - .as_i32() - else { - return Err(SomethingHappened); - }; - - Ok(val) - } + // pub async fn get_pid_from_token(&mut self, token: String) -> Result { + // let req = self + // .do_request(object! { + // "query": + // r"query($token: String!){ + // token(tokenData: $token){ + // pid + // } + // }", + // "variables": { + // "token": token + // } + // }) + // .await?; + // // this breaks switch nex servers and should be fixed eventually + // let Some(val) = req + // .entries() + // .find(|v| v.0 == "data") + // .ok_or(SomethingHappened)? + // .1 + // .entries() + // .find(|v| v.0 == "token") + // .ok_or(SomethingHappened)? + // .1 + // .entries() + // .find(|v| v.0 == "pid") + // .ok_or(SomethingHappened)? + // .1 + // .as_i32() + // else { + // return Err(SomethingHappened); + // }; + // + // Ok(val) + // } /*pub async fn get_user_data(&mut self , pid: u32) -> Result{ let req = Request::new(GetUserDataRequest{ diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index 1ca0576..1a44788 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -28,13 +28,13 @@ pub const SESSION_KEY_LENGTH: usize = SessionLengthTy::USIZE; type Md5Hmac = Hmac; -pub fn derive_key(pid: PID, password: &[u8]) -> [u8; 16] { - let iteration_count = 65000 + pid % 1024; +pub fn derive_key(pid: PID, key: &[u8]) -> [u8; 16] { + let iteration_count = pid % 1024; // we do one iteration out here to ensure the key is always 16 bytes let mut key: [u8; 16] = { let mut md5 = Md5::new(); - md5.update(password); + md5.update(key); md5.finalize().try_into().unwrap() }; diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index a5ffe2b..643c228 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -83,7 +83,7 @@ async fn get_login_data_by_pid(pid: PID) -> Option<(PID, Box<[u8]>)> { return None; }; - let Ok(passwd) = client.get_nex_password(pid).await else { + let Ok(passwd) = client.get_nex_key(pid).await else { return None; }; @@ -128,7 +128,7 @@ impl AuthHandler { return Err(ErrorCode::Core_Exception); }; - let Ok(passwd) = client.get_nex_password(pid).await else { + let Ok(passwd) = client.get_nex_key(pid).await else { warn!("unable to get nex password for pid: {}:", pid); return Err(ErrorCode::Core_Exception); };