diff options
| -rw-r--r-- | examples/windmark.rs | 23 | ||||
| -rw-r--r-- | src/returnable.rs | 31 | ||||
| -rw-r--r-- | src/router.rs | 48 |
3 files changed, 75 insertions, 27 deletions
diff --git a/examples/windmark.rs b/examples/windmark.rs index 0c5b13b..eaf7b43 100644 --- a/examples/windmark.rs +++ b/examples/windmark.rs @@ -199,9 +199,26 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { ) }) }); - // router.mount("", Box::new(|_| { - // Response::Success("hi".into()) - // })); + router.mount( + "/secret", + Box::new(|context| { + if let Some(certificate) = context.certificate { + Response::Success(format!("Your public key: {}.", { + (|| -> Result<String, openssl::error::ErrorStack> { + Ok(format!( + "{:?}", + certificate.public_key()?.rsa()?.public_key_to_pem()? + )) + })() + .unwrap_or_else(|_| "Unknown".to_string()) + },)) + } else { + Response::ClientCertificateRequired( + "This is a secret route! Identify yourself!".to_string(), + ) + } + }), + ); router.run().await } diff --git a/src/returnable.rs b/src/returnable.rs index 31d7e4f..ef34c77 100644 --- a/src/returnable.rs +++ b/src/returnable.rs @@ -17,56 +17,69 @@ // SPDX-License-Identifier: GPL-3.0-only use matchit::Params; +use openssl::x509::X509; use tokio::net::TcpStream; use url::Url; pub struct RouteContext<'a> { - pub tcp: &'a TcpStream, - pub url: &'a Url, - pub params: &'a Params<'a, 'a>, + pub tcp: &'a TcpStream, + pub url: &'a Url, + pub params: &'a Params<'a, 'a>, + pub certificate: &'a Option<X509>, } impl<'a> RouteContext<'a> { pub const fn new( tcp: &'a TcpStream, url: &'a Url, params: &'a Params<'a, 'a>, + certificate: &'a Option<X509>, ) -> Self { Self { tcp, url, params, + certificate, } } } pub struct ErrorContext<'a> { - pub tcp: &'a TcpStream, - pub url: &'a Url, + pub tcp: &'a TcpStream, + pub url: &'a Url, + pub certificate: &'a Option<X509>, } impl<'a> ErrorContext<'a> { - pub const fn new(tcp: &'a TcpStream, url: &'a Url) -> Self { + pub const fn new( + tcp: &'a TcpStream, + url: &'a Url, + certificate: &'a Option<X509>, + ) -> Self { Self { tcp, url, + certificate, } } } pub struct CallbackContext<'a> { - pub tcp: &'a TcpStream, - pub url: &'a Url, - pub params: Option<&'a Params<'a, 'a>>, + pub tcp: &'a TcpStream, + pub url: &'a Url, + pub params: Option<&'a Params<'a, 'a>>, + pub certificate: &'a Option<X509>, } impl<'a> CallbackContext<'a> { pub const fn new( tcp: &'a TcpStream, url: &'a Url, params: Option<&'a Params<'a, 'a>>, + certificate: &'a Option<X509>, ) -> Self { Self { tcp, url, params, + certificate, } } } diff --git a/src/router.rs b/src/router.rs index c7abcc2..5463884 100644 --- a/src/router.rs +++ b/src/router.rs @@ -299,13 +299,18 @@ impl Router { let route = &mut self.routes.at(&fixed_path); for module in &mut *self.modules.lock().unwrap() { - module.on_pre_route(CallbackContext::new(stream.get_ref(), &url, { - if let Ok(route) = &route { - Some(&route.params) - } else { - None - } - })); + module.on_pre_route(CallbackContext::new( + stream.get_ref(), + &url, + { + if let Ok(route) = &route { + Some(&route.params) + } else { + None + } + }, + &stream.ssl().peer_certificate(), + )); } (*self.pre_route_callback).lock().unwrap().call_mut(( @@ -330,6 +335,7 @@ impl Router { stream.get_ref(), &url, &route.params, + &stream.ssl().peer_certificate() )), )); } @@ -342,6 +348,7 @@ impl Router { stream.get_ref(), &url, &route.params, + &stream.ssl().peer_certificate() )), if footers_length > 1 && i != footers_length - 1 { "\n" @@ -355,6 +362,7 @@ impl Router { stream.get_ref(), &url, &route.params, + &stream.ssl().peer_certificate(), ),)), &mut response_status, #[cfg(not(feature = "auto-deduce-mime"))] @@ -365,7 +373,11 @@ impl Router { (*self.error_handler) .lock() .unwrap() - .call_mut((ErrorContext::new(stream.get_ref(), &url),)), + .call_mut((ErrorContext::new( + stream.get_ref(), + &url, + &stream.ssl().peer_certificate(), + ),)), &mut response_status, #[cfg(not(feature = "auto-deduce-mime"))] &mut response_mime_type, @@ -404,13 +416,18 @@ impl Router { .await?; for module in &mut *self.modules.lock().unwrap() { - module.on_post_route(CallbackContext::new(stream.get_ref(), &url, { - if let Ok(route) = &route { - Some(&route.params) - } else { - None - } - })); + module.on_post_route(CallbackContext::new( + stream.get_ref(), + &url, + { + if let Ok(route) = &route { + Some(&route.params) + } else { + None + } + }, + &stream.ssl().peer_certificate(), + )); } (*self.post_route_callback).lock().unwrap().call_mut(( @@ -439,6 +456,7 @@ impl Router { )?; builder.set_certificate_file(&self.ca_file_name, ssl::SslFiletype::PEM)?; builder.check_private_key()?; + builder.set_verify_callback(ssl::SslVerifyMode::PEER, |_, _| true); self.ssl_acceptor = Arc::new(builder.build()); |