Sni works.

This commit is contained in:
int 80h
2020-04-20 13:07:41 -04:00
parent f85c33f042
commit ef003c3eee
3 changed files with 34 additions and 16 deletions

View File

@@ -1,6 +1,7 @@
extern crate serde_derive; extern crate serde_derive;
extern crate toml; extern crate toml;
use toml::de::Error; use toml::de::Error;
use std::collections::HashMap;
// use serde_derive::Deserialize; // use serde_derive::Deserialize;
@@ -25,5 +26,13 @@ impl Config {
let config: Config = toml::from_str(&fd).unwrap(); let config: Config = toml::from_str(&fd).unwrap();
return config; return config;
} }
pub fn to_map( &self /*cfg: &config::Config*/) -> HashMap<String, String> {
let mut map = HashMap::new();
for srv in &self.server {
map.insert(srv.url.clone(), srv.dir.clone());
}
map
}
} }

View File

@@ -6,6 +6,7 @@ use std::fs::File;
use std::sync::Arc; use std::sync::Arc;
use std::net::ToSocketAddrs; use std::net::ToSocketAddrs;
use std::io::{ self, BufReader }; use std::io::{ self, BufReader };
use std::collections::HashMap;
use futures_util::future::TryFutureExt; use futures_util::future::TryFutureExt;
use tokio::prelude::*; use tokio::prelude::*;
use tokio::runtime; use tokio::runtime;
@@ -23,6 +24,15 @@ use std::error::Error;
mod config; mod config;
mod tls; mod tls;
fn get_tls_config(cfg: config::Config) -> rustls::ServerConfig {
let store = rustls::RootCertStore::empty();
let verifier = rustls::AllowAnyAnonymousOrAuthenticatedClient::new(store);
let mut tls_config = rustls::ServerConfig::new( verifier /*NoClientAuth::new()*/);
tls_config.cert_resolver = Arc::new(tls::CertResolver::from_config(cfg).unwrap());
tls_config
}
fn get_content(request: String) -> String { fn get_content(request: String) -> String {
let url = Url::parse(&request).unwrap(); let url = Url::parse(&request).unwrap();
@@ -43,7 +53,14 @@ async fn handle_connection(mut stream: TlsStream<TcpStream>) -> Result<(), Box<d
stream.read(&mut buffer).await?; stream.read(&mut buffer).await?;
let request = String::from_utf8_lossy(&buffer[..]).to_owned(); let request = String::from_utf8_lossy(&buffer[..]).to_owned();
println!("Request: {}", request); println!("Request: {}", request);
/*
let url = Url::parse(&request).unwrap();
for name in cfg.server {
if url.host_str() == Some(&name.url) {
println!("serving url: {:?}", url.host_str());
}
}
*/
stream.write_all(&b"20\ttext/gemini\r\n"[..]).await?; stream.write_all(&b"20\ttext/gemini\r\n"[..]).await?;
stream.flush().await?; stream.flush().await?;
@@ -57,26 +74,21 @@ async fn handle_connection(mut stream: TlsStream<TcpStream>) -> Result<(), Box<d
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
let cfg = config::Config::new("config.toml"); let cfg = config::Config::new("config.toml");
let srv_map = cfg.to_map();
let addr = format!("{}:{}", cfg.host, cfg.port); let addr = format!("{}:{}", cfg.host, cfg.port);
addr.to_socket_addrs()? addr.to_socket_addrs()?
.next() .next()
.ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?; .ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?;
let certs = tls::load_certs(&cfg.server[0].cert)?;
let keys = tls::load_key(&cfg.server[0].key);
let mut runtime = runtime::Builder::new() let mut runtime = runtime::Builder::new()
.threaded_scheduler() .threaded_scheduler()
.enable_io() .enable_io()
.build()?; .build()?;
let handle = runtime.handle().clone(); let handle = runtime.handle().clone();
let mut config = ServerConfig::new(NoClientAuth::new()); let config = get_tls_config(cfg);
config.set_single_cert(certs, keys)
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
let acceptor = TlsAcceptor::from(Arc::new(config));
println!("Serving"); let acceptor = TlsAcceptor::from(Arc::new(config));
let fut = async { let fut = async {
let mut listener = TcpListener::bind(&addr).await?; let mut listener = TcpListener::bind(&addr).await?;

View File

@@ -54,19 +54,16 @@ impl CertResolver {
certs, signing_key_boxed))); certs, signing_key_boxed)));
} }
println!("Successfully loaded {} HTTPS configurations", map.len()); println!("Successfully loaded {} TLS configurations", map.len());
Ok(CertResolver{ map }) Ok(CertResolver{ map })
} }
} }
impl ResolvesServerCert for CertResolver { impl ResolvesServerCert for CertResolver {
fn resolve( fn resolve( &self, client_hello: ClientHello) -> Option<CertifiedKey> {
&self, if let Some(url) = client_hello.server_name() {
client_hello: ClientHello, if let Some(cert) = self.map.get(url.into()) {
) -> Option<CertifiedKey> {
if let Some(server_name) = client_hello.server_name() {
if let Some(cert) = self.map.get(server_name.into()) {
return Some(*cert.clone()) return Some(*cert.clone())
} }
} }