From 839c6bbf812023f866b6b761df3740a530f73f6a Mon Sep 17 00:00:00 2001 From: int 80h Date: Fri, 8 May 2020 16:02:55 -0400 Subject: [PATCH] Revproxy can't connect --- src/config.rs | 13 +++++++++++++ src/main.rs | 11 +++++++++++ src/revproxy.rs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 src/revproxy.rs diff --git a/src/config.rs b/src/config.rs index 346cf59..48f5772 100644 --- a/src/config.rs +++ b/src/config.rs @@ -20,6 +20,7 @@ pub struct Server { pub cert: String, pub cgi: Option, pub usrdir: Option, + pub proxy: Option>, } #[derive(Debug, Clone)] @@ -31,6 +32,7 @@ pub struct ServerCfg { pub cgi: String, pub usrdir: bool, pub port: i32, + pub proxy: HashMap, } impl Config { @@ -50,6 +52,16 @@ impl Config { Some(u) => u, None => false, }; + let mut pmap = HashMap::new(); + match &srv.proxy { + Some(pr) => { + for p in pr { + let p: Vec<&str> = p.split("=").collect(); + pmap.insert(p[0].trim().to_string(), p[1].trim().to_string()); + } + }, + None => {}, + }; map.insert(srv.hostname.clone(), ServerCfg { hostname: srv.hostname.clone(), dir: srv.dir.clone(), @@ -58,6 +70,7 @@ impl Config { cgi: cgi, usrdir: usrdir, port: self.port.clone(), + proxy: pmap, }); } map diff --git a/src/main.rs b/src/main.rs index 5faf846..a0c9680 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,6 +36,7 @@ mod config; mod status; mod tls; mod conn; +mod revproxy; fn get_mime(path: &PathBuf) -> String { let mut mime = "text/gemini"; @@ -124,6 +125,16 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - } }; + if srv.proxy.len() != 0 { + match srv.proxy.get(url.path()) { + Some(p) => { + revproxy::proxy(p.to_string(), url).await?; + return Ok(()); + }, + None => {}, + } + } + if Some(srv.hostname.as_str()) != url.host_str() { con.send_status(status::Status::ProxyRequestRefused, "Url doesn't match certificate!").await?; return Ok(()); diff --git a/src/revproxy.rs b/src/revproxy.rs new file mode 100644 index 0000000..3b65d48 --- /dev/null +++ b/src/revproxy.rs @@ -0,0 +1,37 @@ +use std::io; +use std::fs::File; +use std::sync::Arc; +use std::net::ToSocketAddrs; +use std::io::BufReader; +use futures_util::future; +use tokio::net::TcpStream; +use tokio::io::{ + AsyncWriteExt, + copy, split, +}; +use tokio_rustls::{ TlsConnector, rustls::ClientConfig, webpki::DNSNameRef }; +use url::Url; + +pub async fn proxy(addr: String, _u: url::Url) -> Result<(), io::Error> { + let addr = addr.to_socket_addrs()? + .next() + .ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?; + let mut config = ClientConfig::new(); + + let mut pem = BufReader::new(File::open("cafile")?); + config.root_store.add_pem_file(&mut pem) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))?; + + let connector = TlsConnector::from(Arc::new(config)); + let stream = TcpStream::connect(&addr).await?; + + let domain = DNSNameRef::try_from_ascii_str("cbook.lan") + .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid dnsname"))?; + + println!("Connecting to agena..."); + let mut stream = connector.connect(domain, stream).await?; + //stream.write_all(b"gopher://gopher.club/\r\n").await?; + //stream.flush().await?; + + Ok(()) +}