aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/windmark.rs23
-rw-r--r--src/returnable.rs31
-rw-r--r--src/router.rs48
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());