diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/tpd.rs | 28 | ||||
| -rw-r--r-- | src/daemon.rs | 19 | ||||
| -rw-r--r-- | src/store.rs | 3 |
3 files changed, 42 insertions, 8 deletions
diff --git a/src/bin/tpd.rs b/src/bin/tpd.rs index 54dbd7f..a1edf79 100644 --- a/src/bin/tpd.rs +++ b/src/bin/tpd.rs @@ -308,14 +308,34 @@ fn load_or_create_identity(path: &std::path::Path) -> Vec<u8> { } let mut seed = [0u8; 32]; tesseras_dht::sys::random_bytes(&mut seed); - if let Err(e) = std::fs::write(path, seed) { - log::warn!("identity: failed to save to {}: {e}", path.display()); - } else { - log::info!("identity: generated new keypair at {}", path.display()); + match write_private_file(path, &seed) { + Ok(()) => { + log::info!("identity: generated new keypair at {}", path.display()); + } + Err(e) => { + log::warn!("identity: failed to save to {}: {e}", path.display()); + } } seed.to_vec() } +/// Write data to a file with mode 0600 (owner read/write only). +fn write_private_file( + path: &std::path::Path, + data: &[u8], +) -> std::io::Result<()> { + use std::io::Write; + use std::os::unix::fs::OpenOptionsExt; + let mut f = std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .mode(0o600) + .open(path)?; + f.write_all(data)?; + f.sync_all() +} + const SIGINT: i32 = 2; const SIGTERM: i32 = 15; diff --git a/src/daemon.rs b/src/daemon.rs index 88e3a09..f12efd9 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -413,8 +413,10 @@ fn handle_http( }; let request = String::from_utf8_lossy(&buf[..n]); - // Parse "GET /<path> HTTP/1.x" - let path = match request.split_whitespace().nth(1) { + // Parse "METHOD /<path> HTTP/1.x" + let mut parts = request.split_whitespace(); + let method = parts.next().unwrap_or(""); + let path = match parts.next() { Some(p) => p, None => { http_response(&mut stream, 400, "text/plain", b"Bad Request"); @@ -422,8 +424,18 @@ fn handle_http( } }; + if method != "GET" && method != "HEAD" { + http_response(&mut stream, 405, "text/plain", b"Method Not Allowed"); + return; + } + if path == "/" || path == "/favicon.ico" { - http_response(&mut stream, 200, "text/plain", b"tesseras-paste\n"); + http_response( + &mut stream, + 200, + "text/plain", + b"Hello Tesseras World\n", + ); return; } @@ -539,6 +551,7 @@ fn http_response( 200 => "OK", 400 => "Bad Request", 403 => "Forbidden", + 405 => "Method Not Allowed", 404 => "Not Found", 500 => "Internal Server Error", _ => "Unknown", diff --git a/src/store.rs b/src/store.rs index 98c5481..04d7414 100644 --- a/src/store.rs +++ b/src/store.rs @@ -182,7 +182,8 @@ impl PasteStore { /// corruption if the process is killed mid-write. fn atomic_write(path: &Path, chunks: &[&[u8]]) -> std::io::Result<()> { let parent = path.parent().unwrap_or(Path::new(".")); - let tmp = parent.join(format!(".tmp.{}", std::process::id())); + let name = path.file_name().and_then(|n| n.to_str()).unwrap_or("tmp"); + let tmp = parent.join(format!(".tmp.{}.{}", std::process::id(), name)); let mut f = fs::File::create(&tmp)?; for chunk in chunks { f.write_all(chunk)?; |