2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 01:49:11 +00:00

Add tests for iolog filtering.

This is the functionality used by the log_passwords and passprompt_regex
options.
This commit is contained in:
Todd C. Miller 2022-02-18 09:40:40 -07:00
parent b19bd98531
commit cadfbfedb9
18 changed files with 434 additions and 3 deletions

View File

@ -172,6 +172,22 @@ lib/iolog/regress/fuzz/fuzz_iolog_json.dict
lib/iolog/regress/fuzz/fuzz_iolog_legacy.c
lib/iolog/regress/fuzz/fuzz_iolog_timing.c
lib/iolog/regress/host_port/host_port_test.c
lib/iolog/regress/iolog_filter/check_iolog_filter.c
lib/iolog/regress/iolog_filter/test1/log
lib/iolog/regress/iolog_filter/test1/timing
lib/iolog/regress/iolog_filter/test1/ttyin
lib/iolog/regress/iolog_filter/test1/ttyin.filtered
lib/iolog/regress/iolog_filter/test1/ttyout
lib/iolog/regress/iolog_filter/test2/log
lib/iolog/regress/iolog_filter/test2/timing
lib/iolog/regress/iolog_filter/test2/ttyin
lib/iolog/regress/iolog_filter/test2/ttyin.filtered
lib/iolog/regress/iolog_filter/test2/ttyout
lib/iolog/regress/iolog_filter/test3/log
lib/iolog/regress/iolog_filter/test3/timing
lib/iolog/regress/iolog_filter/test3/ttyin
lib/iolog/regress/iolog_filter/test3/ttyin.filtered
lib/iolog/regress/iolog_filter/test3/ttyout
lib/iolog/regress/iolog_json/check_iolog_json.c
lib/iolog/regress/iolog_json/test1.in
lib/iolog/regress/iolog_json/test2.in

View File

