diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 02:23:56 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 02:23:56 +0000 |
commit | 9620f76a210d9d8c1aaff25e99d6dc513f87e6e9 (patch) | |
tree | ceecc90fb95780872c35da764c5163f38e4727c4 /plugins/sudoers/regress/parser | |
parent | Initial commit. (diff) | |
download | sudo-upstream.tar.xz sudo-upstream.zip |
Adding upstream version 1.8.27.upstream/1.8.27upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/sudoers/regress/parser')
-rw-r--r-- | plugins/sudoers/regress/parser/check_addr.c | 145 | ||||
-rw-r--r-- | plugins/sudoers/regress/parser/check_addr.in | 13 | ||||
-rw-r--r-- | plugins/sudoers/regress/parser/check_base64.c | 123 | ||||
-rw-r--r-- | plugins/sudoers/regress/parser/check_digest.c | 140 | ||||
-rw-r--r-- | plugins/sudoers/regress/parser/check_digest.out.ok | 36 | ||||
-rw-r--r-- | plugins/sudoers/regress/parser/check_fill.c | 194 | ||||
-rw-r--r-- | plugins/sudoers/regress/parser/check_gentime.c | 87 | ||||
-rw-r--r-- | plugins/sudoers/regress/parser/check_hexchar.c | 90 |
8 files changed, 828 insertions, 0 deletions
diff --git a/plugins/sudoers/regress/parser/check_addr.c b/plugins/sudoers/regress/parser/check_addr.c new file mode 100644 index 0000000..5f67d4d --- /dev/null +++ b/plugins/sudoers/regress/parser/check_addr.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2011-2013 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 <sys/types.h> +#include <sys/socket.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <ctype.h> +#include <errno.h> +#include <grp.h> +#include <pwd.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#define SUDO_ERROR_WRAP 0 + +#include "sudoers.h" +#include "interfaces.h" + +__dso_public int main(int argc, char *argv[]); + +static int +check_addr(char *input) +{ + int expected, matched; + const char *errstr; + size_t len; + char *cp; + + while (isspace((unsigned char)*input)) + input++; + + /* input: "addr[/mask] 1/0" */ + len = strcspn(input, " \t"); + cp = input + len; + while (isspace((unsigned char)*cp)) + cp++; + expected = strtonum(cp, 0, 1, &errstr); + if (errstr != NULL) + sudo_fatalx("expecting 0 or 1, got %s", cp); + input[len] = '\0'; + + matched = addr_matches(input); + if (matched != expected) { + sudo_warnx("%s %smatched: FAIL", input, matched ? "" : "not "); + return 1; + } + return 0; +} + +static void +usage(void) +{ + fprintf(stderr, "usage: %s datafile\n", getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int ntests = 0, errors = 0; + char *cp, line[2048]; + size_t len; + FILE *fp; + + initprogname(argc > 0 ? argv[0] : "check_addr"); + + if (argc != 2) + usage(); + + fp = fopen(argv[1], "r"); + if (fp == NULL) + sudo_fatalx("unable to open %s", argv[1]); + + /* + * Input is in the following format. There are two types of + * lines: interfaces, which sets the address and mask of the + * locally connected ethernet interfaces for the lines that + * follow and, address lines that include and address (with + * optional netmask) to match, followed by expected match status + * (1 or 0). E.g. + * + * interfaces: addr1/mask addr2/mask ... + * address: addr[/mask] 1/0 + * address: addr[/mask] 1/0 + * interfaces: addr3/mask addr4/mask ... + * address: addr[/mask] 1/0 + */ + + while (fgets(line, sizeof(line), fp) != NULL) { + len = strcspn(line, "\n"); + line[len] = '\0'; + + /* Ignore comments */ + if ((cp = strchr(line, '#')) != NULL) + *cp = '\0'; + + /* Skip blank lines. */ + if (line[0] == '\0') + continue; + + if (strncmp(line, "interfaces:", sizeof("interfaces:") - 1) == 0) { + if (!set_interfaces(line + sizeof("interfaces:") - 1)) { + sudo_warn("unable to parse interfaces list"); + errors++; + } + } else if (strncmp(line, "address:", sizeof("address:") - 1) == 0) { + errors += check_addr(line + sizeof("address:") - 1); + ntests++; + } else { + sudo_warnx("unexpected data line: %s\n", line); + continue; + } + } + + if (ntests != 0) { + printf("check_addr: %d tests run, %d errors, %d%% success rate\n", + ntests, errors, (ntests - errors) * 100 / ntests); + } + + exit(errors); +} diff --git a/plugins/sudoers/regress/parser/check_addr.in b/plugins/sudoers/regress/parser/check_addr.in new file mode 100644 index 0000000..a3c8612 --- /dev/null +++ b/plugins/sudoers/regress/parser/check_addr.in @@ -0,0 +1,13 @@ +# +interfaces: 10.5.54.73/255.255.240.0 +address: 10.5.48.0 1 +address: 10.5.54.0/20 1 +# +interfaces: 128.138.243.151/255.255.255.0 128.138.241.53/255.255.255.0 +address: 128.138.243.0 1 +address: 128.138.243.0/24 1 +address: 128.138.241.0 1 +address: 128.138.241.0/24 1 +address: 128.138.242.0/24 0 +address: 128.138.0.0 0 +address: 128.138.0.0/16 1 diff --git a/plugins/sudoers/regress/parser/check_base64.c b/plugins/sudoers/regress/parser/check_base64.c new file mode 100644 index 0000000..a3f28e0 --- /dev/null +++ b/plugins/sudoers/regress/parser/check_base64.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2018 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 <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_STDINT_H) +# include <stdint.h> +#elif defined(HAVE_INTTYPES_H) +# include <inttypes.h> +#endif + +#define SUDO_ERROR_WRAP 0 + +#include "sudo_compat.h" +#include "sudo_util.h" + +/* From parse.h */ +extern size_t base64_decode(const char *str, unsigned char *dst, size_t dsize); +extern size_t base64_encode(const unsigned char *in, size_t in_len, char *out, size_t out_len); + +__dso_public int main(int argc, char *argv[]); + +static unsigned char bstring1[] = { 0xea, 0xb8, 0xa2, 0x71, 0xef, 0x67, 0xc1, 0xcd, 0x0d, 0xd9, 0xa6, 0xaa, 0xa8, 0x24, 0x77, 0x2a, 0xfc, 0x6f, 0x76, 0x37, 0x1b, 0xed, 0x9e, 0x1a, 0x90, 0x5f, 0xcf, 0xbc, 0x00 }; + +struct base64_test { + const char *ascii; + const char *encoded; +} test_strings[] = { + { + (char *)bstring1, + "6riice9nwc0N2aaqqCR3Kvxvdjcb7Z4akF/PvA==" + }, + { + "any carnal pleasure.", + "YW55IGNhcm5hbCBwbGVhc3VyZS4=" + }, + { + "any carnal pleasure", + "YW55IGNhcm5hbCBwbGVhc3VyZQ==" + }, + { + "any carnal pleasur", + "YW55IGNhcm5hbCBwbGVhc3Vy" + }, + { + "any carnal pleasu", + "YW55IGNhcm5hbCBwbGVhc3U=" + }, + { + "any carnal pleas", + "YW55IGNhcm5hbCBwbGVhcw==" + } +}; + +int +main(int argc, char *argv[]) +{ + int ntests = nitems(test_strings); + int i, errors = 0; + unsigned char buf[64]; + size_t len; + + initprogname(argc > 0 ? argv[0] : "check_base64"); + + for (i = 0; i < ntests; i++) { + /* Test decode. */ + len = base64_decode(test_strings[i].encoded, buf, sizeof(buf)); + if (len == (size_t)-1) { + fprintf(stderr, "check_base64: failed to decode %s\n", + test_strings[i].encoded); + errors++; + } else { + buf[len] = '\0'; + if (strcmp(test_strings[i].ascii, (char *)buf) != 0) { + fprintf(stderr, "check_base64: expected %s, got %s\n", + test_strings[i].ascii, buf); + errors++; + } + } + + /* Test encode. */ + len = base64_encode((unsigned char *)test_strings[i].ascii, + strlen(test_strings[i].ascii), (char *)buf, sizeof(buf)); + if (len == (size_t)-1) { + fprintf(stderr, "check_base64: failed to encode %s\n", + test_strings[i].ascii); + errors++; + } else { + if (strcmp(test_strings[i].encoded, (char *)buf) != 0) { + fprintf(stderr, "check_base64: expected %s, got %s\n", + test_strings[i].encoded, buf); + errors++; + } + } + } + ntests *= 2; /* we test in both directions */ + + printf("check_base64: %d tests run, %d errors, %d%% success rate\n", + ntests, errors, (ntests - errors) * 100 / ntests); + exit(errors); +} diff --git a/plugins/sudoers/regress/parser/check_digest.c b/plugins/sudoers/regress/parser/check_digest.c new file mode 100644 index 0000000..0d49a35 --- /dev/null +++ b/plugins/sudoers/regress/parser/check_digest.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2015 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 <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_STDINT_H) +# include <stdint.h> +#elif defined(HAVE_INTTYPES_H) +# include <inttypes.h> +#endif +#ifdef HAVE_STDBOOL_H +# include <stdbool.h> +#else +# include "compat/stdbool.h" +#endif /* HAVE_STDBOOL_H */ +#include <limits.h> +#include <unistd.h> + +#include "sudo_compat.h" +#include "sudo_fatal.h" +#include "sudo_queue.h" +#include "sudo_digest.h" +#include "sudo_util.h" +#include "parse.h" + +__dso_public int main(int argc, char *argv[]); + +#define NUM_TESTS 8 +static const char *test_strings[NUM_TESTS] = { + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789" + "012345678901234567890", +}; + +static unsigned char * +check_digest(int digest_type, const char *buf, size_t buflen, size_t *digest_len) +{ + char tfile[] = "digest.XXXXXX"; + unsigned char *digest = NULL; + int tfd; + + /* Write test data to temporary file. */ + tfd = mkstemp(tfile); + if (tfd == -1) { + sudo_warn_nodebug("mkstemp"); + goto done; + } + if ((size_t)write(tfd, buf, buflen) != buflen) { + sudo_warn_nodebug("write"); + goto done; + } + lseek(tfd, 0, SEEK_SET); + + /* Get file digest. */ + digest = sudo_filedigest(tfd, tfile, digest_type, digest_len); + if (digest == NULL) { + /* Warning (if any) printed by sudo_filedigest() */ + goto done; + } +done: + if (tfd != -1) { + close(tfd); + unlink(tfile); + } + return digest; +} + +int +main(int argc, char *argv[]) +{ + static const char hex[] = "0123456789abcdef"; + char buf[1000 * 1000]; + unsigned char *digest; + unsigned int i, j; + size_t digest_len; + int digest_type; + + initprogname(argc > 0 ? argv[0] : "check_digest"); + + for (digest_type = 0; digest_type < SUDO_DIGEST_INVALID; digest_type++) { + for (i = 0; i < NUM_TESTS; i++) { + digest = check_digest(digest_type, test_strings[i], + strlen(test_strings[i]), &digest_len); + if (digest != NULL) { + printf("%s (\"%s\") = ", digest_type_to_name(digest_type), + test_strings[i]); + for (j = 0; j < digest_len; j++) { + putchar(hex[digest[j] >> 4]); + putchar(hex[digest[j] & 0x0f]); + } + putchar('\n'); + free(digest); + } + } + + /* Simulate a string of a million 'a' characters. */ + memset(buf, 'a', sizeof(buf)); + digest = check_digest(digest_type, buf, sizeof(buf), &digest_len); + if (digest != NULL) { + printf("%s (one million 'a' characters) = ", + digest_type_to_name(digest_type)); + for (j = 0; j < digest_len; j++) { + putchar(hex[digest[j] >> 4]); + putchar(hex[digest[j] & 0x0f]); + } + putchar('\n'); + free(digest); + } + } + + return 0; +} diff --git a/plugins/sudoers/regress/parser/check_digest.out.ok b/plugins/sudoers/regress/parser/check_digest.out.ok new file mode 100644 index 0000000..a353664 --- /dev/null +++ b/plugins/sudoers/regress/parser/check_digest.out.ok @@ -0,0 +1,36 @@ +sha224 ("") = d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f +sha224 ("a") = abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5 +sha224 ("abc") = 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7 +sha224 ("message digest") = 2cb21c83ae2f004de7e81c3c7019cbcb65b71ab656b22d6d0c39b8eb +sha224 ("abcdefghijklmnopqrstuvwxyz") = 45a5f72c39c5cff2522eb3429799e49e5f44b356ef926bcf390dccc2 +sha224 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525 +sha224 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = bff72b4fcb7d75e5632900ac5f90d219e05e97a7bde72e740db393d9 +sha224 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e +sha224 (one million 'a' characters) = 20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67 +sha256 ("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256 ("a") = ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb +sha256 ("abc") = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad +sha256 ("message digest") = f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650 +sha256 ("abcdefghijklmnopqrstuvwxyz") = 71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73 +sha256 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1 +sha256 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0 +sha256 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e +sha256 (one million 'a' characters) = cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0 +sha384 ("") = 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b +sha384 ("a") = 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31 +sha384 ("abc") = cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7 +sha384 ("message digest") = 473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5 +sha384 ("abcdefghijklmnopqrstuvwxyz") = feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4 +sha384 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b +sha384 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84 +sha384 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026 +sha384 (one million 'a' characters) = 9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985 +sha512 ("") = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e +sha512 ("a") = 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75 +sha512 ("abc") = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f +sha512 ("message digest") = 107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c +sha512 ("abcdefghijklmnopqrstuvwxyz") = 4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1 +sha512 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445 +sha512 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894 +sha512 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843 +sha512 (one million 'a' characters) = e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b diff --git a/plugins/sudoers/regress/parser/check_fill.c b/plugins/sudoers/regress/parser/check_fill.c new file mode 100644 index 0000000..e0312b6 --- /dev/null +++ b/plugins/sudoers/regress/parser/check_fill.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2011-2016 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 <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_STDBOOL_H +# include <stdbool.h> +#else +# include "compat/stdbool.h" +#endif /* HAVE_STDBOOL_H */ +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <grp.h> +#include <pwd.h> + +#define SUDO_ERROR_WRAP 0 + +#include "sudo_compat.h" +#include "sudo_queue.h" +#include "parse.h" +#include "toke.h" +#include "sudo_plugin.h" +#include "sudo_util.h" +#include <gram.h> + +__dso_public int main(int argc, char *argv[]); + +/* + * TODO: test realloc + */ + +YYSTYPE sudoerslval; + +struct fill_test { + const char *input; + const char *output; + int len; + int addspace; +}; + +/* + * In "normal" fill, anything can be escaped and hex chars are expanded. + */ +static struct fill_test txt_data[] = { + { "Embedded\\x20Space", "Embedded Space", 0 }, + { "\\x20Leading", " Leading", 0 }, + { "Trailing\\x20", "Trailing ", 0 }, + { "Multiple\\x20\\x20Spaces", "Multiple Spaces", 0 }, + { "Hexparse\\x200Check", "Hexparse 0Check", 0 }, + { "Escaped\\\\Escape", "Escaped\\Escape", 0 }, + { "LongGroupName", "LongGrou", 8 } +}; + +/* + * The only escaped chars in a command should be [,:= \t#] + * The rest are done by glob() or fnmatch(). + */ +static struct fill_test cmd_data[] = { + { "foo\\,bar", "foo,bar", 0 }, + { "this\\:that", "this:that", 0 }, + { "foo\\=bar", "foo=bar", 0 }, + { "tab\\\tstop", "tab\tstop", 0 }, + { "not a \\#comment", "not a #comment", 0 } +}; + +/* + * No escaped characters in command line args. + * Arguments get appended. + */ +static struct fill_test args_data[] = { + { "/", "/", 0, 0 }, + { "-type", "/ -type", 0, 1 }, + { "f", "/ -type f", 0, 1 }, + { "-exec", "/ -type f -exec", 0, 1 }, + { "ls", "/ -type f -exec ls", 0, 1 }, + { "{}", "/ -type f -exec ls {}", 0, 1 } +}; + +static int +check_fill(const char *input, int len, int addspace, const char *expect, char **resultp) +{ + if (sudoerslval.string != NULL) { + free(sudoerslval.string); + sudoerslval.string = NULL; + } + if (!fill(input, len)) + return -1; + *resultp = sudoerslval.string; + return !strcmp(sudoerslval.string, expect); +} + +static int +check_fill_cmnd(const char *input, int len, int addspace, const char *expect, char **resultp) +{ + if (sudoerslval.command.cmnd != NULL) { + free(sudoerslval.command.cmnd); + sudoerslval.command.cmnd = NULL; + } + if (!fill_cmnd(input, len)) + return -1; + *resultp = sudoerslval.command.cmnd; + return !strcmp(sudoerslval.command.cmnd, expect); +} + +static int +check_fill_args(const char *input, int len, int addspace, const char *expect, char **resultp) +{ + /* Must not free old sudoerslval.command.args as gets appended to. */ + if (!fill_args(input, len, addspace)) + return -1; + *resultp = sudoerslval.command.args; + return !strcmp(sudoerslval.command.args, expect); +} + +static int +do_tests(int (*checker)(const char *, int, int, const char *, char **), + struct fill_test *data, size_t ntests) +{ + int len, errors = 0; + unsigned int i; + char *result; + + for (i = 0; i < ntests; i++) { + if (data[i].len == 0) + len = strlen(data[i].input); + else + len = data[i].len; + + switch ((*checker)(data[i].input, len, data[i].addspace, data[i].output, &result)) { + case 0: + /* no match */ + fprintf(stderr, "Failed parsing %.*s: expected [%s], got [%s]\n", + (int)data[i].len, data[i].input, data[i].output, result); + errors++; + break; + case 1: + /* match */ + break; + default: + /* error */ + fprintf(stderr, "Failed parsing %.*s: fill function failure\n", + (int)data[i].len, data[i].input); + errors++; + break; + } + } + + return errors; +} + +int +main(int argc, char *argv[]) +{ + int ntests, errors = 0; + + initprogname(argc > 0 ? argv[0] : "check_fill"); + + errors += do_tests(check_fill, txt_data, nitems(txt_data)); + errors += do_tests(check_fill_cmnd, cmd_data, nitems(cmd_data)); + errors += do_tests(check_fill_args, args_data, nitems(args_data)); + + ntests = nitems(txt_data) + nitems(cmd_data) + nitems(args_data); + printf("%s: %d tests run, %d errors, %d%% success rate\n", getprogname(), + ntests, errors, (ntests - errors) * 100 / ntests); + + exit(errors); +} + +/* STUB */ +void +sudoerserror(const char *s) +{ + return; +} diff --git a/plugins/sudoers/regress/parser/check_gentime.c b/plugins/sudoers/regress/parser/check_gentime.c new file mode 100644 index 0000000..957ea4c --- /dev/null +++ b/plugins/sudoers/regress/parser/check_gentime.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017 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 <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#include <time.h> + +#define SUDO_ERROR_WRAP 0 + +#include "sudo_compat.h" +#include "sudo_util.h" +#include "sudoers_debug.h" +#include "parse.h" + +__dso_public int main(int argc, char *argv[]); + +const struct gentime_test { + char *gentime; + time_t unixtime; +} tests[] = { + { "199412161032ZZ", -1 }, + { "199412161032Z", 787573920 }, + { "199412160532-0500", 787573920 }, + { "199412160532-05000", -1 }, + { "199412160532", 787573920 }, /* local time is EST */ + { "20170214083000-0500", 1487079000 }, + { "201702140830-0500", 1487079000 }, + { "201702140830", 1487079000 }, /* local time is EST */ + { "201702140830.3-0500", 1487079018 }, + { "201702140830,3-0500", 1487079018 }, + { "20170214083000.5Z", 1487061000 }, + { "20170214083000,5Z", 1487061000 }, + { "201702142359.4Z", 1487116764 }, + { "201702142359,4Z", 1487116764 }, + { "2017021408.5Z", 1487061000 }, + { "2017021408,5Z", 1487061000 }, + { "20170214Z", -1 }, +}; + +int +main(int argc, char *argv[]) +{ + const int ntests = nitems(tests); + int i, errors = 0; + time_t result; + + initprogname(argc > 0 ? argv[0] : "check_gentime"); + + /* Do local time tests in Eastern Standard Time. */ + putenv("TZ=EST5EST5"); + tzset(); + + for (i = 0; i < ntests; i++) { + result = parse_gentime(tests[i].gentime); + if (result != tests[i].unixtime) { + fprintf(stderr, "check_gentime[%d]: %s: expected %lld, got %lld\n", + i, tests[i].gentime, + (long long)tests[i].unixtime, (long long)result); + errors++; + } + } + printf("check_gentime: %d tests run, %d errors, %d%% success rate\n", + ntests, errors, (ntests - errors) * 100 / ntests); + exit(errors); +} diff --git a/plugins/sudoers/regress/parser/check_hexchar.c b/plugins/sudoers/regress/parser/check_hexchar.c new file mode 100644 index 0000000..d4f9657 --- /dev/null +++ b/plugins/sudoers/regress/parser/check_hexchar.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014-2015 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 <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_STRING_H +# include <string.h> +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif /* HAVE_STRINGS_H */ +#if defined(HAVE_STDINT_H) +# include <stdint.h> +#elif defined(HAVE_INTTYPES_H) +# include <inttypes.h> +#endif + +#define SUDO_ERROR_WRAP 0 + +#include "sudo_compat.h" +#include "sudo_util.h" + +int hexchar(const char *s); + +__dso_public int main(int argc, char *argv[]); + +struct hexchar_test { + char hex[3]; + int value; +}; + +int +main(int argc, char *argv[]) +{ + struct hexchar_test *test_data; + int i, ntests, result, errors = 0; + static const char xdigs_lower[] = "0123456789abcdef"; + static const char xdigs_upper[] = "0123456789ABCDEF"; + + initprogname(argc > 0 ? argv[0] : "check_hexchar"); + + /* Build up test data. */ + ntests = 256 + 256 + 3; + test_data = calloc(sizeof(*test_data), ntests); + for (i = 0; i < 256; i++) { + /* lower case */ + test_data[i].value = i; + test_data[i].hex[1] = xdigs_lower[ (i & 0x0f)]; + test_data[i].hex[0] = xdigs_lower[((i & 0xf0) >> 4)]; + /* upper case */ + test_data[i + 256].value = i; + test_data[i + 256].hex[1] = xdigs_upper[ (i & 0x0f)]; + test_data[i + 256].hex[0] = xdigs_upper[((i & 0xf0) >> 4)]; + } + /* Also test invalid data */ + test_data[ntests - 3].hex[0] = '\0'; + test_data[ntests - 3].value = -1; + strlcpy(test_data[ntests - 2].hex, "AG", sizeof(test_data[ntests - 2].hex)); + test_data[ntests - 2].value = -1; + strlcpy(test_data[ntests - 1].hex, "-1", sizeof(test_data[ntests - 1].hex)); + test_data[ntests - 1].value = -1; + + for (i = 0; i < ntests; i++) { + result = hexchar(test_data[i].hex); + if (result != test_data[i].value) { + fprintf(stderr, "check_hexchar: expected %d, got %d\n", + test_data[i].value, result); + errors++; + } + } + printf("check_hexchar: %d tests run, %d errors, %d%% success rate\n", + ntests, errors, (ntests - errors) * 100 / ntests); + exit(errors); +} |