From 73df1bb951af61fca9105093824e0272c61e949c Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Thu, 9 May 2019 12:17:51 +0200 Subject: [PATCH] Allow tacd to listen on a unix socket --- CHANGELOG.md | 1 + man/en/tacd.8 | 24 ++++++++++++------------ tacd/src/main.rs | 2 +- tacd/src/server.rs | 34 +++++++++++++++++++++++++--------- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19443fe..f2b3a7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - ACMEd now displays a warning when the server indicates an error in an order or an authorization. - A configuration file can now include several other files. +- tacd is now able to listen on a unix socket. ## [0.4.0] - 2019-05-08 diff --git a/man/en/tacd.8 b/man/en/tacd.8 index 12a3388..e0b112e 100644 --- a/man/en/tacd.8 +++ b/man/en/tacd.8 @@ -46,29 +46,29 @@ is read first, then the The options are as follows: .Bl -tag .It Fl e, -acme-ext Ar STRING -The acmeIdentifier extension to set in the self-signed certificate +The acmeIdentifier extension to set in the self-signed certificate. .It Fl -acme-ext-file Ar FILE -File from which is read the acmeIdentifier extension to set in the self-signed certificate +File from which is read the acmeIdentifier extension to set in the self-signed certificate. .It Fl d, -domain Ar STRING -The domain that is being validated +The domain that is being validated. .It Fl -domain-file Ar STRING -File from which is read the domain that is being validated +File from which is read the domain that is being validated. .It Fl f, -foregroung -Runs in the foregroung +Runs in the foregroung. .It Fl h, -help -Prints help information -.It Fl i, -listen Ar host:port -Specifies the host and port to listen on +Prints help information. +.It Fl i, -listen Ar host:port | unix:path +Specifies the host and port combination or the unix socket to listen on. .It Fl -log-stderr -Prints log messages to the standard error output +Prints log messages to the standard error output. .It Fl -log-syslog -Sends log messages via syslog +Sends log messages via syslog. .It Fl -log-level Ar LEVEL Specify the log level. Possible values: error, warn, info, debug and trace. .It Fl -pid-file Ar FILE -Specifies the location of the PID file +Specifies the location of the PID file. .It Fl V, -version -Prints version information +Prints version information. .Sh SEE ALSO .Xr acmed.toml 5 .Sh STANDARDS diff --git a/tacd/src/main.rs b/tacd/src/main.rs index 70a7fc5..faa41be 100644 --- a/tacd/src/main.rs +++ b/tacd/src/main.rs @@ -61,7 +61,7 @@ fn main() { .short("l") .help("Specifies the host and port to listen on") .takes_value(true) - .value_name("host:port"), + .value_name("host:port|unix:path"), ) .arg( Arg::with_name("domain") diff --git a/tacd/src/server.rs b/tacd/src/server.rs index b039365..4e613fa 100644 --- a/tacd/src/server.rs +++ b/tacd/src/server.rs @@ -7,11 +7,29 @@ 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: &X509, @@ -26,15 +44,13 @@ pub fn start( acceptor.set_certificate(certificate)?; acceptor.check_private_key()?; let acceptor = Arc::new(acceptor.build()); - let listener = TcpListener::bind(listen_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(); - }); - }; + 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()) }