@ -78,7 +78,7 @@ PVS_IGNORE = 'V707,V011,V002,V536'
PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
# Regression tests
TEST_PROGS = check_iolog_json check_iolog_mkpath check_iolog_path check_iolog_timing host_port_test
TEST_PROGS = check_iolog_filter check_iolog_json check_iolog_mkpath check_iolog_path check_iolog_timing host_port_test
TEST_LIBS = @LIBS@
TEST_LDFLAGS = @LDFLAGS@
@ -117,6 +117,8 @@ CHECK_IOLOG_PATH_OBJS = check_iolog_path.lo
CHECK_IOLOG_TIMING_OBJS = check_iolog_timing.lo
CHECK_IOLOG_FILTER_OBJS = check_iolog_filter.lo
CHECK_IOLOG_JSON_OBJS = check_iolog_json.lo
HOST_PORT_TEST_OBJS = host_port_test.lo
@ -171,6 +173,9 @@ check_iolog_mkpath: $(CHECK_IOLOG_MKPATH_OBJS) libsudo_iolog.la
check_iolog_timing: $(CHECK_IOLOG_TIMING_OBJS) libsudo_iolog.la
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_TIMING_OBJS) libsudo_iolog.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
check_iolog_filter: $(CHECK_IOLOG_FILTER_OBJS) libsudo_iolog.la
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_FILTER_OBJS) libsudo_iolog.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
check_iolog_json: $(CHECK_IOLOG_JSON_OBJS) libsudo_iolog.la
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_JSON_OBJS) libsudo_iolog.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
@ -325,6 +330,7 @@ check: $(TEST_PROGS) check-fuzzer
MALLOC_OPTIONS=S; export MALLOC_OPTIONS; \
MALLOC_CONF="abort:true,junk:true"; export MALLOC_CONF; \
rval=0; \
./check_iolog_filter $(srcdir)/regress/iolog_filter/test[1-9]* || rval=`expr $$rval + $$?`; \
./check_iolog_json $(srcdir)/regress/iolog_json/*.in || rval=`expr $$rval + $$?`; \
./check_iolog_path $(srcdir)/regress/iolog_path/data || rval=`expr $$rval + $$?`; \
./check_iolog_mkpath || rval=`expr $$rval + $$?`; \
@ -357,6 +363,20 @@ cleandir: realclean
run-fuzz_iolog_timing
# Autogenerated dependencies, do not modify
check_iolog_filter.lo: $(srcdir)/regress/iolog_filter/check_iolog_filter.c \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_iolog.h \
$(incdir)/sudo_plugin.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)/regress/iolog_filter/check_iolog_filter.c
check_iolog_filter.i: $(srcdir)/regress/iolog_filter/check_iolog_filter.c \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_iolog.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_util.h \
$(top_builddir)/config.h
$(CC) -E -o $@ $(CPPFLAGS) $<
check_iolog_filter.plog: check_iolog_filter.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/iolog_filter/check_iolog_filter.c --i-file $< --output-file $@
check_iolog_json.lo: $(srcdir)/regress/iolog_json/check_iolog_json.c \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_json.h \
@ -557,13 +577,15 @@ iolog_filter.lo: $(srcdir)/iolog_filter.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
$(incdir)/sudo_queue.h $(top_builddir)/config.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_filter.c
iolog_filter.i: $(srcdir)/iolog_filter.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
$(incdir)/sudo_queue.h $(top_builddir)/config.h
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
$(top_builddir)/config.h
$(CC) -E -o $@ $(CPPFLAGS) $<
iolog_filter.plog: iolog_filter.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_filter.c --i-file $< --output-file $@

View File

@ -0,0 +1,190 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2022 Todd C. Miller <Todd.Miller@sudo.ws>
*
* 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.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#define SUDO_ERROR_WRAP 0
#include "sudo_compat.h"
#include "sudo_util.h"
#include "sudo_fatal.h"
#include "sudo_iolog.h"
sudo_dso_public int main(int argc, char *argv[]);
int
main(int argc, char *argv[])
{
int dfd = -1, ttyin_fd = -1, ttyout_fd = -1, ttyin_ok_fd = -1;
int i, tests = 0, errors = 0;
void *passprompt_regex = NULL;
initprogname(argc > 0 ? argv[0] : "check_iolog_filter");
passprompt_regex = iolog_pwfilt_alloc();
if (passprompt_regex == NULL)
sudo_fatalx("unable to allocate memory");
if (!iolog_pwfilt_add(passprompt_regex, "(?i)password[: ]*"))
exit(1);
for (i = 1; i < argc; i++) {
struct iolog_file iolog_timing = { true };
struct timing_closure timing;
const char *logdir = argv[i];
char tbuf[8192], fbuf[8192];
ssize_t nread;
tests++;
/* I/O logs consist of multiple files in a directory. */
dfd = open(logdir, O_RDONLY);
if (dfd == -1) {
sudo_warn("%s", logdir);
errors++;
continue;
}
if (!iolog_open(&iolog_timing, dfd, IOFD_TIMING, "r")) {
sudo_warn("timing");
errors++;
goto next;
}
ttyout_fd = openat(dfd, "ttyout", O_RDONLY);
if (ttyout_fd == -1) {
sudo_warn("ttyout");
errors++;
goto next;
}
ttyin_fd = openat(dfd, "ttyin", O_RDONLY);
if (ttyin_fd == -1) {
sudo_warn("ttyin");
errors++;
goto next;
}
ttyin_ok_fd = openat(dfd, "ttyin.filtered", O_RDONLY);
if (ttyin_ok_fd == -1) {
sudo_warn("ttyin.filtered");
errors++;
goto next;
}
memset(&timing, 0, sizeof(timing));
timing.decimal = ".";
for (;;) {
char *newbuf = NULL;
const char *name;
int fd;
if (iolog_read_timing_record(&iolog_timing, &timing) != 0)
break;
switch (timing.event) {
case IO_EVENT_TTYOUT:
fd = ttyout_fd;
name = "ttyout";
break;
case IO_EVENT_TTYIN:
fd = ttyin_fd;
name = "ttyin";
break;
default:
continue;
}
if (timing.u.nbytes > sizeof(tbuf)) {
sudo_warn("buffer too small, %zu > %zu", timing.u.nbytes,
sizeof(tbuf));
errors++;
continue;
}
nread = read(fd, tbuf, timing.u.nbytes);
if ((size_t)nread != timing.u.nbytes) {
if (nread == -1)
sudo_warn("%s/%s", argv[i], name);
else
sudo_warnx("%s/%s: short read", argv[i], name);
errors++;
continue;
}
/* Apply filter. */
if (!iolog_pwfilt_run(passprompt_regex, timing.event, tbuf,
timing.u.nbytes, &newbuf)) {
errors++;
continue;
}
if (timing.event == IO_EVENT_TTYIN) {
nread = read(ttyin_ok_fd, fbuf, timing.u.nbytes);
if (nread == -1) {
if (nread == -1)
sudo_warn("%s/ttyin.filtered", argv[i]);
else
sudo_warnx("%s/ttyin.filtered: short read", argv[i]);
errors++;
free(newbuf);
break;
}
if (memcmp(fbuf, newbuf ? newbuf : tbuf, timing.u.nbytes) != 0) {
sudo_warnx("%s: ttyin mismatch at byte %lld", argv[i],
(long long)lseek(fd, 0, SEEK_CUR));
errors++;
free(newbuf);
break;
}
}
free(newbuf);
}
next:
if (ttyin_fd != -1) {
close(ttyin_fd);
ttyin_fd = -1;
}
if (ttyin_ok_fd != -1) {
close(ttyin_ok_fd);
ttyin_ok_fd = -1;
}
if (dfd != -1) {
close(dfd);
dfd = -1;
}
if (iolog_timing.enabled)
iolog_close(&iolog_timing, NULL);
}
iolog_pwfilt_free(passprompt_regex);
if (tests != 0) {
printf("%s: %d test%s run, %d errors, %d%% success rate\n",
getprogname(), tests, tests == 1 ? "" : "s", errors,
(tests - errors) * 100 / tests);
}
exit(errors);
}

