diff options
| author | Jan Wolff <janw@mailbox.org> | 2020-05-17 12:54:10 +0200 |
|---|---|---|
| committer | Jan Wolff <janw@mailbox.org> | 2020-05-17 12:54:10 +0200 |
| commit | 872197c55805161e1ed6bbbd13b169b3bc809fd5 (patch) | |
| tree | 600914246f6de5e7ae2cee82f0009aec3b2c77ac /src/server | |
| parent | 4a9c6c11acf4128b2c5158307088b0cbc377c3e5 (diff) | |
mime type handling and setuid/setgid support
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/handler.rs | 7 | ||||
| -rw-r--r-- | src/server/mod.rs | 38 |
2 files changed, 41 insertions, 4 deletions
diff --git a/src/server/handler.rs b/src/server/handler.rs index d27d292..ec9b523 100644 --- a/src/server/handler.rs +++ b/src/server/handler.rs @@ -1,5 +1,6 @@ use crate::server::response; use crate::server::ServerConfig; +use crate::mime; use openssl::ssl::SslStream; use std::fs::File; use std::io::{copy, BufReader, BufWriter}; @@ -77,7 +78,11 @@ fn handle_response(config: &ServerConfig, url: Url, mut stream: &mut SslStream<T } }; - let header = response::Header::new(response::Status::Success, "text/gemini"); + let mime_type = match path.extension() { + Some(ext) => mime::get_mime_type(ext), + None => mime::default_mime_type(), + }; + let header = response::Header::new(response::Status::Success, mime_type); send_header(&mut stream, &header); let mut buf_file = BufReader::new(file); diff --git a/src/server/mod.rs b/src/server/mod.rs index 696a3a5..f00ab35 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use std::thread; use std::vec::Vec; use url::Url; +use nix::unistd; pub mod handler; pub mod response; @@ -14,6 +15,8 @@ pub struct ServerConfig { default_host: Url, gem_root: PathBuf, addrs: Vec<SocketAddr>, + user: unistd::Uid, + group: unistd::Gid, } impl ServerConfig { @@ -22,6 +25,8 @@ impl ServerConfig { default_host: Url::parse("gemini://localhost").unwrap(), gem_root: PathBuf::from(""), addrs: Vec::new(), + user: unistd::getuid(), + group: unistd::getgid(), } } @@ -45,17 +50,29 @@ impl ServerConfig { Err(e) => panic!(e), }); } + + pub fn set_user(&mut self, uname: String) { + self.user = match unistd::User::from_name(&uname) { + Ok(user) => user.unwrap().uid, + Err(e) => panic!(e), + }; + } + + pub fn set_group(&mut self, gname: String) { + self.group = match unistd::Group::from_name(&gname) { + Ok(group) => group.unwrap().gid, + Err(e) => panic!(e), + }; + } } pub struct Server { - acceptor: std::sync::Arc<SslAcceptor>, config: ServerConfig, } impl Server { pub fn new(config: &ServerConfig) -> Server { Server { - acceptor: Server::build_acceptor(), config: config.clone(), } } @@ -71,12 +88,27 @@ impl Server { } pub fn serve(&self) { + let acceptor = Server::build_acceptor(); let listener = TcpListener::bind(&self.config.addrs[..]).unwrap(); + if self.config.user.is_root() { + panic!("refusing to run as root"); + } + + match unistd::setgid(self.config.group) { + Ok(_) => {}, + Err(e) => {panic!(e);}, + }; + + match unistd::setuid(self.config.user) { + Ok(_) => {}, + Err(e) => {panic!(e);}, + }; + for stream in listener.incoming() { match stream { Ok(stream) => { - let acceptor = self.acceptor.clone(); + let acceptor = acceptor.clone(); let config = self.config.clone(); thread::spawn(move || { let stream = acceptor.accept(stream).unwrap(); |
