diff --git a/examples/sudo_logsrvd.conf b/examples/sudo_logsrvd.conf index 30c9fdecb..55ae7238c 100644 --- a/examples/sudo_logsrvd.conf +++ b/examples/sudo_logsrvd.conf @@ -16,7 +16,11 @@ # Multiple listen_address settings may be specified. # The default is to listen on all addresses. #listen_address = *:30344 -# + +# Sets timeout for the socket. If this parameter is not set, +# the value will be 0 (no timeout) +#timeout = 30 + # Sets audit server's communication over TLS on/off. # Minimum negotiable TLS version is 1.2 #tls = true diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c index fc7242981..0578fb9d9 100644 --- a/logsrvd/logsrvd.c +++ b/logsrvd/logsrvd.c @@ -1226,6 +1226,7 @@ static int create_listener(struct listen_address *addr) { int flags, i, sock; + struct timeval timeout; debug_decl(create_listener, SUDO_DEBUG_UTIL) if ((sock = socket(addr->sa_un.sa.sa_family, SOCK_STREAM, 0)) == -1) { @@ -1235,6 +1236,12 @@ create_listener(struct listen_address *addr) i = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) == -1) sudo_warn("SO_REUSEADDR"); + timeout.tv_sec = logsrvd_conf_get_sock_timeout(); + timeout.tv_usec = 0; + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1) + sudo_warn("SO_RCVTIMEO"); + if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) == -1) + sudo_warn("SO_SNDTIMEO"); if (bind(sock, &addr->sa_un.sa, addr->sa_len) == -1) { sudo_warn("bind"); goto bad; diff --git a/logsrvd/logsrvd.h b/logsrvd/logsrvd.h index e21dc0764..5945bde21 100644 --- a/logsrvd/logsrvd.h +++ b/logsrvd/logsrvd.h @@ -32,6 +32,9 @@ /* Default listen address (port 30344 on all interfaces). */ #define DEFAULT_LISTEN_ADDR "*:" DEFAULT_PORT_STR +/* Default timeout value for server socket */ +#define DEFAULT_SOCKET_TIMEOUT_SEC 30 + /* How often to send an ACK to the client (commit point) in seconds */ #define ACK_FREQUENCY 10 @@ -164,6 +167,7 @@ bool logsrvd_conf_read(const char *path); const char *logsrvd_conf_iolog_dir(void); const char *logsrvd_conf_iolog_file(void); struct listen_address_list *logsrvd_conf_listen_address(void); +int logsrvd_conf_get_sock_timeout(void); #if defined(HAVE_OPENSSL) bool logsrvd_conf_get_tls_opt(void); const struct logsrvd_tls_config *logsrvd_get_tls_config(void); diff --git a/logsrvd/logsrvd_conf.c b/logsrvd/logsrvd_conf.c index 097c1697c..1fd60d3ef 100644 --- a/logsrvd/logsrvd_conf.c +++ b/logsrvd/logsrvd_conf.c @@ -68,6 +68,7 @@ struct logsrvd_config_section { static struct logsrvd_config { struct logsrvd_config_server { struct listen_address_list addresses; + int timeout; #if defined(HAVE_OPENSSL) bool tls; struct logsrvd_tls_config tls_config; @@ -128,6 +129,12 @@ logsrvd_conf_listen_address(void) return &logsrvd_config->server.addresses; } +int +logsrvd_conf_get_sock_timeout(void) +{ + return logsrvd_config->server.timeout; +} + #if defined(HAVE_OPENSSL) bool logsrvd_conf_get_tls_opt(void) @@ -397,6 +404,22 @@ cb_tls_opt(struct logsrvd_config *config, const char *str) debug_return_bool(true); } +static bool +cb_timeout(struct logsrvd_config *config, const char *str) +{ + int timeout; + const char* errstr; + debug_decl(cb_timeout, SUDO_DEBUG_UTIL) + + timeout = sudo_strtonum(str, 0, UINT_MAX, &errstr); + if (errstr != NULL) + debug_return_bool(false); + + config->server.timeout = timeout; + + debug_return_bool(true); +} + static bool cb_tls_key(struct logsrvd_config *config, const char *path) { @@ -644,6 +667,7 @@ cb_logfile_time_format(struct logsrvd_config *config, const char *str) static struct logsrvd_config_entry server_conf_entries[] = { { "listen_address", cb_listen_address }, + { "timeout", cb_timeout }, #if defined(HAVE_OPENSSL) { "tls", cb_tls_opt }, { "tls_key", cb_tls_key }, @@ -823,6 +847,7 @@ logsrvd_conf_alloc(void) /* Server defaults */ TAILQ_INIT(&config->server.addresses); + config->server.timeout = DEFAULT_SOCKET_TIMEOUT_SEC; /* I/O log defaults */ config->iolog.compress = false;