Add FingerPrintStore trait for fetching a known mailuser via a client

certificate fingerprint;
This commit is contained in:
Nathan Fisher 2023-06-01 19:07:08 -04:00
parent 8b0af76b8f
commit 5ab89f74db
6 changed files with 55 additions and 18 deletions

View file

@ -1,20 +1,23 @@
use super::verifier::Verifier; use super::{Verifier, FingerPrintStore};
use crate::prelude::CertificateStore; use rustls::ServerConfig;
use std::net::TcpStream; use std::{net::TcpStream, sync::Arc};
#[derive(Debug)] #[derive(Debug)]
pub struct Builder<S: CertificateStore> { pub struct Builder<S: FingerPrintStore> {
pub stream: Option<TcpStream>, pub stream: Option<TcpStream>,
pub verifier: Option<Verifier<S>>, pub verifier: Option<Verifier<S>>,
} }
impl<S: CertificateStore> Default for Builder<S> { impl<S: FingerPrintStore> Default for Builder<S> {
fn default() -> Self { fn default() -> Self {
Self { stream: None, verifier: None } Self {
stream: None,
verifier: None,
}
} }
} }
impl<S: CertificateStore> Builder<S> { impl<S: FingerPrintStore + 'static> Builder<S> {
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
} }
@ -29,7 +32,12 @@ impl<S: CertificateStore> Builder<S> {
self self
} }
pub fn build(self) -> super::Connection { pub fn build(self) -> Result<super::Connection, rustls::Error> {
let cfg = ServerConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_safe_default_protocol_versions()?
.with_client_cert_verifier(Arc::new(self.verifier.unwrap()));
todo!() todo!()
} }
} }

View file

@ -1 +1,2 @@
#[derive(Debug)]
pub struct Error;

View file

@ -2,10 +2,11 @@ pub mod builder;
pub mod error; pub mod error;
pub mod verifier; pub mod verifier;
pub use self::{builder::Builder, error::Error, verifier::{FingerPrintStore, Verifier}};
#[derive(Debug)] #[derive(Debug)]
pub struct Connection { pub struct Connection {
pub inner: rustls::ServerConnection, pub inner: rustls::ServerConnection,
} }
impl Connection { impl Connection {}
}

View file

@ -1,7 +1,30 @@
use crate::prelude::CertificateStore; use rustls::server::ClientCertVerifier;
use crate::{prelude::CertificateStore, mailuser::Mailuser};
use std::sync::Mutex; use std::sync::Mutex;
#[derive(Debug)] #[derive(Debug)]
pub struct Verifier<S: CertificateStore> { pub struct Verifier<S: FingerPrintStore> {
pub store: Mutex<S>, pub store: Mutex<S>,
} }
pub trait FingerPrintStore: Send + Sync {
fn get_mailuser(&self, fingerprint: &str) -> Option<Mailuser>;
fn insert_mailuser(&mut self, fingerprint: &str, user: &str) -> Option<Mailuser>;
fn contains_mailuser(&self, fingerprint: &str) -> bool;
}
impl<S: FingerPrintStore> ClientCertVerifier for Verifier<S> {
fn client_auth_root_subjects(&self) -> &[rustls::DistinguishedName] {
todo!()
}
fn verify_client_cert(
&self,
end_entity: &rustls::Certificate,
intermediates: &[rustls::Certificate],
now: std::time::SystemTime,
) -> Result<rustls::server::ClientCertVerified, rustls::Error> {
todo!()
}
}

View file

@ -86,9 +86,7 @@ impl MailStore for Domain {
} }
fn has_mailuser(&self, mailuser: &str) -> bool { fn has_mailuser(&self, mailuser: &str) -> bool {
self.users() self.users().iter().any(|x| x.username == mailuser)
.iter()
.any(|x| x.username == mailuser)
} }
fn get_folder(&self, user: &str, folder: &str) -> Option<Folder> { fn get_folder(&self, user: &str, folder: &str) -> Option<Folder> {

View file

@ -27,9 +27,15 @@ impl FromStr for Link {
return Err(super::Error::MalformedLink); return Err(super::Error::MalformedLink);
}; };
if let Some((url, display)) = s.split_once(char::is_whitespace) { if let Some((url, display)) = s.split_once(char::is_whitespace) {
Ok(Self { url: url.to_string(), display: Some(display.to_string()) }) Ok(Self {
url: url.to_string(),
display: Some(display.to_string()),
})
} else { } else {
Ok(Self { url: s.to_string(), display: None }) Ok(Self {
url: s.to_string(),
display: None,
})
} }
} }
} }