diff --git a/MANIFEST b/MANIFEST index c960e3e8b..7d80d08da 100644 --- a/MANIFEST +++ b/MANIFEST @@ -118,6 +118,7 @@ lib/iolog/hostcheck.c lib/iolog/iolog_fileio.c lib/iolog/iolog_json.c lib/iolog/iolog_json.h +lib/iolog/iolog_legacy.c lib/iolog/iolog_path.c lib/iolog/iolog_util.c lib/iolog/regress/corpus/log_json/id.json diff --git a/lib/iolog/Makefile.in b/lib/iolog/Makefile.in index ac6b24c5c..70eb38699 100644 --- a/lib/iolog/Makefile.in +++ b/lib/iolog/Makefile.in @@ -95,8 +95,8 @@ DEVEL = @DEVEL@ SHELL = @SHELL@ -LIBIOLOG_OBJS = iolog_fileio.lo iolog_json.lo iolog_path.lo iolog_util.lo \ - host_port.lo hostcheck.lo +LIBIOLOG_OBJS = iolog_fileio.lo iolog_json.lo iolog_legacy.lo iolog_path.lo \ + iolog_util.lo host_port.lo hostcheck.lo IOBJS = $(LIBIOLOG_OBJS:.lo=.i) @@ -461,6 +461,22 @@ iolog_json.i: $(srcdir)/iolog_json.c $(incdir)/compat/stdbool.h \ $(CC) -E -o $@ $(CPPFLAGS) $< iolog_json.plog: iolog_json.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_json.c --i-file $< --output-file $@ +iolog_legacy.lo: $(srcdir)/iolog_legacy.c $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ + $(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \ + $(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \ + $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \ + $(incdir)/sudo_util.h $(top_builddir)/config.h + $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog_legacy.c +iolog_legacy.i: $(srcdir)/iolog_legacy.c $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ + $(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \ + $(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \ + $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \ + $(incdir)/sudo_util.h $(top_builddir)/config.h + $(CC) -E -o $@ $(CPPFLAGS) $< +iolog_legacy.plog: iolog_legacy.i + rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_legacy.c --i-file $< --output-file $@ iolog_path.lo: $(srcdir)/iolog_path.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ diff --git a/lib/iolog/iolog_legacy.c b/lib/iolog/iolog_legacy.c new file mode 100644 index 000000000..5d987ae8f --- /dev/null +++ b/lib/iolog/iolog_legacy.c @@ -0,0 +1,168 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2009-2020 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This is an open source non-commercial project. Dear PVS-Studio, please check it. + * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + */ + +#include + +#include +#include +#ifdef HAVE_STDBOOL_H +# include +#else +# include "compat/stdbool.h" +#endif /* HAVE_STDBOOL_H */ +#include +#include +#include +#include + +#include "sudo_compat.h" +#include "sudo_debug.h" +#include "sudo_eventlog.h" +#include "sudo_fatal.h" +#include "sudo_gettext.h" +#include "sudo_iolog.h" +#include "sudo_util.h" + +bool +iolog_parse_loginfo_legacy(FILE *fp, const char *iolog_dir, + struct eventlog *evlog) +{ + char *buf = NULL, *cp, *ep; + const char *errstr; + size_t bufsize = 0, cwdsize = 0, cmdsize = 0; + bool ret = false; + debug_decl(iolog_parse_loginfo_legacy, SUDO_DEBUG_UTIL); + + /* + * Info file has three lines: + * 1) a log info line + * 2) cwd + * 3) command with args + */ + if (getdelim(&buf, &bufsize, '\n', fp) == -1 || + getdelim(&evlog->cwd, &cwdsize, '\n', fp) == -1 || + getdelim(&evlog->command, &cmdsize, '\n', fp) == -1) { + sudo_warn(U_("%s: invalid log file"), iolog_dir); + goto done; + } + + /* Strip the newline from the cwd and command. */ + evlog->cwd[strcspn(evlog->cwd, "\n")] = '\0'; + evlog->command[strcspn(evlog->command, "\n")] = '\0'; + + /* + * Crack the log line (lines and cols not present in old versions). + * timestamp:user:runas_user:runas_group:tty:lines:cols + * XXX - probably better to use strtok and switch on the state. + */ + buf[strcspn(buf, "\n")] = '\0'; + cp = buf; + + /* timestamp */ + if ((ep = strchr(cp, ':')) == NULL) { + sudo_warn(U_("%s: time stamp field is missing"), iolog_dir); + goto done; + } + *ep = '\0'; + evlog->submit_time.tv_sec = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr); + if (errstr != NULL) { + sudo_warn(U_("%s: time stamp %s: %s"), iolog_dir, cp, errstr); + goto done; + } + + /* submit user */ + cp = ep + 1; + if ((ep = strchr(cp, ':')) == NULL) { + sudo_warn(U_("%s: user field is missing"), iolog_dir); + goto done; + } + if ((evlog->submituser = strndup(cp, (size_t)(ep - cp))) == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + goto done; + } + + /* runas user */ + cp = ep + 1; + if ((ep = strchr(cp, ':')) == NULL) { + sudo_warn(U_("%s: runas user field is missing"), iolog_dir); + goto done; + } + if ((evlog->runuser = strndup(cp, (size_t)(ep - cp))) == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + goto done; + } + + /* runas group */ + cp = ep + 1; + if ((ep = strchr(cp, ':')) == NULL) { + sudo_warn(U_("%s: runas group field is missing"), iolog_dir); + goto done; + } + if (cp != ep) { + if ((evlog->rungroup = strndup(cp, (size_t)(ep - cp))) == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + goto done; + } + } + + /* tty, followed by optional lines + cols */ + cp = ep + 1; + if ((ep = strchr(cp, ':')) == NULL) { + /* just the tty */ + if ((evlog->ttyname = strdup(cp)) == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + goto done; + } + } else { + /* tty followed by lines + cols */ + if ((evlog->ttyname = strndup(cp, (size_t)(ep - cp))) == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + goto done; + } + cp = ep + 1; + /* need to NULL out separator to use sudo_strtonum() */ + /* XXX - use sudo_strtonumx */ + if ((ep = strchr(cp, ':')) != NULL) { + *ep = '\0'; + } + evlog->lines = sudo_strtonum(cp, 1, INT_MAX, &errstr); + if (errstr != NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "%s: tty lines %s: %s", iolog_dir, cp, errstr); + } + if (ep != NULL) { + cp = ep + 1; + evlog->columns = sudo_strtonum(cp, 1, INT_MAX, &errstr); + if (errstr != NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "%s: tty cols %s: %s", iolog_dir, cp, errstr); + } + } + } + + ret = true; + +done: + free(buf); + debug_return_bool(ret); +} diff --git a/lib/iolog/iolog_util.c b/lib/iolog/iolog_util.c index 88e693e8f..59313ec17 100644 --- a/lib/iolog/iolog_util.c +++ b/lib/iolog/iolog_util.c @@ -49,130 +49,6 @@ static int timing_event_adj; -bool -iolog_parse_loginfo_legacy(FILE *fp, const char *iolog_dir, - struct eventlog *evlog) -{ - char *buf = NULL, *cp, *ep; - const char *errstr; - size_t bufsize = 0, cwdsize = 0, cmdsize = 0; - bool ret = false; - debug_decl(iolog_parse_loginfo_legacy, SUDO_DEBUG_UTIL); - - /* - * Info file has three lines: - * 1) a log info line - * 2) cwd - * 3) command with args - */ - if (getdelim(&buf, &bufsize, '\n', fp) == -1 || - getdelim(&evlog->cwd, &cwdsize, '\n', fp) == -1 || - getdelim(&evlog->command, &cmdsize, '\n', fp) == -1) { - sudo_warn(U_("%s: invalid log file"), iolog_dir); - goto done; - } - - /* Strip the newline from the cwd and command. */ - evlog->cwd[strcspn(evlog->cwd, "\n")] = '\0'; - evlog->command[strcspn(evlog->command, "\n")] = '\0'; - - /* - * Crack the log line (lines and cols not present in old versions). - * timestamp:user:runas_user:runas_group:tty:lines:cols - * XXX - probably better to use strtok and switch on the state. - */ - buf[strcspn(buf, "\n")] = '\0'; - cp = buf; - - /* timestamp */ - if ((ep = strchr(cp, ':')) == NULL) { - sudo_warn(U_("%s: time stamp field is missing"), iolog_dir); - goto done; - } - *ep = '\0'; - evlog->submit_time.tv_sec = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr); - if (errstr != NULL) { - sudo_warn(U_("%s: time stamp %s: %s"), iolog_dir, cp, errstr); - goto done; - } - - /* submit user */ - cp = ep + 1; - if ((ep = strchr(cp, ':')) == NULL) { - sudo_warn(U_("%s: user field is missing"), iolog_dir); - goto done; - } - if ((evlog->submituser = strndup(cp, (size_t)(ep - cp))) == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - goto done; - } - - /* runas user */ - cp = ep + 1; - if ((ep = strchr(cp, ':')) == NULL) { - sudo_warn(U_("%s: runas user field is missing"), iolog_dir); - goto done; - } - if ((evlog->runuser = strndup(cp, (size_t)(ep - cp))) == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - goto done; - } - - /* runas group */ - cp = ep + 1; - if ((ep = strchr(cp, ':')) == NULL) { - sudo_warn(U_("%s: runas group field is missing"), iolog_dir); - goto done; - } - if (cp != ep) { - if ((evlog->rungroup = strndup(cp, (size_t)(ep - cp))) == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - goto done; - } - } - - /* tty, followed by optional lines + cols */ - cp = ep + 1; - if ((ep = strchr(cp, ':')) == NULL) { - /* just the tty */ - if ((evlog->ttyname = strdup(cp)) == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - goto done; - } - } else { - /* tty followed by lines + cols */ - if ((evlog->ttyname = strndup(cp, (size_t)(ep - cp))) == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - goto done; - } - cp = ep + 1; - /* need to NULL out separator to use sudo_strtonum() */ - /* XXX - use sudo_strtonumx */ - if ((ep = strchr(cp, ':')) != NULL) { - *ep = '\0'; - } - evlog->lines = sudo_strtonum(cp, 1, INT_MAX, &errstr); - if (errstr != NULL) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, - "%s: tty lines %s: %s", iolog_dir, cp, errstr); - } - if (ep != NULL) { - cp = ep + 1; - evlog->columns = sudo_strtonum(cp, 1, INT_MAX, &errstr); - if (errstr != NULL) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, - "%s: tty cols %s: %s", iolog_dir, cp, errstr); - } - } - } - - ret = true; - -done: - free(buf); - debug_return_bool(ret); -} - struct eventlog * iolog_parse_loginfo(int dfd, const char *iolog_dir) {