diff --git a/Cargo.lock b/Cargo.lock index c7ffffd97ba..b45ed61909d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6072,6 +6072,7 @@ version = "1.0.0-beta.40" dependencies = [ "base64 0.22.1", "chrono", + "color-eyre", "futures", "hex", "indexmap 2.5.0", diff --git a/zebra-rpc/Cargo.toml b/zebra-rpc/Cargo.toml index 37349b34d8c..d3976e15e1e 100644 --- a/zebra-rpc/Cargo.toml +++ b/zebra-rpc/Cargo.toml @@ -71,6 +71,9 @@ indexmap = { version = "2.5.0", features = ["serde"] } base64 = "0.22.1" rand = "0.8.5" +# Error handling +color-eyre = "0.6.3" + tokio = { version = "1.40.0", features = [ "time", "rt-multi-thread", diff --git a/zebra-rpc/src/server.rs b/zebra-rpc/src/server.rs index a9b6dcfc6ac..9b12dad730d 100644 --- a/zebra-rpc/src/server.rs +++ b/zebra-rpc/src/server.rs @@ -194,8 +194,10 @@ impl RpcServer { parallel_cpu_threads = available_parallelism().map(usize::from).unwrap_or(1); } - // generate a cookie - cookie::generate(config.cookie_dir.clone()); + // Generate a RPC authentication cookie + if config.enable_cookie_auth { + let _ = cookie::generate(config.cookie_dir.clone()); + } // The server is a blocking task, which blocks on executor shutdown. // So we need to start it in a std::thread. @@ -303,7 +305,7 @@ impl RpcServer { span.in_scope(|| { info!("Stopping RPC server"); close_handle.clone().close(); - cookie::delete(); // delete the auth cookie + let _ = cookie::delete(); // delete the auth cookie if exists debug!("Stopped RPC server"); }) }; diff --git a/zebra-rpc/src/server/cookie.rs b/zebra-rpc/src/server/cookie.rs index cbcf7bd9f4e..213165a5cec 100644 --- a/zebra-rpc/src/server/cookie.rs +++ b/zebra-rpc/src/server/cookie.rs @@ -1,6 +1,7 @@ //! Cookie-based authentication for the RPC server. use base64::{engine::general_purpose::URL_SAFE, Engine as _}; +use color_eyre::Result; use rand::RngCore; use std::{ @@ -14,34 +15,34 @@ pub const COOKIEAUTH_USER: &str = "__cookie__"; /// Default name for auth cookie file */ pub const COOKIEAUTH_FILE: &str = ".cookie"; -/// Generate a new auth cookie and return the encoded password. -pub fn generate(cookie_dir: PathBuf) -> Option<()> { +/// Generate a new auth cookie and store it in the given `cookie_dir`. +pub fn generate(cookie_dir: PathBuf) -> Result<()> { let mut data = [0u8; 32]; rand::thread_rng().fill_bytes(&mut data); let encoded_password = URL_SAFE.encode(data); let cookie_content = format!("{}:{}", COOKIEAUTH_USER, encoded_password); - let mut file = File::create(cookie_dir.join(COOKIEAUTH_FILE)).ok()?; - file.write_all(cookie_content.as_bytes()).ok()?; + let mut file = File::create(cookie_dir.join(COOKIEAUTH_FILE))?; + file.write_all(cookie_content.as_bytes())?; tracing::info!("RPC auth cookie generated successfully"); - Some(()) + Ok(()) } /// Get the encoded password from the auth cookie. -pub fn get(cookie_dir: PathBuf) -> Option { - let mut file = File::open(cookie_dir.join(COOKIEAUTH_FILE)).ok()?; +pub fn get(cookie_dir: PathBuf) -> Result { + let mut file = File::open(cookie_dir.join(COOKIEAUTH_FILE))?; let mut contents = String::new(); - file.read_to_string(&mut contents).ok()?; + file.read_to_string(&mut contents)?; let parts: Vec<&str> = contents.split(":").collect(); - Some(parts[1].to_string()) + Ok(parts[1].to_string()) } /// Delete the auth cookie. -pub fn delete() -> Option<()> { - remove_file(COOKIEAUTH_FILE).ok()?; +pub fn delete() -> Result<()> { + remove_file(COOKIEAUTH_FILE)?; tracing::info!("RPC auth cookie deleted successfully"); - Some(()) + Ok(()) } diff --git a/zebra-rpc/src/server/http_request_compatibility.rs b/zebra-rpc/src/server/http_request_compatibility.rs index 653edc791d5..b07f04ef29d 100644 --- a/zebra-rpc/src/server/http_request_compatibility.rs +++ b/zebra-rpc/src/server/http_request_compatibility.rs @@ -180,7 +180,7 @@ impl FixHttpRequestMiddleware { .map(|password| password.to_string()) }) .map_or(false, |password| { - if let Some(cookie_password) = cookie::get(self.0.cookie_dir.clone()) { + if let Ok(cookie_password) = cookie::get(self.0.cookie_dir.clone()) { cookie_password == password } else { false