From: Todd C. Miller <Todd.Miller@courtesan.com> Date: Wed, 12 Jul 2017 11:47:28 +0000 (-0600) Subject: Log window size change events in the sudoers I/O plugin. X-Git-Tag: SUDO_1_8_21^2~42 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f79a236533da8e5a3fdc22b1da205fa4be79e6df;p=sudo Log window size change events in the sudoers I/O plugin. Let sudoreplay parse a timing file with window change events (currently ignored). --- diff --git a/plugins/sudoers/iolog.c b/plugins/sudoers/iolog.c index 18543ff01..52cbe28c8 100644 --- a/plugins/sudoers/iolog.c +++ b/plugins/sudoers/iolog.c @@ -961,8 +961,11 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, goto done; /* Write log file with user and command details. */ - if (gettimeofday(&last_time, NULL) == -1) + if (gettimeofday(&last_time, NULL) == -1) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, + "%s: unable to get time of day", __func__); goto done; + } write_info_log(pathbuf, len, &iolog_details, argv, &last_time); /* Create the timing and I/O log files. */ @@ -1060,7 +1063,7 @@ sudoers_io_log(const char *buf, unsigned int len, int idx) char tbuf[1024]; const char *errstr = NULL; int ret = -1; - debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN) + debug_decl(sudoers_io_log, SUDOERS_DEBUG_PLUGIN) if (io_log_files[idx].fd.v == NULL) { sudo_warnx(U_("%s: internal error, file index %d not open"), @@ -1068,7 +1071,12 @@ sudoers_io_log(const char *buf, unsigned int len, int idx) debug_return_int(-1); } - gettimeofday(&now, NULL); + if (gettimeofday(&now, NULL) == -1) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, + "%s: unable to get time of day", __func__); + errstr = strerror(errno); + goto done; + } /* Write I/O log file entry. */ errstr = iolog_write(buf, len, idx); @@ -1141,6 +1149,57 @@ sudoers_io_log_stderr(const char *buf, unsigned int len) return sudoers_io_log(buf, len, IOFD_STDERR); } +static int +sudoers_io_change_winsize(unsigned int lines, unsigned int cols) +{ + struct timeval now, delay; + unsigned int len; + char tbuf[1024]; + const char *errstr = NULL; + int ret = -1; + debug_decl(sudoers_io_change_winsize, SUDOERS_DEBUG_PLUGIN) + + if (gettimeofday(&now, NULL) == -1) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, + "%s: unable to get time of day", __func__); + errstr = strerror(errno); + goto done; + } + + /* Write window change event to the timing file. */ + sudo_timevalsub(&now, &last_time, &delay); + len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %f %u %u\n", + IOFD_TIMING, delay.tv_sec + ((double)delay.tv_usec / 1000000), + lines, cols); + if (len >= sizeof(tbuf)) { + /* Not actually possible due to the size of tbuf[]. */ + errstr = strerror(EOVERFLOW); + goto done; + } + errstr = iolog_write(tbuf, len, IOFD_TIMING); + if (errstr != NULL) + goto done; + +done: + last_time.tv_sec = now.tv_sec; + last_time.tv_usec = now.tv_usec; + + if (ret == -1) { + if (errstr != NULL && !warned) { + /* Only warn about I/O log file errors once. */ + log_warning(SLOG_SEND_MAIL, + N_("unable to write to I/O log file: %s"), errstr); + warned = true; + } + + /* Ignore errors if they occur if the policy says so. */ + if (iolog_details.ignore_iolog_errors) + ret = 1; + } + + debug_return_int(ret); +} + __dso_public struct io_plugin sudoers_io = { SUDO_IO_PLUGIN, SUDO_API_VERSION, @@ -1151,5 +1210,8 @@ __dso_public struct io_plugin sudoers_io = { sudoers_io_log_ttyout, sudoers_io_log_stdin, sudoers_io_log_stdout, - sudoers_io_log_stderr + sudoers_io_log_stderr, + NULL, /* register_hooks */ + NULL, /* deregister_hooks */ + sudoers_io_change_winsize }; diff --git a/plugins/sudoers/sudoreplay.c b/plugins/sudoers/sudoreplay.c index 5deb17d06..80ada701b 100644 --- a/plugins/sudoers/sudoreplay.c +++ b/plugins/sudoers/sudoreplay.c @@ -453,7 +453,7 @@ replay_session(const double max_wait, const char *decimal) sudo_ev_loop(evbase, 0); /* Even if we are not replaying, we still have to delay. */ - if (idx >= IOFD_MAX || io_log_files[idx].fd.v == NULL) + if (idx >= IOFD_TIMING || io_log_files[idx].fd.v == NULL) continue; /* Check whether we need to convert newline to CR LF pairs. */ @@ -1196,7 +1196,7 @@ parse_timing(const char *buf, const char *decimal, int *idx, double *seconds, ul = strtoul(buf, &ep, 10); if (ep == buf || !isspace((unsigned char) *ep)) goto bad; - if (ul >= IOFD_TIMING) { + if (ul >= IOFD_MAX) { if (ul != 6) goto bad; /* work around a bug in timing files generated by sudo 1.8.7 */ @@ -1232,7 +1232,8 @@ parse_timing(const char *buf, const char *decimal, int *idx, double *seconds, errno = 0; ul = strtoul(cp, &ep, 10); - if (ep == cp || *ep != '\0' || (errno == ERANGE && ul == ULONG_MAX)) + if (ep == cp || (*ep != '\0' && !isspace((unsigned char) *ep)) || + (errno == ERANGE && ul == ULONG_MAX)) goto bad; *nbytes = (size_t)ul;