aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bin/tpd.rs28
-rw-r--r--src/daemon.rs19
-rw-r--r--src/store.rs3
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)?;