From 62ba1420b9cf6933a9553dedf11eab413b0ed52e Mon Sep 17 00:00:00 2001 From: "D. Scott Boggs" Date: Mon, 26 Jun 2023 10:59:37 -0400 Subject: [PATCH] Add support for rocket's "secret cookies" --- docker-compose_dev.yml | 2 + docker-compose_prod.yml | 2 + server/Cargo.lock | 89 +++++++++++++++++++++++++++++++++++++++++ server/Cargo.toml | 2 +- server/src/api/mod.rs | 13 ++++++ 5 files changed, 107 insertions(+), 1 deletion(-) diff --git a/docker-compose_dev.yml b/docker-compose_dev.yml index 93d4bf1..60d71ec 100644 --- a/docker-compose_dev.yml +++ b/docker-compose_dev.yml @@ -65,6 +65,8 @@ services: secrets: postgres-password: file: ./server/postgres.pw + cookie-secret: + file: ./server/cookie-secret.pw networks: internal: diff --git a/docker-compose_prod.yml b/docker-compose_prod.yml index cb57656..71405e1 100644 --- a/docker-compose_prod.yml +++ b/docker-compose_prod.yml @@ -32,6 +32,8 @@ services: secrets: postgres-password: file: ./server/postgres.pw + cookie-secret: + file: ./server/cookie-secret.pw networks: internal: diff --git a/server/Cargo.lock b/server/Cargo.lock index 026a33f..7f9f8e9 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -8,6 +8,41 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "ahash" version = "0.7.6" @@ -380,7 +415,13 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" dependencies = [ + "aes-gcm", + "base64 0.21.2", + "hkdf", "percent-encoding", + "rand", + "sha2", + "subtle", "time 0.3.22", "version_check", ] @@ -426,9 +467,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "darling" version = "0.14.4" @@ -789,6 +840,16 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "glob" version = "0.3.1" @@ -1292,6 +1353,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "os_str_bytes" version = "6.5.1" @@ -1422,6 +1489,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "polyval" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2742,6 +2821,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.7.1" diff --git a/server/Cargo.toml b/server/Cargo.toml index ec1cbdb..68e15ca 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -41,7 +41,7 @@ features = [ [dependencies.rocket] git = "https://github.com/SergioBenitez/Rocket" rev = "v0.5.0-rc.3" -features = ["json"] +features = ["json", "secrets"] [dependencies.serde] version = "1.0.163" diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs index bec41f1..40fb19b 100644 --- a/server/src/api/mod.rs +++ b/server/src/api/mod.rs @@ -8,11 +8,13 @@ pub(crate) mod update; use std::{ default::default, + env, fs, net::{IpAddr, Ipv4Addr}, }; use crate::error::Error; use rocket::{ + config::SecretKey, fs::{FileServer, NamedFile}, response::stream::EventStream, routes, Build, Config, Rocket, State, @@ -61,6 +63,16 @@ async fn spa_index_redirect() -> ApiResult { .map_err(Error::from)?) } +fn get_secret() -> [u8; 32] { + let path = + env::var("COOKIE_SECRET_FILE").unwrap_or_else(|_| "/run/secrets/cookie-secret".into()); + let file_contents = + fs::read(&path).unwrap_or_else(|err| panic!("failed to read from {path:?}: {err:?}")); + let mut data = [0u8; 32]; + data.copy_from_slice(&file_contents); + data +} + pub(crate) fn start_server(db: DatabaseConnection) -> Rocket { use groups::*; use ticks::*; @@ -69,6 +81,7 @@ pub(crate) fn start_server(db: DatabaseConnection) -> Rocket { let it = rocket::build() .configure(Config { address: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), + secret_key: SecretKey::derive_from(&get_secret()), ..default() }) .register("/", catchers![spa_index_redirect])