From c1dc5313171a81097e1783ba63e208282665b398 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Tue, 6 Jul 2021 20:21:34 +0100 Subject: [PATCH] Set file permissions when creating files This isn't a full audit of all places files are created, but it covers most. Intentionally not set them on the image cache, as they're not sensitive. --- src/api/core/ciphers.rs | 37 +++++++++++++++++++++---------------- src/api/core/sends.rs | 3 +++ src/config.rs | 3 ++- src/main.rs | 4 +++- src/util.rs | 11 +++++++++++ 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index db455231..53a21094 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -13,6 +13,7 @@ use crate::{ auth::Headers, crypto, db::{models::*, DbConn, DbPool}, + util::set_file_mode, CONFIG, }; @@ -929,22 +930,26 @@ fn save_attachment( }; path = base_path.join(&file_id); - let size = - match field.data.save().memory_threshold(0).size_limit(size_limit).with_path(path.clone()) { - SaveResult::Full(SavedData::File(_, size)) => size as i32, - SaveResult::Full(other) => { - error = Some(format!("Attachment is not a file: {:?}", other)); - return; - } - SaveResult::Partial(_, reason) => { - error = Some(format!("Attachment size limit exceeded with this file: {:?}", reason)); - return; - } - SaveResult::Error(e) => { - error = Some(format!("Error: {:?}", e)); - return; - } - }; + let size = match field.data.save().memory_threshold(0).size_limit(size_limit).with_path(&path) { + SaveResult::Full(SavedData::File(_, size)) => size as i32, + SaveResult::Full(other) => { + error = Some(format!("Attachment is not a file: {:?}", other)); + return; + } + SaveResult::Partial(_, reason) => { + error = Some(format!("Attachment size limit exceeded with this file: {:?}", reason)); + return; + } + SaveResult::Error(e) => { + error = Some(format!("Error: {:?}", e)); + return; + } + }; + + if let Err(e) = set_file_mode(&path, 0o600) { + error = Some(format!("Error: {:?}", e)); + return; + }; if let Some(attachment) = &mut attachment { // v2 API diff --git a/src/api/core/sends.rs b/src/api/core/sends.rs index 13cd300e..79d6851e 100644 --- a/src/api/core/sends.rs +++ b/src/api/core/sends.rs @@ -10,6 +10,7 @@ use crate::{ api::{ApiResult, EmptyResult, JsonResult, JsonUpcase, Notify, UpdateType}, auth::{Headers, Host}, db::{models::*, DbConn, DbPool}, + util::set_file_mode, CONFIG, }; @@ -213,6 +214,8 @@ fn post_send_file(data: Data, content_type: &ContentType, headers: Headers, conn } }; + set_file_mode(&file_path, 0o600)?; + // Set ID and sizes let mut data_value: Value = serde_json::from_str(&send.data)?; if let Some(o) = data_value.as_object_mut() { diff --git a/src/config.rs b/src/config.rs index b1f86449..db3457b5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,7 +8,7 @@ use reqwest::Url; use crate::{ db::DbConnType, error::Error, - util::{get_env, get_env_bool, write_file}, + util::{get_env, get_env_bool, set_file_mode, write_file}, }; static CONFIG_FILE: Lazy = Lazy::new(|| { @@ -692,6 +692,7 @@ impl Config { //Save to file write_file(&CONFIG_FILE, config_str.as_bytes())?; + set_file_mode(&*CONFIG_FILE, 0o600)?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index bcf40e4a..b48d00e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,7 +32,7 @@ mod util; pub use config::CONFIG; pub use error::{Error, MapResult}; -pub use util::is_running_in_docker; +pub use util::{is_running_in_docker, set_file_mode}; fn main() { parse_args(); @@ -254,6 +254,7 @@ fn check_rsa_keys() -> Result<(), crate::error::Error> { let priv_key = rsa_key.private_key_to_pem()?; crate::util::write_file(&priv_path, &priv_key)?; + set_file_mode(&priv_path, 0o600)?; info!("Private key created correctly."); } @@ -262,6 +263,7 @@ fn check_rsa_keys() -> Result<(), crate::error::Error> { let pub_key = rsa_key.public_key_to_pem()?; crate::util::write_file(&pub_path, &pub_key)?; + set_file_mode(&pub_path, 0o600)?; info!("Public key created correctly."); } diff --git a/src/util.rs b/src/util.rs index 8512bc7b..dc81f012 100644 --- a/src/util.rs +++ b/src/util.rs @@ -248,6 +248,17 @@ pub fn delete_file(path: &str) -> IOResult<()> { res } +pub fn set_file_mode>(path: P, mode: u32) -> IOResult<()> { + if !cfg!(unix) { + // noop on non-unix + return Ok(()); + } + use std::fs::{set_permissions, Permissions}; + use std::os::unix::fs::PermissionsExt; + + set_permissions(&path, Permissions::from_mode(mode)) +} + const UNITS: [&str; 6] = ["bytes", "KB", "MB", "GB", "TB", "PB"]; pub fn get_display_size(size: i32) -> String {