sudoers: disable SO_KEEPALIVE socket option based on log_server_disable_keepalive flag in sudoers

This commit is contained in:
Laszlo Orban
2020-01-21 15:18:27 +01:00
committed by Todd C. Miller
parent 38160d0ccb
commit 6f3f45aa24
8 changed files with 50 additions and 12 deletions

View File

@@ -513,6 +513,10 @@ struct sudo_defs_types sudo_defs_table[] = {
"log_server_timeout", T_TIMEOUT|T_BOOL,
N_("Sudo log server timeout in seconds: %u"),
NULL,
}, {
"log_server_keepalive", T_FLAG,
N_("Enable SO_KEEPALIVE socket option on the socket connected to the logserver"),
NULL,
}, {
"log_server_cabundle", T_STR|T_BOOL|T_PATH,
N_("Path to the audit server's CA bundle file: %s"),

View File

@@ -236,15 +236,17 @@
#define def_log_servers (sudo_defs_table[I_LOG_SERVERS].sd_un.list)
#define I_LOG_SERVER_TIMEOUT 118
#define def_log_server_timeout (sudo_defs_table[I_LOG_SERVER_TIMEOUT].sd_un.ival)
#define I_LOG_SERVER_CABUNDLE 119
#define I_LOG_SERVER_KEEPALIVE 119
#define def_log_server_keepalive (sudo_defs_table[I_LOG_SERVER_KEEPALIVE].sd_un.flag)
#define I_LOG_SERVER_CABUNDLE 120
#define def_log_server_cabundle (sudo_defs_table[I_LOG_SERVER_CABUNDLE].sd_un.str)
#define I_LOG_SERVER_PEER_CERT 120
#define I_LOG_SERVER_PEER_CERT 121
#define def_log_server_peer_cert (sudo_defs_table[I_LOG_SERVER_PEER_CERT].sd_un.str)
#define I_LOG_SERVER_PEER_KEY 121
#define I_LOG_SERVER_PEER_KEY 122
#define def_log_server_peer_key (sudo_defs_table[I_LOG_SERVER_PEER_KEY].sd_un.str)
#define I_RUNAS_ALLOW_UNKNOWN_ID 122
#define I_RUNAS_ALLOW_UNKNOWN_ID 123
#define def_runas_allow_unknown_id (sudo_defs_table[I_RUNAS_ALLOW_UNKNOWN_ID].sd_un.flag)
#define I_RUNAS_CHECK_SHELL 123
#define I_RUNAS_CHECK_SHELL 124
#define def_runas_check_shell (sudo_defs_table[I_RUNAS_CHECK_SHELL].sd_un.flag)
enum def_tuple {

View File

@@ -372,6 +372,9 @@ log_servers
log_server_timeout
T_TIMEOUT|T_BOOL
"Sudo log server timeout in seconds: %u"
log_server_keepalive
T_FLAG
"Enable SO_KEEPALIVE socket option on the socket connected to the logserver"
log_server_cabundle
T_STR|T_BOOL|T_PATH
"Path to the audit server's CA bundle file: %s"

View File

@@ -564,6 +564,7 @@ init_defaults(void)
def_compress_io = true;
#endif
def_log_server_timeout = 30;
def_log_server_keepalive = true;
def_ignore_audit_errors = true;
def_ignore_iolog_errors = false;
def_ignore_logfile_errors = true;

View File

@@ -366,6 +366,15 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
TIME_T_MAX, NULL);
continue;
}
if (strncmp(*cur, "log_server_keepalive=", sizeof("log_server_keepalive=") - 1) == 0) {
int val = sudo_strtobool(*cur + sizeof("log_server_keepalive=") - 1);
if (val != -1) {
details->tcp_keepalive = val;
} else {
details->tcp_keepalive = true;
}
continue;
}
#if defined(HAVE_OPENSSL)
if (strncmp(*cur, "log_server_cabundle=", sizeof("log_server_cabundle=") - 1) == 0) {
details->ca_bundle = *cur + sizeof("log_server_cabundle=") - 1;
@@ -594,7 +603,7 @@ sudoers_io_open_remote(void)
debug_decl(sudoers_io_open_remote, SUDOERS_DEBUG_PLUGIN);
/* Connect to log server. */
sock = log_server_connect(iolog_details.log_servers,
sock = log_server_connect(iolog_details.log_servers, iolog_details.tcp_keepalive,
&iolog_details.server_timeout, &connected_server);
if (sock == -1) {
/* TODO: support offline logs if server unreachable */

View File

@@ -131,8 +131,8 @@ done:
* Returns open socket or -1 on error.
*/
static int
connect_server(const char *host, const char *port, struct timespec *timo,
const char **reason)
connect_server(const char *host, const char *port, bool tcp_keepalive,
struct timespec *timo, const char **reason)
{
struct addrinfo hints, *res, *res0;
const char *cause = NULL;
@@ -166,6 +166,20 @@ connect_server(const char *host, const char *port, struct timespec *timo,
sock = -1;
continue;
}
if (tcp_keepalive) {
int keepalive = 1;
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepalive,
sizeof(keepalive)) == -1) {
cause = "setsockopt(SO_KEEPALIVE)";
save_errno = errno;
close(sock);
errno = save_errno;
sock = -1;
continue;
}
}
if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timo) == -1) {
cause = "connect";
save_errno = errno;
@@ -189,8 +203,8 @@ connect_server(const char *host, const char *port, struct timespec *timo,
* Returns a socket with O_NONBLOCK and close-on-exec flags set.
*/
int
log_server_connect(struct sudoers_str_list *servers, struct timespec *timo,
struct sudoers_string **connected_server)
log_server_connect(struct sudoers_str_list *servers, bool tcp_keepalive,
struct timespec *timo, struct sudoers_string **connected_server)
{
struct sudoers_string *server;
char *copy, *host, *port;
@@ -204,7 +218,7 @@ log_server_connect(struct sudoers_str_list *servers, struct timespec *timo,
free(copy);
continue;
}
sock = connect_server(host, port, timo, &cause);
sock = connect_server(host, port, tcp_keepalive, timo, &cause);
free(copy);
if (sock != -1) {
int flags = fcntl(sock, F_GETFL, 0);

View File

@@ -61,6 +61,7 @@ struct iolog_details {
char **user_env;
struct sudoers_str_list *log_servers;
struct timespec server_timeout;
bool tcp_keepalive;
#if defined(HAVE_OPENSSL)
char *ca_bundle;
char *cert_file;
@@ -156,7 +157,7 @@ bool fmt_exit_message(struct client_closure *closure, int exit_status, int error
bool fmt_io_buf(struct client_closure *closure, int type, const char *buf, unsigned int len, struct timespec *delay);
bool fmt_suspend(struct client_closure *closure, const char *signame, struct timespec *delay);
bool fmt_winsize(struct client_closure *closure, unsigned int lines, unsigned int cols, struct timespec *delay);
int log_server_connect(struct sudoers_str_list *servers, struct timespec *timo, struct sudoers_string **connected_server);
int log_server_connect(struct sudoers_str_list *servers, bool tcp_keepalive, struct timespec *timo, struct sudoers_string **connected_server);
void client_closure_free(struct client_closure *closure);
#endif /* SUDOERS_IOLOG_CLIENT_H */

View File

@@ -735,6 +735,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
goto oom;
}
if ((command_info[info_len++] = sudo_new_key_val("log_server_keepalive",
def_log_server_keepalive ? "true" : "false")) == NULL)
goto oom;
if (def_log_server_cabundle != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("log_server_cabundle", def_log_server_cabundle)) == NULL)
goto oom;