mirror of https://github.com/breard-r/acmed.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.8 KiB
55 lines
1.8 KiB
use acme_common::crypto::{KeyPair, X509Certificate};
|
|
use acme_common::error::Error;
|
|
use log::debug;
|
|
use openssl::ssl::{self, AlpnError, SslAcceptor, SslMethod};
|
|
use std::net::TcpListener;
|
|
use std::sync::Arc;
|
|
use std::thread;
|
|
|
|
#[cfg(target_family = "unix")]
|
|
use std::os::unix::net::UnixListener;
|
|
|
|
#[cfg(ossl110)]
|
|
const ALPN_ERROR: AlpnError = AlpnError::ALERT_FATAL;
|
|
#[cfg(not(ossl110))]
|
|
const ALPN_ERROR: AlpnError = AlpnError::NOACK;
|
|
|
|
macro_rules! listen_and_accept {
|
|
($lt: ident, $addr: ident, $acceptor: ident) => {
|
|
let listener = $lt::bind($addr)?;
|
|
for stream in listener.incoming() {
|
|
if let Ok(stream) = stream {
|
|
let acceptor = $acceptor.clone();
|
|
thread::spawn(move || {
|
|
debug!("New client");
|
|
let _ = acceptor.accept(stream).unwrap();
|
|
});
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
pub fn start(
|
|
listen_addr: &str,
|
|
certificate: &X509Certificate,
|
|
key_pair: &KeyPair,
|
|
) -> Result<(), Error> {
|
|
let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
|
|
acceptor.set_alpn_select_callback(|_, client| {
|
|
debug!("ALPN negociation");
|
|
ssl::select_next_proto(crate::ALPN_ACME_PROTO_NAME, client).ok_or(ALPN_ERROR)
|
|
});
|
|
acceptor.set_private_key(&key_pair.inner_key)?;
|
|
acceptor.set_certificate(&certificate.inner_cert)?;
|
|
acceptor.check_private_key()?;
|
|
let acceptor = Arc::new(acceptor.build());
|
|
if cfg!(unix) && listen_addr.starts_with("unix:") {
|
|
let listen_addr = &listen_addr[5..];
|
|
debug!("Listening on unix socket {}", listen_addr);
|
|
listen_and_accept!(UnixListener, listen_addr, acceptor);
|
|
} else {
|
|
debug!("Listening on {}", listen_addr);
|
|
listen_and_accept!(TcpListener, listen_addr, acceptor);
|
|
}
|
|
Err("Main thread loop unexpectedly exited".into())
|
|
}
|