zebra_rpc/server/
cookie.rs

1//! Cookie-based authentication for the RPC server.
2
3use base64::{engine::general_purpose::URL_SAFE, Engine as _};
4use color_eyre::Result;
5use rand::RngCore;
6
7use std::{
8    fs::{remove_file, File},
9    io::Write,
10    path::Path,
11};
12
13/// The name of the cookie file on the disk
14const FILE: &str = ".cookie";
15
16/// If the RPC authentication is enabled, all requests must contain this cookie.
17#[derive(Clone, Debug)]
18pub struct Cookie(String);
19
20impl Cookie {
21    /// Checks if the given passwd matches the contents of the cookie.
22    pub fn authenticate(&self, passwd: String) -> bool {
23        *passwd == self.0
24    }
25}
26
27impl Default for Cookie {
28    fn default() -> Self {
29        let mut bytes = [0u8; 32];
30        rand::thread_rng().fill_bytes(&mut bytes);
31
32        Self(URL_SAFE.encode(bytes))
33    }
34}
35
36/// Writes the given cookie to the given dir.
37pub fn write_to_disk(cookie: &Cookie, dir: &Path) -> Result<()> {
38    // Create the directory if needed.
39    std::fs::create_dir_all(dir)?;
40    File::create(dir.join(FILE))?.write_all(format!("__cookie__:{}", cookie.0).as_bytes())?;
41
42    tracing::info!("RPC auth cookie written to disk");
43
44    Ok(())
45}
46
47/// Removes a cookie from the given dir.
48pub fn remove_from_disk(dir: &Path) -> Result<()> {
49    remove_file(dir.join(FILE))?;
50
51    tracing::info!("RPC auth cookie removed from disk");
52
53    Ok(())
54}