From 9779009fae234cccc5d39ea72cdba95b3cf48e3f Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 9 Nov 2020 17:15:11 -0700 Subject: [PATCH] Add info_msgs to AlertMessage and populate it. This lets us log eventlog info along with the alert if it is available. --- doc/sudo_logsrv.proto.man.in | 19 ++++++++++++++----- doc/sudo_logsrv.proto.mdoc.in | 18 +++++++++++++----- include/log_server.pb-c.h | 9 +++++++-- lib/eventlog/eventlog.c | 10 ++++++---- lib/logsrv/log_server.pb-c.c | 19 ++++++++++++++++--- lib/logsrv/log_server.proto | 5 +++-- logsrvd/iolog_writer.c | 6 ++++-- logsrvd/logsrvd.c | 11 ++++++++++- plugins/sudoers/log_client.c | 15 ++++++++++++++- 9 files changed, 87 insertions(+), 25 deletions(-) diff --git a/doc/sudo_logsrv.proto.man.in b/doc/sudo_logsrv.proto.man.in index 35443b47d..32c67c5f7 100644 --- a/doc/sudo_logsrv.proto.man.in +++ b/doc/sudo_logsrv.proto.man.in @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.TH "SUDO_LOGSRV.PROTO" "@mansectform@" "May 4, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.TH "SUDO_LOGSRV.PROTO" "@mansectform@" "November 6, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .nh .if n .ad l .SH "NAME" @@ -174,7 +174,6 @@ describing the user who submitted the command as well as the execution environment of the command. This information is used to generate an event log entry and may also be used by server to determine where and how the I/O log is stored. -as choose the .TP 8n expect_iobufs Set to true if the server should expect @@ -326,6 +325,7 @@ or message AlertMessage { TimeSpec alert_time = 1; string reason = 2; + repeated InfoMessage info_msgs = 3; } .RE .fi @@ -341,6 +341,13 @@ The wall clock time when the alert occurred. .TP 8n reason The reason for the alert. +.TP 8n +info_msgs +An optional array of +\fIInfoMessage\fR +describing the user who submitted the command as well as the execution +environment of the command. +This information is used to generate an event log entry. .SS "IoBuffer ttyin_buf | ttyout_buf | stdin_buf | stdout_buf | stderr_buf" .nf .RS 0n @@ -599,7 +606,8 @@ If an \fIabort\fR message is received, the client should terminate the running command. .SH "EVENT LOG VARIABLES" -\fIAcceptMessage\fR +\fIAcceptMessage\fR, +\fIAlertMessage\fR and \fIRejectMessage\fR classes contain an array of @@ -798,8 +806,9 @@ message ExitMessage { /* Alert message, policy module-specific. */ message AlertMessage { - TimeSpec alert_time = 1; /* time alert message occurred */ - string reason = 2; /* description of policy violation */ + TimeSpec alert_time = 1; /* time alert message occurred */ + string reason = 2; /* policy alert error string */ + repeated InfoMessage info_msgs = 3; /* key,value event log data */ } /* Used to restart an existing I/O log on the server. */ diff --git a/doc/sudo_logsrv.proto.mdoc.in b/doc/sudo_logsrv.proto.mdoc.in index ab97beacb..ef9953a71 100644 --- a/doc/sudo_logsrv.proto.mdoc.in +++ b/doc/sudo_logsrv.proto.mdoc.in @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd May 4, 2020 +.Dd November 6, 2020 .Dt SUDO_LOGSRV.PROTO @mansectform@ .Os Sudo @PACKAGE_VERSION@ .Sh NAME @@ -162,7 +162,6 @@ describing the user who submitted the command as well as the execution environment of the command. This information is used to generate an event log entry and may also be used by server to determine where and how the I/O log is stored. -as choose the .It expect_iobufs Set to true if the server should expect .Em IoBuffer @@ -303,6 +302,7 @@ or message AlertMessage { TimeSpec alert_time = 1; string reason = 2; + repeated InfoMessage info_msgs = 3; } .Ed .Pp @@ -316,6 +316,12 @@ It contains the following members: The wall clock time when the alert occurred. .It reason The reason for the alert. +.It info_msgs +An optional array of +.Em InfoMessage +describing the user who submitted the command as well as the execution +environment of the command. +This information is used to generate an event log entry. .El .Ss IoBuffer ttyin_buf | ttyout_buf | stdin_buf | stdout_buf | stderr_buf .Bd -literal @@ -552,7 +558,8 @@ If an .Em abort message is received, the client should terminate the running command. .Sh EVENT LOG VARIABLES -.Em AcceptMessage +.Em AcceptMessage , +.Em AlertMessage and .Em RejectMessage classes contain an array of @@ -718,8 +725,9 @@ message ExitMessage { /* Alert message, policy module-specific. */ message AlertMessage { - TimeSpec alert_time = 1; /* time alert message occurred */ - string reason = 2; /* description of policy violation */ + TimeSpec alert_time = 1; /* time alert message occurred */ + string reason = 2; /* policy alert error string */ + repeated InfoMessage info_msgs = 3; /* key,value event log data */ } /* Used to restart an existing I/O log on the server. */ diff --git a/include/log_server.pb-c.h b/include/log_server.pb-c.h index f18e0e3ae..3463b2f26 100644 --- a/include/log_server.pb-c.h +++ b/include/log_server.pb-c.h @@ -270,13 +270,18 @@ struct _AlertMessage */ TimeSpec *alert_time; /* - * description of policy violation + * policy alert error string */ char *reason; + /* + * optional key,value event log data + */ + size_t n_info_msgs; + InfoMessage **info_msgs; }; #define ALERT_MESSAGE__INIT \ { PROTOBUF_C_MESSAGE_INIT (&alert_message__descriptor) \ - , NULL, (char *)protobuf_c_empty_string } + , NULL, (char *)protobuf_c_empty_string, 0,NULL } /* diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c index f7c24050d..8b190b7ce 100644 --- a/lib/eventlog/eventlog.c +++ b/lib/eventlog/eventlog.c @@ -1026,11 +1026,13 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr, } static bool -do_logfile_sudo(const char *logline, const struct eventlog *evlog) +do_logfile_sudo(const char *logline, const struct eventlog *evlog, + const struct timespec *event_time) { + char *full_line, timebuf[8192], *timestr = NULL; const char *timefmt = evl_conf.time_fmt; const char *logfile = evl_conf.logpath; - char *full_line, timebuf[8192], *timestr = NULL; + time_t tv_sec = event_time->tv_sec; struct tm *timeptr; bool ret = false; FILE *fp; @@ -1046,7 +1048,7 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog) goto done; } - if ((timeptr = localtime(&evlog->submit_time.tv_sec)) != NULL) { + if ((timeptr = localtime(&tv_sec)) != NULL) { /* strftime() does not guarantee to NUL-terminate so we must check. */ timebuf[sizeof(timebuf) - 1] = '\0'; if (strftime(timebuf, sizeof(timebuf), timefmt, timeptr) != 0 && @@ -1161,7 +1163,7 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr, switch (evl_conf.format) { case EVLOG_SUDO: - ret = do_logfile_sudo(logline ? logline : reason, evlog); + ret = do_logfile_sudo(logline ? logline : reason, evlog, event_time); break; case EVLOG_JSON: ret = do_logfile_json(event_type, reason, errstr, evlog, diff --git a/lib/logsrv/log_server.pb-c.c b/lib/logsrv/log_server.pb-c.c index 6d5bbd1c8..51f4ef0bf 100644 --- a/lib/logsrv/log_server.pb-c.c +++ b/lib/logsrv/log_server.pb-c.c @@ -1329,7 +1329,7 @@ const ProtobufCMessageDescriptor exit_message__descriptor = (ProtobufCMessageInit) exit_message__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor alert_message__field_descriptors[2] = +static const ProtobufCFieldDescriptor alert_message__field_descriptors[3] = { { "alert_time", @@ -1355,15 +1355,28 @@ static const ProtobufCFieldDescriptor alert_message__field_descriptors[2] = 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "info_msgs", + 3, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(AlertMessage, n_info_msgs), + offsetof(AlertMessage, info_msgs), + &info_message__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned alert_message__field_indices_by_name[] = { 0, /* field[0] = alert_time */ + 2, /* field[2] = info_msgs */ 1, /* field[1] = reason */ }; static const ProtobufCIntRange alert_message__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 2 } + { 0, 3 } }; const ProtobufCMessageDescriptor alert_message__descriptor = { @@ -1373,7 +1386,7 @@ const ProtobufCMessageDescriptor alert_message__descriptor = "AlertMessage", "", sizeof(AlertMessage), - 2, + 3, alert_message__field_descriptors, alert_message__field_indices_by_name, 1, alert_message__number_ranges, diff --git a/lib/logsrv/log_server.proto b/lib/logsrv/log_server.proto index 012fcc332..9c7973784 100644 --- a/lib/logsrv/log_server.proto +++ b/lib/logsrv/log_server.proto @@ -84,8 +84,9 @@ message ExitMessage { /* Alert message, policy module-specific. */ message AlertMessage { - TimeSpec alert_time = 1; /* time alert message occurred */ - string reason = 2; /* description of policy violation */ + TimeSpec alert_time = 1; /* time alert message occurred */ + string reason = 2; /* policy alert error string */ + repeated InfoMessage info_msgs = 3; /* optional key,value event log data */ } /* Used to restart an existing I/O log on the server. */ diff --git a/logsrvd/iolog_writer.c b/logsrvd/iolog_writer.c index c69f58117..6f620b4ca 100644 --- a/logsrvd/iolog_writer.c +++ b/logsrvd/iolog_writer.c @@ -125,8 +125,10 @@ evlog_new(TimeSpec *submit_time, InfoMessage **info_msgs, size_t infolen) memset(evlog, 0, sizeof(*evlog)); /* Submit time. */ - evlog->submit_time.tv_sec = submit_time->tv_sec; - evlog->submit_time.tv_nsec = submit_time->tv_nsec; + if (submit_time != NULL) { + evlog->submit_time.tv_sec = submit_time->tv_sec; + evlog->submit_time.tv_nsec = submit_time->tv_nsec; + } /* Default values */ evlog->lines = 24; diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c index 6b79841d9..145bd6e47 100644 --- a/logsrvd/logsrvd.c +++ b/logsrvd/logsrvd.c @@ -300,7 +300,8 @@ handle_accept(AcceptMessage *msg, struct connection_closure *closure) } sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received AcceptMessage", __func__); - closure->evlog = evlog_new(msg->submit_time, msg->info_msgs, msg->n_info_msgs); + closure->evlog = evlog_new(msg->submit_time, msg->info_msgs, + msg->n_info_msgs); if (closure->evlog == NULL) { closure->errstr = _("error parsing AcceptMessage"); debug_return_bool(false); @@ -486,6 +487,14 @@ handle_alert(AlertMessage *msg, struct connection_closure *closure) } sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received AlertMessage", __func__); + if (msg->info_msgs != NULL && msg->n_info_msgs != 0) { + closure->evlog = evlog_new(NULL, msg->info_msgs, msg->n_info_msgs); + if (closure->evlog == NULL) { + closure->errstr = _("error parsing AlertMessage"); + debug_return_bool(false); + } + } + alert_time.tv_sec = msg->alert_time->tv_sec; alert_time.tv_nsec = msg->alert_time->tv_nsec; if (!eventlog_alert(closure->evlog, 0, &alert_time, msg->reason, NULL)) { diff --git a/plugins/sudoers/log_client.c b/plugins/sudoers/log_client.c index 8752fd544..73acd281d 100644 --- a/plugins/sudoers/log_client.c +++ b/plugins/sudoers/log_client.c @@ -1040,6 +1040,7 @@ fmt_alert_message(struct client_closure *closure) AlertMessage alert_msg = ALERT_MESSAGE__INIT; TimeSpec ts = TIME_SPEC__INIT; struct timespec now; + bool ret = false; debug_decl(fmt_alert_message, SUDOERS_DEBUG_UTIL); /* @@ -1056,11 +1057,23 @@ fmt_alert_message(struct client_closure *closure) /* Reason for the alert. */ alert_msg.reason = (char *)closure->reason; + alert_msg.info_msgs = fmt_info_messages(closure, &alert_msg.n_info_msgs); + if (alert_msg.info_msgs == NULL) + goto done; + + sudo_debug_printf(SUDO_DEBUG_INFO, + "%s: sending AlertMessage, array length %zu", __func__, + alert_msg.n_info_msgs); + /* Schedule ClientMessage */ client_msg.u.alert_msg = &alert_msg; client_msg.type_case = CLIENT_MESSAGE__TYPE_ALERT_MSG; + ret = fmt_client_message(closure, &client_msg); - debug_return_bool(fmt_client_message(closure, &client_msg)); +done: + free_info_messages(alert_msg.info_msgs, alert_msg.n_info_msgs); + + debug_return_bool(ret); } #ifdef notyet