View File

@ -0,0 +1,3 @@
1645151020:millert:root::/dev/ttypb:24:80
/home/millert
/usr/bin/passwd

View File

@ -0,0 +1,44 @@
4 0.087089703 32
4 0.000503221 13
3 1.617732029 1
3 0.671818399 1
3 0.632182533 1
3 0.135484597 1
3 0.120171445 1
3 0.120200768 1
3 0.239782513 1
3 0.064059449 1
3 0.184048364 1
3 0.135992479 1
3 0.167905298 1
3 0.087948033 1
3 0.135913060 1
3 0.136306311 1
3 0.279830387 1
3 0.280221744 1
4 0.000453682 2
4 0.001188404 20
3 0.678534827 1
3 1.912119627 1
3 0.303804149 1
3 0.071831900 1
3 0.248608651 1
3 0.088758738 1
3 0.262821628 1
3 0.111839737 1
3 0.184326849 1
3 0.119709565 1
3 0.184446495 1
3 0.089439595 1
3 0.150353799 1
3 0.152035883 1
3 0.392237165 1
3 0.183498720 1
3 0.136099560 1
3 0.256165394 1
4 0.000392254 2
4 0.000348360 35
4 0.000330782 13
3 0.871580665 1
4 0.000434371 2
4 0.001150945 23

View File

@ -0,0 +1 @@
A new password? A bad password... 

View File

@ -0,0 +1 @@
*************** ***************** *

View File

@ -0,0 +1,7 @@
Changing password for millert.
New password:
Retype new password:
Mismatch; try again, EOF to quit.
New password:
Password unchanged.

View File

@ -0,0 +1,3 @@
1645153850:millert:millert::/dev/ttypb:24:80
/home/millert
/usr/bin/su testdude

View File

