From ce82f7d6a344af882d2991591756ea42b36fd527 Mon Sep 17 00:00:00 2001 From: _ <> Date: Sun, 2 May 2021 22:23:12 +0000 Subject: [PATCH] one-click registration works --- crates/ptth_relay/src/lib.rs | 66 +++++++++++++----------- crates/ptth_relay/src/relay_state.rs | 20 ++++++- crates/ptth_relay/src/scraper_api.rs | 25 ++++++--- crates/ptth_relay/src/server_endpoint.rs | 29 ----------- 4 files changed, 72 insertions(+), 68 deletions(-) diff --git a/crates/ptth_relay/src/lib.rs b/crates/ptth_relay/src/lib.rs index ad9da70..f69cf32 100644 --- a/crates/ptth_relay/src/lib.rs +++ b/crates/ptth_relay/src/lib.rs @@ -123,11 +123,8 @@ async fn handle_http_request ( let req_method = req.method.clone (); - { - let config = state.config.read ().await; - if ! config.servers.contains_key (server_name) { - return Err (UnknownServer); - } + if ! state.server_exists (server_name).await { + return Err (UnknownServer); } let user = get_user_name (&req); @@ -643,10 +640,16 @@ async fn handle_all ( let api_key = req.headers ().get ("X-ApiKey"); let api_key = match api_key { - None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run server without an API key")?), + None => return Ok (error_reply (StatusCode::FORBIDDEN, "Forbidden")?), Some (x) => x, }; - server_endpoint::handle_listen (state, listen_code.into (), api_key.as_bytes ()).await? + + match check_server_api_key (state, listen_code, api_key.as_bytes ()).await { + Ok (_) => (), + Err (_) => return Ok (error_reply (StatusCode::FORBIDDEN, "Forbidden")?) + } + + server_endpoint::handle_listen (state, listen_code.into ()).await? }, ServerHttpResponse { request_code, @@ -658,39 +661,40 @@ async fn handle_all ( Ok (response) } -async fn check_server_api_key (state: &Relay, name: &str, req: &http::request::Parts) +async fn check_server_api_key (state: &Relay, name: &str, api_key: &[u8]) -> Result <(), anyhow::Error> { - let api_key = req.headers.get ("X-ApiKey"); + let actual_tripcode = key_validity::BlakeHashWrapper::from_key (api_key); - let api_key = match api_key { - None => bail! ("Can't run server without an API key"), - Some (x) => x, - }; - - let actual_tripcode = blake3::hash (api_key.as_bytes ()); - - let expected_tripcode = { + let expected_human = { let config = state.config.read ().await; - match config.servers.get (name) { - None => { - state.unregistered_servers.push (crate::RejectedServer { - name: name.to_string (), - tripcode: actual_tripcode, - seen: Utc::now (), - }).await; - bail! ("Denied API request for non-existent server name {}", name); - }, - Some (x) => *(*x).tripcode, - } + config.servers.get (name).map (|s| s.tripcode.clone ()) }; - if expected_tripcode != actual_tripcode { - bail! ("Denied API request for bad tripcode {}", base64::encode (actual_tripcode.as_bytes ())); + let expected_machine = { + let me_config = state.me_config.read ().await; + + me_config.servers.get (name).map (|s| s.tripcode.clone ()) + }; + + if expected_machine.is_none () && expected_human.is_none () { + state.unregistered_servers.push (crate::RejectedServer { + name: name.to_string (), + tripcode: *actual_tripcode, + seen: Utc::now (), + }).await; + bail! ("Denied API request for non-existent server name {}", name); } - Ok (()) + if Some (actual_tripcode) == expected_human { + return Ok (()); + } + if Some (actual_tripcode) == expected_machine { + return Ok (()); + } + + bail! ("Denied API request for bad tripcode {}", base64::encode (actual_tripcode.as_bytes ())); } fn load_templates (asset_root: &Path) diff --git a/crates/ptth_relay/src/relay_state.rs b/crates/ptth_relay/src/relay_state.rs index 66107e9..1d5cd4c 100644 --- a/crates/ptth_relay/src/relay_state.rs +++ b/crates/ptth_relay/src/relay_state.rs @@ -182,7 +182,7 @@ impl TryFrom for Relay { let me_config = match machine_editable::Config::from_file (Path::new ("data/ptth_relay_me_config.toml")) { Err (e) => { - error! ("Can't load machine-editable config: {:?}", e); + warn! ("Can't load machine-editable config: {:?}", e); me_config }, Ok (x) => x, @@ -211,6 +211,24 @@ impl Relay { .collect () } + pub async fn server_exists (&self, name: &str) -> bool { + { + let config = self.config.read ().await; + if config.servers.contains_key (name) { + return true; + } + } + + { + let config = self.me_config.read ().await; + if config.servers.contains_key (name) { + return true; + } + } + + false + } + pub fn build () -> Builder { Builder::default () } diff --git a/crates/ptth_relay/src/scraper_api.rs b/crates/ptth_relay/src/scraper_api.rs index ef49d9c..67e0688 100644 --- a/crates/ptth_relay/src/scraper_api.rs +++ b/crates/ptth_relay/src/scraper_api.rs @@ -68,20 +68,31 @@ pub async fn v1_server_list (state: &Relay) -> ServerList { // name --> display_name - let display_names: HashMap = { + let mut display_names = HashMap::new (); + + { let guard = state.config.read ().await; - let servers = (*guard).servers.iter () - .map (|(k, v)| { + for (k, v) in &guard.servers { let display_name = v.display_name .clone () .unwrap_or_else (|| k.clone ()); - (k.clone (), display_name) - }); + display_names.insert (k.clone (), display_name); + } + } + + { + let guard = state.me_config.read ().await; - servers.collect () - }; + for (k, v) in &guard.servers { + let display_name = v.display_name + .clone () + .unwrap_or_else (|| k.clone ()); + + display_names.insert (k.clone (), display_name); + } + } // name --> status let server_statuses = { diff --git a/crates/ptth_relay/src/server_endpoint.rs b/crates/ptth_relay/src/server_endpoint.rs index ace791f..84333dd 100644 --- a/crates/ptth_relay/src/server_endpoint.rs +++ b/crates/ptth_relay/src/server_endpoint.rs @@ -45,41 +45,12 @@ use super::{ pub async fn handle_listen ( state: &Relay, watcher_code: String, - api_key: &[u8], ) -> Result , RequestError> { use super::RequestRendezvous::*; - let trip_error = || Ok (error_reply (StatusCode::UNAUTHORIZED, "Bad X-ApiKey")?); - let now = Utc::now (); - let actual_tripcode = blake3::hash (api_key); - - let expected_tripcode = { - let config = state.config.read ().await; - - match config.servers.get (&watcher_code) { - None => { - error! ("Denied http_listen for non-existent server name {}", watcher_code); - state.unregistered_servers.push (crate::RejectedServer { - name: watcher_code, - tripcode: actual_tripcode, - seen: now, - }).await; - - return trip_error (); - }, - Some (x) => *(*x).tripcode, - } - }; - - if expected_tripcode != actual_tripcode { - error! ("Denied http_listen for bad tripcode {}", base64::encode (actual_tripcode.as_bytes ())); - return trip_error (); - } - - // End of early returns { // TODO: Move into relay_state.rs