diff --git a/client.toml b/client.toml new file mode 100644 index 0000000..2b5a5ff --- /dev/null +++ b/client.toml @@ -0,0 +1,11 @@ +[client] +endpoint = "alphamethyl.barr0w.net:9092" +server_name = "alphamethyl.barr0w.net" + +[tls] +cert_file = "client_tls.crt" +key_file = "client_tls.key" + +[interface] +address = "192.168.255.1" +netmask = "255.255.255.254" diff --git a/config.toml b/config.toml index e84b4c9..6ed0588 100644 --- a/config.toml +++ b/config.toml @@ -12,8 +12,8 @@ endpoint = "alphamethyl.barr0w.net:9092" server_name = "alphamethyl.barr0w.net" [tls] -cert_file = "tls.crt" -key_file = "tls.key" +cert_file = "/etc/sleepytunny/tls.crt" +key_file = "/etc/sleepytunny/tls.key" [interface] address = "192.168.255.1" diff --git a/server.toml b/server.toml new file mode 100644 index 0000000..29d68dc --- /dev/null +++ b/server.toml @@ -0,0 +1,16 @@ +[server] +daemonize = true +endpoint = "127.0.0.1:9092" +server_name = "alphamethyl.barr0w.net" +user = "nobody" +group = "daemon" +stdout = "/tmp/sleepyserver" +stderr = "/tmp/sleepyserver.err" + +[tls] +cert_file = "server_tls.crt" +key_file = "server_tls.key" + +[interface] +address = "192.168.255.0" +netmask = "255.255.255.254" diff --git a/src/bin/client.rs b/src/bin/client.rs index e07e984..074b418 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -14,8 +14,12 @@ * -Ezra Barrow * -------------------- */ +use std::sync::Arc; +use sleepytunny::config::Configuration; #[tokio::main] async fn main() -> anyhow::Result<()> { - sleepytunny::client_main().await + let c = Arc::new(Configuration::load_config("client.toml")?); + let tls = &c.tls.clone().unwrap().load()?; + sleepytunny::client_main(c.clone(), tls.clone()).await } diff --git a/src/bin/generate_config.rs b/src/bin/generate_config.rs index 6c6389f..6d68c1a 100644 --- a/src/bin/generate_config.rs +++ b/src/bin/generate_config.rs @@ -17,5 +17,8 @@ #[tokio::main] async fn main() -> anyhow::Result<()> { - sleepytunny::config::Configuration::generate_config("config.toml") + sleepytunny::config::Configuration::generate_config("config.toml")?; + sleepytunny::config::Configuration::generate_client_conf("client.toml")?; + sleepytunny::config::Configuration::generate_server_conf("server.toml")?; + Ok(()) } diff --git a/src/bin/mkcert.rs b/src/bin/mkcert.rs index 6b8c73e..9b42006 100644 --- a/src/bin/mkcert.rs +++ b/src/bin/mkcert.rs @@ -23,7 +23,7 @@ fn main() -> anyhow::Result<()> { match &config.tls { Some(t) => { let server_names: Option = match config.server() { - Ok(s) => Some(s.server_name.clone().unwrap_or(String::from("localhost"))), + Ok(s) => Some(s.server_name()?.cloned().unwrap_or(String::from("localhost"))), Err(_) => None, }; // Lets vectorize it. diff --git a/src/bin/server.rs b/src/bin/server.rs index 7476bc9..2a9073a 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -25,7 +25,7 @@ use sleepytunny::config::Configuration; #[tokio::main] async fn main() -> anyhow::Result<()> { - let c = Arc::new(Configuration::load_config("config.toml")?); + let c = Arc::new(Configuration::load_config("server.toml")?); let tun = Tun::builder() .name("sleepy") .tap(false) @@ -34,7 +34,7 @@ async fn main() -> anyhow::Result<()> { .netmask(c.interface.netmask) .up() .try_build()?; - let tun = tun; + let keypair = &c.tls.clone().unwrap().load()?; let user = &c.server()?.user()?; let group = &c.server()?.group()?; let stdout = File::create(&c.server()?.stdout()?)?; @@ -45,15 +45,15 @@ async fn main() -> anyhow::Result<()> { .group(group.as_str()) .stdout(stdout) .stderr(stderr); - if c.server()?.daemonize { + if c.server()?.daemonize()? { match daemonize.start() { - Ok(_) => sleepytunny::server_main(c.clone(), tun).await, + Ok(_) => sleepytunny::server_main(c.clone(), tun, keypair.clone()).await, Err(e) => { eprintln!("Error, {}", e); panic!() } } } else { - sleepytunny::server_main(c.clone(), tun).await + sleepytunny::server_main(c.clone(), tun, keypair.clone()).await } } diff --git a/src/config.rs b/src/config.rs index b73032d..66b2fc1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,27 +4,26 @@ use std::fs; use std::io::Write; use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs}; -//TODO: use Arc instead of String for all this stuff that needs to be cloned and last forever - #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Server { - pub daemonize: bool, - pub endpoint: String, #[serde(skip_serializing_if = "Option::is_none")] - pub server_name: Option, + daemonize: Option, + endpoint: String, #[serde(skip_serializing_if = "Option::is_none")] - pub user: Option, + server_name: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub group: Option, + user: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub stdout: Option, + group: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub stderr: Option, + stdout: Option, + #[serde(skip_serializing_if = "Option::is_none")] + stderr: Option, } impl Server { pub fn new() -> Self { Self { - daemonize: true, + daemonize: Some(true), endpoint: String::from("127.0.0.1:9092"), server_name: Some(String::from("alphamethyl.barr0w.net")), user: Some(String::from("nobody")), @@ -33,6 +32,12 @@ impl Server { stderr: Some(String::from("/tmp/sleepyserver.err")), } } + pub fn daemonize(&self) -> anyhow::Result { + match self.daemonize { + Some(b) => Ok(b), + None => Ok(true), + } + } pub fn user(&self) -> anyhow::Result { match &self.user { Some(u) => Ok(u.clone()), @@ -103,33 +108,42 @@ impl Client { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TLS { pub cert_file: String, - #[serde(skip_serializing)] - pub cert: Option, // Eventually maybe an actual cert object pub key_file: String, - #[serde(skip_serializing)] - pub key: Option, // Eventually maybe an actual key object } impl TLS { pub fn new() -> Self { Self { cert_file: String::from("/etc/sleepytunny/tls.crt"), key_file: String::from("/etc/sleepytunny/tls.key"), - cert: None, - key: None, } } - pub fn load(&mut self) -> anyhow::Result<()> { + /// Loads in the key and cert from files specified in config. + pub fn load(&mut self) -> anyhow::Result { let k = fs::read_to_string(&self.key_file)?; let c = fs::read_to_string(&self.cert_file)?; - self.cert = Some(c); - self.key = Some(k); - Ok(()) + Ok(KeyPair::new(c, k)) } +} + +#[derive(Debug, Clone)] +pub struct KeyPair { + cert: String, + key: String, +} +impl KeyPair { + pub fn new(c: String, k: String) -> Self { + Self { + cert: c, + key: k, + } + } + /// Produces the certificate as a String for you to call .to_bytes() on. pub fn cert(&self) -> anyhow::Result { - Ok(self.cert.clone().unwrap()) + Ok(self.cert.clone()) } + /// Produces the key as a String for you to call .to_bytes() on. pub fn key(&self) -> anyhow::Result { - Ok(self.key.clone().unwrap()) + Ok(self.key.clone()) } } @@ -174,6 +188,30 @@ impl Configuration { Err(_) => Ok(Self::new()), } } + /// Generates new client configuration file f with default values + pub fn generate_client_conf(f: &str) -> anyhow::Result<()> { + let config = Self { + server: None, + client: Some(Client::new()), + tls: Some(TLS::new()), + interface: Interface::new(), + }; + let mut config_file = fs::File::create(&f)?; + config_file.write(toml::to_string(&config)?.as_bytes())?; + Ok(()) + } + /// Generates new server configuration file f with default values + pub fn generate_server_conf(f: &str) -> anyhow::Result<()> { + let config = Self { + server: Some(Server::new()), + client: None, + tls: Some(TLS::new()), + interface: Interface::new(), + }; + let mut config_file = fs::File::create(&f)?; + config_file.write(toml::to_string(&config)?.as_bytes())?; + Ok(()) + } /// Generates new configuration file f with default values pub fn generate_config(f: &str) -> anyhow::Result<()> { let config = Self::new(); diff --git a/src/lib.rs b/src/lib.rs index 8ee2d49..d51511a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ use encoder::Encoder; mod quic; pub mod config; -use config::Configuration; +use config::{Configuration, KeyPair}; // const STREAM_ID: u64 = 0b000; @@ -70,8 +70,7 @@ macro_rules! handle_timeout { }}; } -pub async fn client_main() -> anyhow::Result<()> { - let c = Arc::new(Configuration::load_config("config.toml")?); +pub async fn client_main(c: Arc, tls: KeyPair) -> anyhow::Result<()> { let tun = Tun::builder() .name("sleepy") .tap(false) @@ -193,7 +192,7 @@ pub async fn client_main() -> anyhow::Result<()> { } } -pub async fn server_main(c: Arc, mut tun: Tun) -> anyhow::Result<()> { +pub async fn server_main(c: Arc, mut tun: Tun, tls: KeyPair) -> anyhow::Result<()> { let mut tun = Encoder::new(tun); let (mut to_tun, mut from_quic) = tokio::sync::mpsc::unbounded_channel::>(); let (mut to_quic, mut from_tun) = tokio::sync::mpsc::channel::>(8);