@ -0,0 +1,73 @@
4 0.077895153 9
3 9.876530326 1
3 0.191980568 1
3 0.168017746 1
3 0.088081740 1
3 0.183886638 1
3 0.071966892 1
3 0.175772878 1
3 0.672270691 1
4 0.000336085 2
4 0.022264031 8
3 4.721817713 1
4 0.001379444 1
3 0.086406844 1
4 0.000383615 1
3 0.055583229 1
4 0.000353543 1
3 0.079726966 1
4 0.000336390 1
3 0.063626746 1
4 0.000719018 1
3 0.135204338 1
4 0.000342720 1
3 0.095976209 1
4 0.000338049 1
3 0.047259669 1
4 0.000339501 1
3 0.399809817 1
4 0.000345392 1
3 0.111587761 1
4 0.000366589 1
3 0.087582640 1
4 0.000328160 1
3 0.480159500 1
4 0.000370778 3
3 0.143285883 1
4 0.000332529 3
3 0.135841236 1
4 0.000343729 3
3 0.223401313 1
4 0.000329496 1
3 0.063760060 1
4 0.000382349 1
3 0.087442363 1
4 0.000345787 1
3 0.095598655 1
4 0.000343712 1
3 0.560106197 1
4 0.000405183 3
3 0.151363786 1
4 0.000345085 3
3 0.167809002 1
4 0.000326037 3
3 0.135471962 1
4 0.000378004 3
3 0.111681517 1
4 0.000329093 1
3 0.127537491 1
4 0.000355403 1
3 0.103896235 1
4 0.000320608 1
3 0.095563437 1
4 0.000327463 1
3 0.087808248 1
4 0.000321244 1
3 0.503531970 1
4 0.000338699 1
3 1.383887942 1
4 0.000324499 3
4 0.000334583 11
4 0.000324866 8
3 0.999440679 1
4 0.000365851 5

View File

@ -0,0 +1 @@
test123 echo hi ereherethere! 

View File

@ -0,0 +1 @@
******* echo hi ereherethere! 

View File

@ -0,0 +1,4 @@
Password:
xerxes$ echo hi ere   here    there!
hi there!
xerxes$ ^D

View File

@ -0,0 +1,3 @@
1645201461:millert:root::/dev/ttyp0:24:80
/home/millert
/usr/bin/ssh -oPubkeyAuthentication=no localhost

View File

@ -0,0 +1,54 @@
4 0.158768144 1
4 0.000406264 27
3 4.390837642 1
3 0.119705081 1
3 0.175600726 1
3 0.064357615 1
3 0.239945395 1
3 0.088142451 1
3 0.143665762 1
3 0.071941169 1
3 0.208359675 1
3 0.145706215 1
3 0.302231926 1
3 0.079805215 1
3 0.112114024 1
3 0.143802378 1
3 0.160033289 1
4 0.000416283 2
4 0.042939142 40
4 0.000399448 27
3 1.084753026 1
3 0.087720859 1
3 0.215896027 1
3 0.167921572 1
3 0.304253899 1
3 0.103807201 1
3 0.191962088 1
3 0.071989566 1
3 0.296183440 1
3 0.162262688 1
3 0.125661454 1
3 0.192164590 1
4 0.000394039 2
4 0.034617321 40
4 0.000414822 27
3 0.796676353 1
3 0.119589531 1
3 0.120189440 1
3 0.080002264 1
3 0.120104599 1
3 0.087897523 1
3 0.088072936 1
3 0.111980459 1
3 0.064099904 1
3 0.440166638 1
3 0.159957933 1
3 0.063988834 1
3 0.247906778 1
3 0.167767797 1
3 0.151961605 1
3 0.176237322 1
3 0.368288839 1
4 0.000364019 2
4 0.034413644 79

View File

@ -0,0 +1 @@
not a password nope, sorry try again please

View File

@ -0,0 +1 @@
************** *********** ****************

View File

@ -0,0 +1,6 @@
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
root@localhost: Permission denied (publickey,password,keyboard-interactive).