From 2f50690fefefbc54b7bdee1f58e5403518713365 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Sun, 27 Mar 2022 14:20:07 +0200 Subject: [PATCH] Can restrict updates by ip --- src/main.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/main.rs b/src/main.rs index 424a11d..fa6c24b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,10 @@ struct Args { /// Handle for not found files. By default, a basic message is returned #[clap(short, long, env, default_value = "")] not_found_file: String, + + /// Optional proxy IP + #[clap(short, long, env)] + proxy_ip: Option, } impl Args { @@ -60,9 +64,57 @@ struct NewFile { bytes: Vec, } +// Check if two ips matches +pub fn match_ip(pattern: &str, ip: &str) -> bool { + if pattern.eq(ip) { + return true; + } + + if pattern.ends_with('*') && ip.starts_with(&pattern.replace('*', "")) { + return true; + } + + false +} + + +/// Get the remote IP address +fn get_remote_ip(req: &HttpRequest, args: &Args) -> String { + let mut ip = req.peer_addr().unwrap().ip().to_string(); + + // We check if the request comes from a trusted reverse proxy + if let Some(proxy) = args.proxy_ip.as_ref() { + if match_ip(proxy, &ip) { + if let Some(header) = req.headers().get("X-Forwarded-For") { + let header: Vec = header + .to_str() + .unwrap() + .to_string() + .split(",") + .map(|f| f.to_string()) + .collect(); + + if header.len() > 0 { + ip = header[0].to_string(); + } + } + } + } + + ip +} + + /// Replace all the files of the website async fn replace_files(args: web::Data, req: HttpRequest, mut payload: Multipart) -> Result { + // Validate remote IP + let remote_ip = get_remote_ip(&req, &args); + if !match_ip(&args.allowed_ips_for_update, &remote_ip) { + log::warn!("Block unauthorized attempt to perform site update from {}", remote_ip); + return Err(ErrorUnauthorized("You are not allowed to perform updates!")); + } + // Check token let token = match req.headers().get("Token") { None => {