Add tests for JSON and sudo-style log output.
This commit is contained in:
14
MANIFEST
14
MANIFEST
@@ -118,6 +118,20 @@ lib/eventlog/eventlog_free.c
|
||||
lib/eventlog/eventlog_json.h
|
||||
lib/eventlog/logwrap.c
|
||||
lib/eventlog/parse_json.c
|
||||
lib/eventlog/regress/eventlog_store/store_json_test.c
|
||||
lib/eventlog/regress/eventlog_store/store_sudo_test.c
|
||||
lib/eventlog/regress/eventlog_store/test1.json.in
|
||||
lib/eventlog/regress/eventlog_store/test1.json.out.ok
|
||||
lib/eventlog/regress/eventlog_store/test1.sudo.out.ok
|
||||
lib/eventlog/regress/eventlog_store/test2.json.in
|
||||
lib/eventlog/regress/eventlog_store/test2.json.out.ok
|
||||
lib/eventlog/regress/eventlog_store/test2.sudo.out.ok
|
||||
lib/eventlog/regress/eventlog_store/test3.json.in
|
||||
lib/eventlog/regress/eventlog_store/test3.json.out.ok
|
||||
lib/eventlog/regress/eventlog_store/test3.sudo.out.ok
|
||||
lib/eventlog/regress/eventlog_store/test4.json.in
|
||||
lib/eventlog/regress/eventlog_store/test4.json.out.ok
|
||||
lib/eventlog/regress/eventlog_store/test4.sudo.out.ok
|
||||
lib/eventlog/regress/logwrap/check_wrap.c
|
||||
lib/eventlog/regress/logwrap/check_wrap.in
|
||||
lib/eventlog/regress/logwrap/check_wrap.out.ok
|
||||
|
@@ -82,7 +82,7 @@ DEVEL = @DEVEL@
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
TEST_PROGS = check_wrap check_parse_json
|
||||
TEST_PROGS = check_wrap check_parse_json store_json_test store_sudo_test
|
||||
TEST_VERBOSE =
|
||||
|
||||
LIBEVENTLOG_OBJS = eventlog.lo eventlog_conf.lo eventlog_free.lo logwrap.lo \
|
||||
@@ -96,6 +96,10 @@ CHECK_WRAP_OBJS = check_wrap.lo logwrap.lo
|
||||
|
||||
CHECK_PARSE_JSON_OBJS = check_parse_json.lo parse_json.lo
|
||||
|
||||
STORE_JSON_TEST_OBJS = store_json_test.lo
|
||||
|
||||
STORE_SUDO_TEST_OBJS = store_sudo_test.lo
|
||||
|
||||
all: libsudo_eventlog.la
|
||||
|
||||
depend:
|
||||
@@ -126,6 +130,12 @@ check_parse_json: $(CHECK_PARSE_JSON_OBJS)
|
||||
check_wrap: $(CHECK_WRAP_OBJS) $(LIBUTIL)
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_WRAP_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(LIBS)
|
||||
|
||||
store_json_test: $(STORE_JSON_TEST_OBJS) libsudo_eventlog.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(STORE_JSON_TEST_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(LIBS) libsudo_eventlog.la
|
||||
|
||||
store_sudo_test: $(STORE_SUDO_TEST_OBJS) libsudo_eventlog.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(STORE_SUDO_TEST_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(LIBS) libsudo_eventlog.la
|
||||
|
||||
pre-install:
|
||||
|
||||
install:
|
||||
@@ -169,6 +179,8 @@ check: $(TEST_PROGS) check-fuzzer
|
||||
umask 022; \
|
||||
rval=0; \
|
||||
./check_parse_json $(srcdir)/regress/parse_json/*.in || rval=`expr $$rval + $$?`; \
|
||||
./store_json_test $(srcdir)/regress/eventlog_store/*.json.in || rval=`expr $$rval + $$?`; \
|
||||
./store_sudo_test $(srcdir)/regress/eventlog_store/*.json.in || rval=`expr $$rval + $$?`; \
|
||||
mkdir -p regress/logwrap; \
|
||||
./check_wrap $(srcdir)/regress/logwrap/check_wrap.in > regress/logwrap/check_wrap.out; \
|
||||
diff regress/logwrap/check_wrap.out $(srcdir)/regress/logwrap/check_wrap.out.ok || rval=`expr $$rval + $$?`; \
|
||||
@@ -200,14 +212,16 @@ cleandir: realclean
|
||||
check_parse_json.lo: $(srcdir)/regress/parse_json/check_parse_json.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(incdir)/sudo_json.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/parse_json.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/regress/parse_json/check_parse_json.c
|
||||
check_parse_json.i: $(srcdir)/regress/parse_json/check_parse_json.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(incdir)/sudo_json.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/parse_json.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
check_parse_json.plog: check_parse_json.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parse_json/check_parse_json.c --i-file $< --output-file $@
|
||||
@@ -288,16 +302,48 @@ logwrap.plog: logwrap.i
|
||||
parse_json.lo: $(srcdir)/parse_json.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_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_json.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(srcdir)/parse_json.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/parse_json.c
|
||||
parse_json.i: $(srcdir)/parse_json.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_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_json.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(srcdir)/parse_json.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
parse_json.plog: parse_json.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/parse_json.c --i-file $< --output-file $@
|
||||
store_json_test.lo: $(srcdir)/regress/eventlog_store/store_json_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_json.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/parse_json.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/regress/eventlog_store/store_json_test.c
|
||||
store_json_test.i: $(srcdir)/regress/eventlog_store/store_json_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_json.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/parse_json.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
store_json_test.plog: store_json_test.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/eventlog_store/store_json_test.c --i-file $< --output-file $@
|
||||
store_sudo_test.lo: $(srcdir)/regress/eventlog_store/store_sudo_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_lbuf.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) $(HARDENING_CFLAGS) $(srcdir)/regress/eventlog_store/store_sudo_test.c
|
||||
store_sudo_test.i: $(srcdir)/regress/eventlog_store/store_sudo_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
store_sudo_test.plog: store_sudo_test.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/eventlog_store/store_sudo_test.c --i-file $< --output-file $@
|
||||
|
198
lib/eventlog/regress/eventlog_store/store_json_test.c
Normal file
198
lib/eventlog/regress/eventlog_store/store_json_test.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2020, 2023 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 <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SUDO_ERROR_WRAP 0
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_eventlog.h"
|
||||
#include "sudo_fatal.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
#include "parse_json.h"
|
||||
|
||||
sudo_dso_public int main(int argc, char *argv[]);
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-cv] input_file ...\n",
|
||||
getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static bool
|
||||
compare(FILE *fp, const char *infile, struct json_container *jsonc)
|
||||
{
|
||||
const char *cp;
|
||||
unsigned int lineno = 0;
|
||||
size_t linesize = 0;
|
||||
char *line = NULL;
|
||||
ssize_t len;
|
||||
|
||||
cp = sudo_json_get_buf(jsonc);
|
||||
|
||||
while ((len = getdelim(&line, &linesize, '\n', fp)) != -1) {
|
||||
lineno++;
|
||||
|
||||
/* skip open/close brace, not present in formatted output */
|
||||
if (lineno == 1 && strcmp(line, "{\n") == 0)
|
||||
continue;
|
||||
if (*cp == '\0' && strcmp(line, "}\n") == 0)
|
||||
continue;
|
||||
|
||||
/* Ignore newlines in output to make comparison easier. */
|
||||
if (*cp == '\n')
|
||||
cp++;
|
||||
if (line[len - 1] == '\n')
|
||||
len--;
|
||||
|
||||
if (strncmp(line, cp, len) != 0) {
|
||||
fprintf(stderr, "%s: mismatch on line %u\n", infile, lineno);
|
||||
fprintf(stderr, "expected: %s", line);
|
||||
fprintf(stderr, "got : %.*s\n", (int)len, cp);
|
||||
return false;
|
||||
}
|
||||
cp += len;
|
||||
}
|
||||
free(line);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, i, ntests = 0, errors = 0;
|
||||
bool cat = false;
|
||||
|
||||
initprogname(argc > 0 ? argv[0] : "store_json_test");
|
||||
|
||||
while ((ch = getopt(argc, argv, "cv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
cat = true;
|
||||
break;
|
||||
case 'v':
|
||||
/* ignored */
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
struct eventlog_json_object *root;
|
||||
struct eventlog *evlog = NULL;
|
||||
struct json_container jsonc;
|
||||
const char *infile = argv[i];
|
||||
const char *outfile = argv[i];
|
||||
const char *cp;
|
||||
char pathbuf[PATH_MAX];
|
||||
FILE *infp = NULL;
|
||||
FILE *outfp = NULL;
|
||||
|
||||
ntests++;
|
||||
|
||||
if (!sudo_json_init(&jsonc, 4, false, true, true)) {
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Parse input file. */
|
||||
if ((infp = fopen(infile, "r")) == NULL) {
|
||||
sudo_warn("%s", argv[i]);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
root = eventlog_json_read(infp, infile);
|
||||
if (root == NULL) {
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Convert JSON to event log. */
|
||||
evlog = calloc(1, sizeof(*evlog));
|
||||
if (evlog == NULL) {
|
||||
sudo_warnx("%s: %s", __func__, "unable to allocate memory");
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
if (!eventlog_json_parse(root, evlog)) {
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Format event log as JSON. */
|
||||
if (!eventlog_store_json(&jsonc, evlog)) {
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Check for a .out.ok file in the same location as the .in file. */
|
||||
cp = strrchr(infile, '.');
|
||||
if (cp != NULL && strcmp(cp, ".in") == 0) {
|
||||
snprintf(pathbuf, sizeof(pathbuf), "%.*s.out.ok",
|
||||
(int)(cp - infile), infile);
|
||||
if ((outfp = fopen(pathbuf, "r")) != NULL)
|
||||
outfile = pathbuf;
|
||||
}
|
||||
if (outfp == NULL)
|
||||
outfp = infp;
|
||||
|
||||
/* Compare output to expected output. */
|
||||
rewind(outfp);
|
||||
if (!compare(outfp, outfile, &jsonc))
|
||||
errors++;
|
||||
|
||||
/* Write the formatted output to stdout for -c (cat) */
|
||||
if (cat) {
|
||||
fprintf(stdout, "{%s\n}\n", sudo_json_get_buf(&jsonc));
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
next:
|
||||
eventlog_free(evlog);
|
||||
eventlog_json_free(root);
|
||||
sudo_json_free(&jsonc);
|
||||
if (infp != NULL)
|
||||
fclose(infp);
|
||||
if (outfp != NULL && outfp != infp)
|
||||
fclose(outfp);
|
||||
}
|
||||
|
||||
if (ntests != 0) {
|
||||
printf("%s: %d test%s run, %d errors, %d%% success rate\n",
|
||||
getprogname(), ntests, ntests == 1 ? "" : "s", errors,
|
||||
(ntests - errors) * 100 / ntests);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
206
lib/eventlog/regress/eventlog_store/store_sudo_test.c
Normal file
206
lib/eventlog/regress/eventlog_store/store_sudo_test.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2020, 2023 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 <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SUDO_ERROR_WRAP 0
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_eventlog.h"
|
||||
#include "sudo_fatal.h"
|
||||
#include "sudo_lbuf.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
sudo_dso_public int main(int argc, char *argv[]);
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-cv] input_file ...\n",
|
||||
getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static bool
|
||||
compare(FILE *fp, const char *infile, const char *output)
|
||||
{
|
||||
static size_t linesize = 0;
|
||||
static char *line = NULL;
|
||||
int i;
|
||||
|
||||
/* Expect two log lines, one for accept, one for exit. */
|
||||
for (i = 0; i < 2; i++) {
|
||||
ssize_t output_len = strcspn(output, "\n");
|
||||
ssize_t len = getdelim(&line, &linesize, '\n', fp);
|
||||
if (len == -1) {
|
||||
sudo_warn("getdelim");
|
||||
return false;
|
||||
}
|
||||
if (line[len - 1] == '\n')
|
||||
len--;
|
||||
|
||||
if (len != output_len || strncmp(line, output, len) != 0) {
|
||||
fprintf(stderr, "%s: %s mismatch\n", infile, i ? "exit" : "accept");
|
||||
fprintf(stderr, "expected: %.*s\n", (int)len, line);
|
||||
fprintf(stderr, "got : %.*s\n", (int)output_len, output);
|
||||
return false;
|
||||
}
|
||||
if (i == 0) {
|
||||
/* Skip past newline in accept record output. */
|
||||
output += output_len;
|
||||
if (output[0] != '\n' || output[1] == '\0') {
|
||||
sudo_warnx("missing exit record");
|
||||
return false;
|
||||
}
|
||||
output++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, i, ntests = 0, errors = 0;
|
||||
struct sudo_lbuf lbuf;
|
||||
bool cat = false;
|
||||
|
||||
initprogname(argc > 0 ? argv[0] : "store_sudo_test");
|
||||
|
||||
while ((ch = getopt(argc, argv, "v")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
cat = true;
|
||||
break;
|
||||
case 'v':
|
||||
/* ignored */
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0);
|
||||
for (i = 0; i < argc; i++) {
|
||||
struct eventlog_json_object *root;
|
||||
struct eventlog *evlog = NULL;
|
||||
const char *infile = argv[i];
|
||||
const char *outfile = argv[i];
|
||||
char pathbuf[PATH_MAX];
|
||||
FILE *infp = NULL;
|
||||
FILE *outfp = NULL;
|
||||
size_t len;
|
||||
|
||||
ntests++;
|
||||
|
||||
/* Parse input file. */
|
||||
if ((infp = fopen(infile, "r")) == NULL) {
|
||||
sudo_warn("%s", argv[i]);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
root = eventlog_json_read(infp, infile);
|
||||
if (root == NULL) {
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Convert JSON to event log. */
|
||||
evlog = calloc(1, sizeof(*evlog));
|
||||
if (evlog == NULL) {
|
||||
sudo_warnx("%s: %s", __func__, "unable to allocate memory");
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
if (!eventlog_json_parse(root, evlog)) {
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Format event log in sudo log format. */
|
||||
if (!eventlog_store_sudo(EVLOG_ACCEPT, evlog, &lbuf)) {
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
sudo_lbuf_append(&lbuf, "\n");
|
||||
if (!eventlog_store_sudo(EVLOG_EXIT, evlog, &lbuf)) {
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
sudo_lbuf_append(&lbuf, "\n");
|
||||
|
||||
/* Write the formatted output to stdout for -c (cat) */
|
||||
if (cat) {
|
||||
puts(lbuf.buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* Check for a .out.ok file in the same location as the .in file. */
|
||||
len = strlen(infile);
|
||||
if (len < sizeof(".json.in")) {
|
||||
sudo_warnx("%s must end in .json.in", infile);
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
len -= sizeof(".json.in") - 1;
|
||||
if (strcmp(&infile[len], ".json.in") != 0) {
|
||||
sudo_warnx("%s must end in .json.in", infile);
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
snprintf(pathbuf, sizeof(pathbuf), "%.*s.sudo.out.ok",
|
||||
(int)len, infile);
|
||||
if ((outfp = fopen(pathbuf, "r")) == NULL) {
|
||||
sudo_warn("%s", pathbuf);
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Compare output to expected output. */
|
||||
if (!compare(outfp, outfile, lbuf.buf))
|
||||
errors++;
|
||||
|
||||
next:
|
||||
lbuf.len = 0;
|
||||
eventlog_free(evlog);
|
||||
if (infp != NULL)
|
||||
fclose(infp);
|
||||
if (outfp != NULL && outfp != infp)
|
||||
fclose(outfp);
|
||||
}
|
||||
|
||||
if (ntests != 0) {
|
||||
printf("%s: %d test%s run, %d errors, %d%% success rate\n",
|
||||
getprogname(), ntests, ntests == 1 ? "" : "s", errors,
|
||||
(ntests - errors) * 100 / ntests);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
51
lib/eventlog/regress/eventlog_store/test1.json.in
Normal file
51
lib/eventlog/regress/eventlog_store/test1.json.in
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"uuid": "94109a6eb8-9bed-41ba-0ff1-79926f3947",
|
||||
"server_time": {
|
||||
"seconds": 1677638673,
|
||||
"nanoseconds": 98769807,
|
||||
"iso8601": "20230301024433Z",
|
||||
"localtime": "Tue Feb 28 19:44:33 MST 2023"
|
||||
},
|
||||
"submit_time": {
|
||||
"seconds": 1677638673,
|
||||
"nanoseconds": 93789768,
|
||||
"iso8601": "20230301024433Z",
|
||||
"localtime": "Tue Feb 28 19:44:33 MST 2023"
|
||||
},
|
||||
"peeraddr": "172.30.200.2",
|
||||
"iolog_path": "/var/log/sudo-logsrvd/millert/00/03/FI",
|
||||
"iolog_file": "00/03/FI",
|
||||
"columns": 80,
|
||||
"command": "/usr/bin/ci",
|
||||
"lines": 24,
|
||||
"runargv": [
|
||||
"ci",
|
||||
"-u",
|
||||
"aliases\n"
|
||||
],
|
||||
"runenv": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"TERM=tmux",
|
||||
"LANG=en_US.UTF-8",
|
||||
"MAIL=/var/mail/root",
|
||||
"LOGNAME=root",
|
||||
"USER=root",
|
||||
"HOME=/root",
|
||||
"SHELL=/bin/bash",
|
||||
"SUDO_COMMAND=/usr/bin/ci -u aliases",
|
||||
"SUDO_USER=millert",
|
||||
"SUDO_UID=8036",
|
||||
"SUDO_GID=20"
|
||||
],
|
||||
"runenv_override": [
|
||||
"KRB5CCNAME=bogus",
|
||||
"LD_LIBRARY_PATH=/opt/sudo/libexec"
|
||||
],
|
||||
"runuid": 0,
|
||||
"runuser": "root",
|
||||
"submitcwd": "/etc/mail",
|
||||
"submithost": "xerxes.sudo.ws",
|
||||
"submituser": "millert",
|
||||
"ttyname": "/dev/ttypb",
|
||||
"exit_value": 1
|
||||
}
|
30
lib/eventlog/regress/eventlog_store/test1.json.out.ok
Normal file
30
lib/eventlog/regress/eventlog_store/test1.json.out.ok
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"submituser": "millert",
|
||||
"command": "/usr/bin/ci",
|
||||
"runuser": "root",
|
||||
"ttyname": "/dev/ttypb",
|
||||
"submithost": "xerxes.sudo.ws",
|
||||
"submitcwd": "/etc/mail",
|
||||
"runuid": 0,
|
||||
"columns": 80,
|
||||
"lines": 24,
|
||||
"runargv": [
|
||||
"ci",
|
||||
"-u",
|
||||
"aliases\n"
|
||||
],
|
||||
"runenv": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"TERM=tmux",
|
||||
"LANG=en_US.UTF-8",
|
||||
"MAIL=/var/mail/root",
|
||||
"LOGNAME=root",
|
||||
"USER=root",
|
||||
"HOME=/root",
|
||||
"SHELL=/bin/bash",
|
||||
"SUDO_COMMAND=/usr/bin/ci -u aliases",
|
||||
"SUDO_USER=millert",
|
||||
"SUDO_UID=8036",
|
||||
"SUDO_GID=20"
|
||||
]
|
||||
}
|
2
lib/eventlog/regress/eventlog_store/test1.sudo.out.ok
Normal file
2
lib/eventlog/regress/eventlog_store/test1.sudo.out.ok
Normal file
@@ -0,0 +1,2 @@
|
||||
HOST=xerxes.sudo.ws ; TTY=ttypb ; CWD=/etc/mail ; USER=root ; TSID=0003FI ; ENV=KRB5CCNAME=bogus LD_LIBRARY_PATH=/opt/sudo/libexec ; COMMAND=/usr/bin/ci -u aliases#012
|
||||
HOST=xerxes.sudo.ws ; TTY=ttypb ; CWD=/etc/mail ; USER=root ; TSID=0003FI ; ENV=KRB5CCNAME=bogus LD_LIBRARY_PATH=/opt/sudo/libexec ; COMMAND=/usr/bin/ci -u aliases#012 ; EXIT=1
|
47
lib/eventlog/regress/eventlog_store/test2.json.in
Normal file
47
lib/eventlog/regress/eventlog_store/test2.json.in
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"uuid": "a17521dd52-1b7f-4ca1-5086-6957336362",
|
||||
"server_time": {
|
||||
"seconds": 1671070212,
|
||||
"nanoseconds": 246006550,
|
||||
"iso8601": "20221215021012Z",
|
||||
"localtime": "Wed Dec 14 19:10:12 MST 2022"
|
||||
},
|
||||
"submit_time": {
|
||||
"seconds": 1671070212,
|
||||
"nanoseconds": 243017337,
|
||||
"iso8601": "20221215021012Z",
|
||||
"localtime": "Wed Dec 14 19:10:12 MST 2022"
|
||||
},
|
||||
"peeraddr": "172.30.200.2",
|
||||
"iolog_path": "/var/log/sudo-logsrvd/millert/00/03/5Q",
|
||||
"iolog_file": "00/03/5Q",
|
||||
"columns": 80,
|
||||
"command": "/usr/bin/id",
|
||||
"lines": 24,
|
||||
"runargv": [
|
||||
"id"
|
||||
],
|
||||
"runenv": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"TERM=tmux",
|
||||
"LANG=en_US.UTF-8",
|
||||
"MAIL=/var/mail/root",
|
||||
"LOGNAME=root",
|
||||
"USER=root",
|
||||
"HOME=/root",
|
||||
"SHELL=/bin/bash",
|
||||
"SUDO_COMMAND=/usr/bin/id",
|
||||
"SUDO_USER=millert",
|
||||
"SUDO_UID=8036",
|
||||
"SUDO_GID=20"
|
||||
],
|
||||
"runenv_override": [
|
||||
"KRB5CCNAME=bogus"
|
||||
],
|
||||
"runuid": 0,
|
||||
"runuser": "root",
|
||||
"submitcwd": "/usr/src/local/millert/sudo/trunk",
|
||||
"submithost": "xerxes.sudo.ws",
|
||||
"submituser": "millert",
|
||||
"ttyname": "/dev/ttyp0"
|
||||
}
|
28
lib/eventlog/regress/eventlog_store/test2.json.out.ok
Normal file
28
lib/eventlog/regress/eventlog_store/test2.json.out.ok
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"submituser": "millert",
|
||||
"command": "/usr/bin/id",
|
||||
"runuser": "root",
|
||||
"ttyname": "/dev/ttyp0",
|
||||
"submithost": "xerxes.sudo.ws",
|
||||
"submitcwd": "/usr/src/local/millert/sudo/trunk",
|
||||
"runuid": 0,
|
||||
"columns": 80,
|
||||
"lines": 24,
|
||||
"runargv": [
|
||||
"id"
|
||||
],
|
||||
"runenv": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"TERM=tmux",
|
||||
"LANG=en_US.UTF-8",
|
||||
"MAIL=/var/mail/root",
|
||||
"LOGNAME=root",
|
||||
"USER=root",
|
||||
"HOME=/root",
|
||||
"SHELL=/bin/bash",
|
||||
"SUDO_COMMAND=/usr/bin/id",
|
||||
"SUDO_USER=millert",
|
||||
"SUDO_UID=8036",
|
||||
"SUDO_GID=20"
|
||||
]
|
||||
}
|
2
lib/eventlog/regress/eventlog_store/test2.sudo.out.ok
Normal file
2
lib/eventlog/regress/eventlog_store/test2.sudo.out.ok
Normal file
@@ -0,0 +1,2 @@
|
||||
HOST=xerxes.sudo.ws ; TTY=ttyp0 ; CWD=/usr/src/local/millert/sudo/trunk ; USER=root ; TSID=00035Q ; ENV=KRB5CCNAME=bogus ; COMMAND=/usr/bin/id
|
||||
HOST=xerxes.sudo.ws ; TTY=ttyp0 ; CWD=/usr/src/local/millert/sudo/trunk ; USER=root ; TSID=00035Q ; ENV=KRB5CCNAME=bogus ; COMMAND=/usr/bin/id ; EXIT=0
|
48
lib/eventlog/regress/eventlog_store/test3.json.in
Normal file
48
lib/eventlog/regress/eventlog_store/test3.json.in
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"uuid": "54e6806305-0f50-44bf-fe6a-c8fa7a65ac",
|
||||
"server_time": {
|
||||
"seconds": 1678475729,
|
||||
"nanoseconds": 286796437,
|
||||
"iso8601": "20230310191529Z",
|
||||
"localtime": "Fri Mar 10 12:15:29 MST 2023"
|
||||
},
|
||||
"submit_time": {
|
||||
"seconds": 1633116433,
|
||||
"nanoseconds": 682537651,
|
||||
"iso8601": "20211001192713Z",
|
||||
"localtime": "Fri Oct 1 13:27:13 MDT 2021"
|
||||
},
|
||||
"peeraddr": "172.30.200.50",
|
||||
"iolog_path": "/var/log/sudo-logsrvd/millert/00/00/5H",
|
||||
"iolog_file": "00/00/5H",
|
||||
"columns": 80,
|
||||
"command": "/usr/bin/find",
|
||||
"lines": 24,
|
||||
"runargv": [
|
||||
"find",
|
||||
"build/out/sudoers/"
|
||||
],
|
||||
"runenv": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"TERM=tmux",
|
||||
"LANG=en_US.UTF-8",
|
||||
"MAIL=/var/mail/root",
|
||||
"LOGNAME=root",
|
||||
"USER=root",
|
||||
"HOME=/root",
|
||||
"SHELL=/bin/bash",
|
||||
"SUDO_COMMAND=/usr/bin/find build/out/sudoers/",
|
||||
"SUDO_USER=millert",
|
||||
"SUDO_UID=8036",
|
||||
"SUDO_GID=20"
|
||||
],
|
||||
"runuid": 0,
|
||||
"runuser": "root",
|
||||
"submitcwd": "/home/millert/sudo/oss-fuzz",
|
||||
"submithost": "linux-build",
|
||||
"submituser": "millert",
|
||||
"ttyname": "/dev/pts/1",
|
||||
"exit_value": 131,
|
||||
"signal": "QUIT",
|
||||
"dumped_core": true
|
||||
}
|
29
lib/eventlog/regress/eventlog_store/test3.json.out.ok
Normal file
29
lib/eventlog/regress/eventlog_store/test3.json.out.ok
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"submituser": "millert",
|
||||
"command": "/usr/bin/find",
|
||||
"runuser": "root",
|
||||
"ttyname": "/dev/pts/1",
|
||||
"submithost": "linux-build",
|
||||
"submitcwd": "/home/millert/sudo/oss-fuzz",
|
||||
"runuid": 0,
|
||||
"columns": 80,
|
||||
"lines": 24,
|
||||
"runargv": [
|
||||
"find",
|
||||
"build/out/sudoers/"
|
||||
],
|
||||
"runenv": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"TERM=tmux",
|
||||
"LANG=en_US.UTF-8",
|
||||
"MAIL=/var/mail/root",
|
||||
"LOGNAME=root",
|
||||
"USER=root",
|
||||
"HOME=/root",
|
||||
"SHELL=/bin/bash",
|
||||
"SUDO_COMMAND=/usr/bin/find build/out/sudoers/",
|
||||
"SUDO_USER=millert",
|
||||
"SUDO_UID=8036",
|
||||
"SUDO_GID=20"
|
||||
]
|
||||
}
|
2
lib/eventlog/regress/eventlog_store/test3.sudo.out.ok
Normal file
2
lib/eventlog/regress/eventlog_store/test3.sudo.out.ok
Normal file
@@ -0,0 +1,2 @@
|
||||
HOST=linux-build ; TTY=pts/1 ; CWD=/home/millert/sudo/oss-fuzz ; USER=root ; TSID=00005H ; COMMAND=/usr/bin/find build/out/sudoers/
|
||||
HOST=linux-build ; TTY=pts/1 ; CWD=/home/millert/sudo/oss-fuzz ; USER=root ; TSID=00005H ; COMMAND=/usr/bin/find build/out/sudoers/ ; SIGNAL=QUIT ; EXIT=131
|
46
lib/eventlog/regress/eventlog_store/test4.json.in
Normal file
46
lib/eventlog/regress/eventlog_store/test4.json.in
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"uuid": "0bf9f26a7c-5e8b-4f82-f6c1-24a49a254c",
|
||||
"server_time": {
|
||||
"seconds": 1677638637,
|
||||
"nanoseconds": 369091862,
|
||||
"iso8601": "20230301024357Z",
|
||||
"localtime": "Tue Feb 28 19:43:57 MST 2023"
|
||||
},
|
||||
"submit_time": {
|
||||
"seconds": 1677638637,
|
||||
"nanoseconds": 364571747,
|
||||
"iso8601": "20230301024357Z",
|
||||
"localtime": "Tue Feb 28 19:43:57 MST 2023"
|
||||
},
|
||||
"peeraddr": "172.30.200.2",
|
||||
"iolog_path": "/var/log/sudo-logsrvd/millert/00/03/FG",
|
||||
"iolog_file": "00/03/FG",
|
||||
"columns": 80,
|
||||
"command": "/usr/bin/vi",
|
||||
"lines": 24,
|
||||
"runargv": [
|
||||
"vi",
|
||||
"aliases"
|
||||
],
|
||||
"runenv": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"TERM=tmux",
|
||||
"LANG=en_US.UTF-8",
|
||||
"MAIL=/var/mail/root",
|
||||
"LOGNAME=root",
|
||||
"USER=root",
|
||||
"HOME=/root",
|
||||
"SHELL=/bin/bash",
|
||||
"SUDO_COMMAND=/usr/bin/vi aliases",
|
||||
"SUDO_USER=millert",
|
||||
"SUDO_UID=8036",
|
||||
"SUDO_GID=20",
|
||||
"KRB5CCNAME=bogus"
|
||||
],
|
||||
"runuid": 0,
|
||||
"runuser": "root",
|
||||
"submitcwd": "/etc/mail",
|
||||
"submithost": "xerxes.sudo.ws",
|
||||
"submituser": "millert",
|
||||
"ttyname": "/dev/ttypb"
|
||||
}
|
30
lib/eventlog/regress/eventlog_store/test4.json.out.ok
Normal file
30
lib/eventlog/regress/eventlog_store/test4.json.out.ok
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"submituser": "millert",
|
||||
"command": "/usr/bin/vi",
|
||||
"runuser": "root",
|
||||
"ttyname": "/dev/ttypb",
|
||||
"submithost": "xerxes.sudo.ws",
|
||||
"submitcwd": "/etc/mail",
|
||||
"runuid": 0,
|
||||
"columns": 80,
|
||||
"lines": 24,
|
||||
"runargv": [
|
||||
"vi",
|
||||
"aliases"
|
||||
],
|
||||
"runenv": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"TERM=tmux",
|
||||
"LANG=en_US.UTF-8",
|
||||
"MAIL=/var/mail/root",
|
||||
"LOGNAME=root",
|
||||
"USER=root",
|
||||
"HOME=/root",
|
||||
"SHELL=/bin/bash",
|
||||
"SUDO_COMMAND=/usr/bin/vi aliases",
|
||||
"SUDO_USER=millert",
|
||||
"SUDO_UID=8036",
|
||||
"SUDO_GID=20",
|
||||
"KRB5CCNAME=bogus"
|
||||
]
|
||||
}
|
2
lib/eventlog/regress/eventlog_store/test4.sudo.out.ok
Normal file
2
lib/eventlog/regress/eventlog_store/test4.sudo.out.ok
Normal file
@@ -0,0 +1,2 @@
|
||||
HOST=xerxes.sudo.ws ; TTY=ttypb ; CWD=/etc/mail ; USER=root ; TSID=0003FG ; COMMAND=/usr/bin/vi aliases
|
||||
HOST=xerxes.sudo.ws ; TTY=ttypb ; CWD=/etc/mail ; USER=root ; TSID=0003FG ; COMMAND=/usr/bin/vi aliases ; EXIT=0
|
@@ -124,7 +124,7 @@ done:
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-c] input_file ...\n",
|
||||
fprintf(stderr, "usage: %s [-cv] input_file ...\n",
|
||||
getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -176,11 +176,14 @@ main(int argc, char *argv[])
|
||||
|
||||
initprogname(argc > 0 ? argv[0] : "check_parse_json");
|
||||
|
||||
while ((ch = getopt(argc, argv, "c")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "cv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
cat = true;
|
||||
break;
|
||||
case 'v':
|
||||
/* ignored */
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
@@ -258,8 +261,8 @@ next:
|
||||
}
|
||||
|
||||
if (ntests != 0) {
|
||||
printf("iolog_json: %d test%s run, %d errors, %d%% success rate\n",
|
||||
ntests, ntests == 1 ? "" : "s", errors,
|
||||
printf("%s: %d test%s run, %d errors, %d%% success rate\n",
|
||||
getprogname(), ntests, ntests == 1 ? "" : "s", errors,
|
||||
(ntests - errors) * 100 / ntests);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user