From 86894697225814dc35023e607f2671e8ae25781b Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 3 Sep 2019 01:10:35 +0200 Subject: [PATCH] up --- Cargo.toml | 2 +- src/crypto.rs | 19 ++++++++++++++++ src/dnscrypt_certs.rs | 4 ++-- src/globals.rs | 17 +++------------ src/main.rs | 50 ++++++++++++++++++++++++++++++++++++------- 5 files changed, 67 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d63b589..ffb19a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rust-dnscrypt-server" +name = "dnscrypt-server" version = "0.1.0" authors = ["Frank Denis "] edition = "2018" diff --git a/src/crypto.rs b/src/crypto.rs index 175b04f..b21dbe7 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -1,6 +1,7 @@ use crate::errors::*; use libsodium_sys::*; +use std::ffi::CStr; use std::ptr; #[derive(Derivative)] @@ -63,6 +64,10 @@ impl SignPK { pub fn from_bytes(bytes: [u8; crypto_sign_PUBLICKEYBYTES as usize]) -> Self { SignPK(bytes) } + + pub fn as_string(&self) -> String { + bin2hex(self.as_bytes()) + } } #[derive(Derivative)] @@ -81,6 +86,20 @@ impl SignKeyPair { } } +pub fn bin2hex(bin: &[u8]) -> String { + let bin_len = bin.len(); + let hex_len = bin_len * 2 + 1; + let mut hex = vec![0u8; hex_len]; + unsafe { + sodium_bin2hex(hex.as_mut_ptr() as *mut i8, hex_len, bin.as_ptr(), bin_len); + } + CStr::from_bytes_with_nul(&hex) + .unwrap() + .to_str() + .unwrap() + .to_string() +} + pub fn init() -> Result<(), Error> { let res = unsafe { sodium_init() }; ensure!(res >= 0, "Unable to initialize libsodium"); diff --git a/src/dnscrypt_certs.rs b/src/dnscrypt_certs.rs index 74342fa..5ed6ec5 100644 --- a/src/dnscrypt_certs.rs +++ b/src/dnscrypt_certs.rs @@ -17,7 +17,7 @@ fn now() -> u32 { pub struct DNSCryptCertInner { resolver_pk: [u8; 32], client_magic: [u8; 8], - serial: [u8; 8], + serial: [u8; 4], ts_start: [u8; 4], ts_end: [u8; 4], } @@ -54,7 +54,7 @@ impl DNSCryptCert { dnscrypt_cert_inner .client_magic .copy_from_slice(&dnscrypt_cert_inner.resolver_pk[..8]); - BigEndian::write_u64(&mut dnscrypt_cert_inner.serial, 1); + BigEndian::write_u32(&mut dnscrypt_cert_inner.serial, 1); BigEndian::write_u32(&mut dnscrypt_cert_inner.ts_start, ts_start); BigEndian::write_u32(&mut dnscrypt_cert_inner.ts_end, ts_end); diff --git a/src/globals.rs b/src/globals.rs index 64b8914..de06219 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -1,6 +1,7 @@ use crate::crypto::*; use crate::dnscrypt_certs::*; +use std::net::SocketAddr; use std::sync::Arc; use tokio::runtime::Runtime; @@ -9,18 +10,6 @@ pub struct Globals { pub runtime: Arc, pub resolver_kp: SignKeyPair, pub dnscrypt_certs: Vec, -} - -impl Globals { - pub fn new( - runtime: Arc, - resolver_kp: SignKeyPair, - dnscrypt_certs: Vec, - ) -> Self { - Globals { - runtime, - resolver_kp, - dnscrypt_certs, - } - } + pub provider_name: String, + pub listen_addr: SocketAddr, } diff --git a/src/main.rs b/src/main.rs index 15a4a4c..42ca4e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,8 @@ extern crate clap; extern crate derivative; #[macro_use] extern crate failure; +#[macro_use] +extern crate log; mod config; mod crypto; @@ -68,7 +70,7 @@ async fn udp_acceptor(globals: Arc, mut udp_listener: UdpSocket) -> Res dbg!(&packet); let mut packet = &mut packet[..packet_len]; if let Some(synth_packet) = - serve_certificates(&packet, "2.dnscrypt.example.com", &globals.dnscrypt_certs)? + serve_certificates(&packet, &globals.provider_name, &globals.dnscrypt_certs)? { let _ = udp_listener.send_to(&synth_packet, client_addr).await; continue; @@ -79,7 +81,7 @@ async fn udp_acceptor(globals: Arc, mut udp_listener: UdpSocket) -> Res } async fn start(globals: Arc, runtime: Arc) -> Result<(), Error> { - let socket_addr: SocketAddr = "127.0.0.1:5300".parse()?; + let socket_addr: SocketAddr = globals.listen_addr; let tcp_listener = TcpListener::bind(&socket_addr).await?; let udp_listener = UdpSocket::bind(&socket_addr).await?; runtime.spawn(tcp_acceptor(globals.clone(), tcp_listener).map(|_| {})); @@ -91,17 +93,49 @@ fn main() -> Result<(), Error> { env_logger::init(); crypto::init()?; - let _matches = app_from_crate!().get_matches(); - + let matches = app_from_crate!() + .arg( + Arg::with_name("listen-addr") + .value_name("listen-addr") + .takes_value(true) + .default_value("0.0.0.0:4443") + .required(true) + .help("Address and port to listen to"), + ) + .arg( + Arg::with_name("provider-name") + .value_name("provider-name") + .takes_value(true) + .default_value("2.dnscrypt.test") + .required(true) + .help("Provider name"), + ) + .get_matches(); + let listen_addr = matches + .value_of("listen-addr") + .unwrap() + .to_ascii_lowercase(); + let provider_name = match matches.value_of("provider-name").unwrap() { + provider_name if provider_name.starts_with("2.dnscrypt.") => provider_name.to_string(), + provider_name => format!("2.dnscrypt.{}", provider_name), + }; + let listen_addr: SocketAddr = matches.value_of("listen-addr").unwrap().parse()?; let resolver_kp = SignKeyPair::new(); + + println!("Server address: {}", listen_addr); + println!("Provider public key: {}", resolver_kp.pk.as_string()); + println!("Provider name: {}", provider_name); + let dnscrypt_cert = DNSCryptCert::new(&resolver_kp); let runtime = Arc::new(Runtime::new()?); - let globals = Arc::new(Globals::new( - runtime.clone(), + let globals = Arc::new(Globals { + runtime: runtime.clone(), resolver_kp, - vec![dnscrypt_cert], - )); + dnscrypt_certs: vec![dnscrypt_cert], + provider_name, + listen_addr, + }); runtime.spawn(start(globals, runtime.clone()).map(|_| ())); runtime.block_on(future::pending::<()>());