🐛 Use file permissions to forbid access to ptth_server.toml
parent
563465c85b
commit
5378e66e39
|
@ -29,6 +29,7 @@ reqwest = { version = "0.10.8", features = ["stream"] }
|
|||
rmp-serde = "0.14.4"
|
||||
serde = {version = "1.0.117", features = ["derive"]}
|
||||
structopt = "0.3.20"
|
||||
# thiserror = "1.0.22"
|
||||
tokio = { version = "0.2.22", features = ["full"] }
|
||||
tracing = "0.1.21"
|
||||
tracing-futures = "0.2.4"
|
||||
|
|
|
@ -21,7 +21,7 @@ async fn main () -> Result <(), Box <dyn Error>> {
|
|||
.init ()
|
||||
;
|
||||
|
||||
let config_file = ptth::load_toml::load ("config/ptth_relay.toml");
|
||||
let config_file = ptth::load_toml::load_public ("config/ptth_relay.toml");
|
||||
|
||||
info! ("ptth_relay Git version: {:?}", ptth::git_version::GIT_VERSION);
|
||||
|
||||
|
|
|
@ -7,19 +7,48 @@ use std::{
|
|||
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
pub fn load <
|
||||
pub const CONFIG_PERMISSIONS_MODE: u32 = 33152;
|
||||
|
||||
fn load_inner <
|
||||
T: DeserializeOwned
|
||||
> (
|
||||
mut f: File
|
||||
) -> T {
|
||||
let mut buffer = vec! [0u8; 4096];
|
||||
let bytes_read = f.read (&mut buffer).unwrap_or_else (|_| panic! ("Can't read config"));
|
||||
buffer.truncate (bytes_read);
|
||||
|
||||
let config_s = String::from_utf8 (buffer).unwrap_or_else (|_| panic! ("Can't parse config as UTF-8"));
|
||||
toml::from_str (&config_s).unwrap_or_else (|e| panic! ("Can't parse config as TOML: {}", e))
|
||||
}
|
||||
|
||||
/// For files that contain public-viewable information
|
||||
|
||||
pub fn load_public <
|
||||
T: DeserializeOwned,
|
||||
P: AsRef <Path> + Debug
|
||||
> (
|
||||
config_file_path: P
|
||||
) -> T {
|
||||
let mut f = File::open (&config_file_path).unwrap_or_else (|_| panic! ("Can't open {:?}", config_file_path));
|
||||
let mut buffer = vec! [0u8; 4096];
|
||||
let bytes_read = f.read (&mut buffer).unwrap_or_else (|_| panic! ("Can't read {:?}", config_file_path));
|
||||
buffer.truncate (bytes_read);
|
||||
load_inner (f)
|
||||
}
|
||||
|
||||
{
|
||||
let config_s = String::from_utf8 (buffer).unwrap_or_else (|_| panic! ("Can't parse {:?} as UTF-8", config_file_path));
|
||||
toml::from_str (&config_s).unwrap_or_else (|e| panic! ("Can't parse {:?} as TOML: {}", config_file_path, e))
|
||||
}
|
||||
/// For files that may contain secrets and should have permissions or other
|
||||
/// safeties checked
|
||||
|
||||
pub fn load <
|
||||
T: DeserializeOwned,
|
||||
P: AsRef <Path> + Debug
|
||||
> (
|
||||
config_file_path: P
|
||||
) -> T {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
let mut f = File::open (&config_file_path).unwrap_or_else (|_| panic! ("Can't open {:?}", config_file_path));
|
||||
|
||||
let mode = f.metadata ().unwrap ().permissions ().mode ();
|
||||
assert_eq! (mode, CONFIG_PERMISSIONS_MODE, "Config file has bad permissions mode, it should be octal 0600");
|
||||
|
||||
load_inner (f)
|
||||
}
|
||||
|
|
|
@ -500,7 +500,8 @@ async fn handle_all (req: Request <Body>, state: Arc <RelayState>)
|
|||
servers: Vec <ServerEntry <'a>>,
|
||||
}
|
||||
|
||||
let names = state.list_servers ().await;
|
||||
let mut names = state.list_servers ().await;
|
||||
names.sort ();
|
||||
|
||||
//println! ("Found {} servers", names.len ());
|
||||
|
||||
|
|
|
@ -501,8 +501,7 @@ async fn internal_serve_all (
|
|||
let path_s = percent_decode (encoded_path.as_bytes ()).decode_utf8 ().unwrap ();
|
||||
let path = Path::new (&*path_s);
|
||||
|
||||
let mut full_path = PathBuf::from (root);
|
||||
full_path.push (path);
|
||||
let full_path = root.join (path);
|
||||
|
||||
debug! ("full_path = {:?}", full_path);
|
||||
|
||||
|
@ -531,7 +530,14 @@ async fn internal_serve_all (
|
|||
})
|
||||
}
|
||||
else if let Ok (mut file) = File::open (&full_path).await {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
let file_md = file.metadata ().await.unwrap ();
|
||||
if file_md.permissions ().mode () == crate::load_toml::CONFIG_PERMISSIONS_MODE
|
||||
{
|
||||
return Forbidden;
|
||||
}
|
||||
|
||||
let file_len = file_md.len ();
|
||||
|
||||
let range_header = headers.get ("range").map (|v| std::str::from_utf8 (v).ok ()).flatten ();
|
||||
|
|
Loading…
Reference in New Issue