From 34bce1ee22d58fed94c177df58bd83af9a77773e Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 28 Apr 2019 22:41:41 +0200 Subject: [PATCH] fix paths handling in hagrid (for nginx, too) --- .gitignore | 4 +- Rocket.toml.dist | 27 +++++++++--- database/src/fs.rs | 46 +++++++++++--------- dist/templates/manage/manage_key.html.hbs | 2 +- hagrid-routes.conf | 51 +++++++++++------------ src/web/mod.rs | 18 ++++---- 6 files changed, 84 insertions(+), 64 deletions(-) diff --git a/.gitignore b/.gitignore index 864a4b0..46fc87d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ /Rocket.toml /target +/state **/*.rs.bk -/dist/public/by-* -/dist/verification_tokens/* -/dist/deletion_tokens/* **/.*.swp **/.*.swo diff --git a/Rocket.toml.dist b/Rocket.toml.dist index 14241ce..b8c6372 100644 --- a/Rocket.toml.dist +++ b/Rocket.toml.dist @@ -1,11 +1,6 @@ [global] address = "0.0.0.0" port = 8080 -template_dir = "dist/templates" -assets_dir = "dist/assets" -keys_dir = "dist/keys" -token_dir = "dist/tokens" -tmp_dir = "dist/tmp" [development] base-URI = "http://localhost:8080" @@ -13,13 +8,35 @@ from = "noreply@localhost" x-accel-redirect = false token_secret = "hagrid" token_validity = 3600 +template_dir = "dist/templates" +assets_dir = "dist/assets" +keys_internal_dir = "state/keys-internal" +keys_external_dir = "state/keys-external" +token_dir = "state/tokens" +tmp_dir = "state/tmp" [staging] base-URI = "https://keys.openpgp.org" from = "noreply@keys.openpgp.org" x-accel-redirect = true +token_secret = "hagrid" +token_validity = 3600 +template_dir = "templates" +keys_internal_dir = "keys" +keys_external_dir = "public/keys" +assets_dir = "public/assets" +token_dir = "tokens" +tmp_dir = "tmp" [production] base-URI = "https://keys.openpgp.org" from = "noreply@keys.openpgp.org" x-accel-redirect = true +token_secret = "generated production secret" +token_validity = 3600 +template_dir = "templates" +keys_internal_dir = "keys" +keys_external_dir = "public/keys" +assets_dir = "public/assets" +token_dir = "tokens" +tmp_dir = "tmp" diff --git a/database/src/fs.rs b/database/src/fs.rs index 4036eda..8cbdd0f 100644 --- a/database/src/fs.rs +++ b/database/src/fs.rs @@ -24,7 +24,8 @@ pub struct Filesystem { tmp_dir: PathBuf, - keys_dir: PathBuf, + keys_internal_dir: PathBuf, + keys_external_dir: PathBuf, keys_dir_full: PathBuf, keys_dir_published: PathBuf, @@ -51,11 +52,12 @@ impl Filesystem { let keys_dir = base_dir.join("keys"); let tmp_dir = base_dir.join("tmp"); - Self::new(keys_dir, tmp_dir) + Self::new(&keys_dir, &keys_dir, tmp_dir) } pub fn new( - keys_dir: impl Into, + keys_internal_dir: impl Into, + keys_external_dir: impl Into, tmp_dir: impl Into, ) -> Result { @@ -90,25 +92,28 @@ impl Filesystem { let tmp_dir = tmp_dir.into(); create_dir_all(&tmp_dir)?; - let keys_dir: PathBuf = keys_dir.into(); - let keys_dir_full = keys_dir.join("full"); - let keys_dir_published = keys_dir.join("published"); + let keys_internal_dir: PathBuf = keys_internal_dir.into(); + let keys_external_dir: PathBuf = keys_external_dir.into(); + let keys_dir_full = keys_internal_dir.join("full"); + let keys_dir_published = keys_external_dir.join("published"); create_dir_all(&keys_dir_full)?; create_dir_all(&keys_dir_published)?; - let links_dir_by_keyid = keys_dir.join("by-keyid"); - let links_dir_by_fingerprint = keys_dir.join("by-fpr"); - let links_dir_by_email = keys_dir.join("by-email"); + let links_dir_by_keyid = keys_external_dir.join("by-keyid"); + let links_dir_by_fingerprint = keys_external_dir.join("by-fpr"); + let links_dir_by_email = keys_external_dir.join("by-email"); create_dir_all(&links_dir_by_keyid)?; create_dir_all(&links_dir_by_fingerprint)?; create_dir_all(&links_dir_by_email)?; info!("Opened filesystem database."); - info!("keys_dir: '{}'", keys_dir.display()); + info!("keys_internal_dir: '{}'", keys_internal_dir.display()); + info!("keys_external_dir: '{}'", keys_external_dir.display()); info!("tmp_dir: '{}'", tmp_dir.display()); Ok(Filesystem { - update_lock: FlockMutex::new(&keys_dir)?, - keys_dir, + update_lock: FlockMutex::new(&keys_internal_dir)?, + keys_internal_dir, + keys_external_dir, tmp_dir, keys_dir_full, @@ -152,11 +157,12 @@ impl Filesystem { self.links_dir_by_email.join(path_split(&email)) } - fn read_from_path(&self, path: &Path) -> Option { + fn read_from_path(&self, path: &Path, allow_internal: bool) -> Option { use std::fs; - if !path.starts_with(&self.keys_dir) { - panic!("Attempted to access file outside keys_dir!"); + if !path.starts_with(&self.keys_external_dir) && + !(allow_internal && path.starts_with(&self.keys_internal_dir)) { + panic!("Attempted to access file outside expected dirs!"); } if path.exists() { @@ -441,7 +447,7 @@ impl Database for Filesystem { }; if path.exists() { - let x = diff_paths(&path, &self.keys_dir).expect("related paths"); + let x = diff_paths(&path, &self.keys_external_dir).expect("related paths"); Some(x) } else { None @@ -516,25 +522,25 @@ impl Database for Filesystem { // XXX: slow fn by_fpr_full(&self, fpr: &Fingerprint) -> Option { let path = self.fingerprint_to_path_full(fpr); - self.read_from_path(&path) + self.read_from_path(&path, true) } // XXX: slow fn by_fpr(&self, fpr: &Fingerprint) -> Option { let path = self.link_by_fingerprint(fpr); - self.read_from_path(&path) + self.read_from_path(&path, false) } // XXX: slow fn by_email(&self, email: &Email) -> Option { let path = self.link_by_email(&email); - self.read_from_path(&path) + self.read_from_path(&path, false) } // XXX: slow fn by_kid(&self, kid: &KeyID) -> Option { let path = self.link_by_keyid(kid); - self.read_from_path(&path) + self.read_from_path(&path, false) } } diff --git a/dist/templates/manage/manage_key.html.hbs b/dist/templates/manage/manage_key.html.hbs index 41fdf60..f7e4982 100644 --- a/dist/templates/manage/manage_key.html.hbs +++ b/dist/templates/manage/manage_key.html.hbs @@ -2,7 +2,7 @@ {{#if uid_status}}

- Your key {{key_fpr}} is published for the following addresses. + Your key {{key_fpr}} is published for the following addresses.

{{#each uid_status}} diff --git a/hagrid-routes.conf b/hagrid-routes.conf index 71c2e6f..f181122 100644 --- a/hagrid-routes.conf +++ b/hagrid-routes.conf @@ -5,24 +5,24 @@ client_max_body_size 1m; location /vks/v1/by-email/ { - rewrite "^/vks/v1/by-email/([^/]{2})([^/]*)$" /by-email/$1/$2 break; + rewrite "^/vks/v1/by-email/([^/][^/])([^/][^/])([^/]*)$" /by-email/$1$2$3 break; default_type application/pgp-keys; - add_header Content-Disposition 'attachment; filename="$1$2.asc"'; - try_files /$uri =404; + add_header Content-Disposition 'attachment; filename="$1$2$3.asc"'; + try_files /by-email/$1/$2/$3 @fallback; } location /vks/v1/by-fingerprint/ { - rewrite ^/vks/v1/by-fingerprint/(0x)?([^/][^/])(..*)$ /vks/v1/by-fingerprint/$2$3 break; + rewrite ^/vks/v1/by-fingerprint/(0x)?([^/][^/])([^/][^/])(..*)$ /vks/v1/by-fingerprint/$2$3$4 break; default_type application/pgp-keys; - add_header Content-Disposition 'attachment; filename="$2$3.asc"'; - try_files /by-fpr/$2/$3 @fallback; + add_header Content-Disposition 'attachment; filename="$2$3$4.asc"'; + try_files /by-fpr/$2/$3/$4 @fallback; } location /vks/v1/by-keyid/ { - rewrite ^/vks/v1/by-keyid/(0x)?([^/][^/])(.*)$ /vks/v1/by-keyid/$2$3 break; + rewrite ^/vks/v1/by-keyid/(0x)?([^/][^/])([^/][^/])(.*)$ /vks/v1/by-keyid/$2$3$4 break; default_type application/pgp-keys; - add_header Content-Disposition 'attachment; filename="$2$3.asc"'; - try_files /by-keyid/$2/$3 @fallback; + add_header Content-Disposition 'attachment; filename="$2$3$4.asc"'; + try_files /by-keyid/$2/$3/$4 @fallback; } # Pass queries that we do not understand to hagrid. @@ -57,22 +57,7 @@ location /pks/lookup { proxy_pass http://127.0.0.1:8080; } -location /pks/add { - proxy_pass http://127.0.0.1:8080; -} - -location = / { - proxy_cache static_cache; - proxy_pass http://127.0.0.1:8080; -} - -location = /about { - proxy_cache static_cache; - proxy_pass http://127.0.0.1:8080; -} - -location = /apidoc { - proxy_cache static_cache; +location /pks { proxy_pass http://127.0.0.1:8080; } @@ -80,10 +65,22 @@ location /vks/v1/ { proxy_pass http://127.0.0.1:8080; } -location = /delete { +location /manage { proxy_pass http://127.0.0.1:8080; } -location = /publish { +location /publish { + proxy_pass http://127.0.0.1:8080; +} + +# explicitly cache the home directory +location = / { + proxy_cache static_cache; + proxy_pass http://127.0.0.1:8080; +} + +# cache "about" pages +location /about { + proxy_cache static_cache; proxy_pass http://127.0.0.1:8080; } diff --git a/src/web/mod.rs b/src/web/mod.rs index d9b205a..11e36fa 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -169,7 +169,7 @@ pub struct HagridState { assets_dir: PathBuf, /// The keys directory, where keys are located, served by hagrid or nginx - keys_dir: PathBuf, + keys_external_dir: PathBuf, /// XXX base_uri: String, @@ -193,7 +193,7 @@ fn key_to_response<'a>(state: rocket::State, if machine_readable { if state.x_accel_redirect { if let Some(key_path) = db.lookup_path(&query) { - let x_accel_path = state.keys_dir.join(&key_path).to_string_lossy().to_string(); + let x_accel_path = state.keys_external_dir.join(&key_path).to_string_lossy().to_string(); return MyResponse::x_accel_redirect(x_accel_path, &fp); } } @@ -230,7 +230,7 @@ fn key_has_uids(state: &HagridState, db: &KeyDatabase, query: &Query) use sequoia_openpgp::Packet; use sequoia_openpgp::parse::{Parse, PacketParser, PacketParserResult}; let mut ppr = match db.lookup_path(query) { - Some(path) => PacketParser::from_file(&state.keys_dir.join(path))?, + Some(path) => PacketParser::from_file(&state.keys_external_dir.join(path))?, None => return Err(failure::err_msg("key vanished")), }; @@ -389,22 +389,23 @@ fn rocket_factory(rocket: rocket::Rocket) -> Result { } fn configure_db_service(config: &Config) -> Result { - let keys_dir: PathBuf = config.get_str("keys_dir")?.into(); + let keys_internal_dir: PathBuf = config.get_str("keys_internal_dir")?.into(); + let keys_external_dir: PathBuf = config.get_str("keys_external_dir")?.into(); let tmp_dir: PathBuf = config.get_str("tmp_dir")?.into(); - let fs_db = KeyDatabase::new(keys_dir, tmp_dir)?; + let fs_db = KeyDatabase::new(keys_internal_dir, keys_external_dir, tmp_dir)?; Ok(fs_db) } fn configure_hagrid_state(config: &Config) -> Result { let assets_dir: PathBuf = config.get_str("assets_dir")?.into(); - let keys_dir: PathBuf = config.get_str("keys_dir")?.into(); + let keys_external_dir: PathBuf = config.get_str("keys_external_dir")?.into(); // State let base_uri = config.get_str("base-URI")?.to_string(); Ok(HagridState { assets_dir, - keys_dir: keys_dir, + keys_external_dir: keys_external_dir, base_uri: base_uri.clone(), x_accel_redirect: config.get_bool("x-accel-redirect")?, }) @@ -495,7 +496,8 @@ pub mod tests { .extra("assets_dir", ::std::env::current_dir().unwrap().join("dist/assets") .to_str().unwrap()) - .extra("keys_dir", base_dir.join("keys").to_str().unwrap()) + .extra("keys_internal_dir", base_dir.join("keys_internal").to_str().unwrap()) + .extra("keys_external_dir", base_dir.join("keys_external").to_str().unwrap()) .extra("tmp_dir", base_dir.join("tmp").to_str().unwrap()) .extra("token_dir", base_dir.join("tokens").to_str().unwrap()) .extra("base-URI", BASE_URI)