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.9 KiB

  1. use acme_common::crypto::{PrivateKey, X509Certificate};
  2. use acme_common::error::Error;
  3. use log::debug;
  4. use openssl::ssl::{self, AlpnError, SslAcceptor, SslMethod};
  5. use std::net::TcpListener;
  6. use std::sync::Arc;
  7. use std::thread;
  8. #[cfg(target_family = "unix")]
  9. use std::os::unix::net::UnixListener;
  10. #[cfg(ossl110)]
  11. const ALPN_ERROR: AlpnError = AlpnError::ALERT_FATAL;
  12. #[cfg(not(ossl110))]
  13. const ALPN_ERROR: AlpnError = AlpnError::NOACK;
  14. macro_rules! listen_and_accept {
  15. ($lt: ident, $addr: ident, $acceptor: ident) => {
  16. let listener = $lt::bind($addr)?;
  17. for stream in listener.incoming() {
  18. if let Ok(stream) = stream {
  19. let acceptor = $acceptor.clone();
  20. thread::spawn(move || {
  21. debug!("New client");
  22. let _ = acceptor.accept(stream).unwrap();
  23. });
  24. };
  25. }
  26. };
  27. }
  28. pub fn start(
  29. listen_addr: &str,
  30. certificate: &X509Certificate,
  31. private_key: &PrivateKey,
  32. ) -> Result<(), Error> {
  33. let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
  34. acceptor.set_alpn_select_callback(|_, client| {
  35. debug!("ALPN negociation");
  36. ssl::select_next_proto(crate::ALPN_ACME_PROTO_NAME, client).ok_or(ALPN_ERROR)
  37. });
  38. acceptor.set_private_key(&private_key.inner_key)?;
  39. acceptor.set_certificate(&certificate.inner_cert)?;
  40. acceptor.check_private_key()?;
  41. let acceptor = Arc::new(acceptor.build());
  42. if cfg!(unix) && listen_addr.starts_with("unix:") {
  43. let listen_addr = &listen_addr[5..];
  44. debug!("Listening on unix socket {}", listen_addr);
  45. listen_and_accept!(UnixListener, listen_addr, acceptor);
  46. } else {
  47. debug!("Listening on {}", listen_addr);
  48. listen_and_accept!(TcpListener, listen_addr, acceptor);
  49. }
  50. Err("Main thread loop unexpectedly exited".into())
  51. }