diff --git a/.luacheckrc b/.luacheckrc index 29e59a28e9edbde7acda7cba4852009b0214a69b..a6a3210868879005af1db100a6ab9a12a478ad69 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -76,4 +76,4 @@ files['daemon/lua/kres-gen.lua'].ignore = {'631'} -- Allow overly long lines -- Tests and scripts can use global variables files['scripts'].ignore = {'111', '112', '113'} files['tests'].ignore = {'111', '112', '113'} -files['modules/*/*_test.lua'].ignore = {'111', '112', '113', '122'} \ No newline at end of file +files['modules/**/*.test.lua'].ignore = {'111', '112', '113', '122'} diff --git a/config.mk b/config.mk index 0023b4b5cbc1a3904d57f78de08a0a84fed26fca..00dd3805c9ad67f08b01194db9d1ddcd02896233 100644 --- a/config.mk +++ b/config.mk @@ -23,6 +23,7 @@ ROOTHINTS ?= $(ETCDIR)/root.hints COVERAGE_STAGE ?= gcov COVERAGE_STATSDIR ?= $(CURDIR)/coverage.stats TOPSRCDIR := $(CURDIR) +KEYFILE_DEFAULT ?= # Tools CC ?= cc diff --git a/daemon/README.rst b/daemon/README.rst index c7979012231767c2bfcad273ea39db7ff5510979..c3dc6e3179e1b24f91d8b458e64327a5a8fc19f6 100644 --- a/daemon/README.rst +++ b/daemon/README.rst @@ -22,9 +22,12 @@ To enable it, you need to provide trusted root keys. Bootstrapping of the keys i $ kresd -k root-new.keys # File for root keys [ ta ] keyfile 'root-new.keys': doesn't exist, bootstrapping [ ta ] Root trust anchors bootstrapped over https with pinned certificate. - You may want to verify them manually, as described on: - https://data.iana.org/root-anchors/old/draft-icann-dnssec-trust-anchor.html#sigs - [ ta ] next refresh for . in 23.912361111111 hours + You SHOULD verify them manually against original source: + https://www.iana.org/dnssec/files + [ ta ] Current root trust anchors are: + . 0 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 + . 0 IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D + [ ta ] next refresh for . in 24 hours Alternatively, you can set it in configuration file with ``trust_anchors.file = 'root.keys'``. If the file doesn't exist, it will be automatically populated with root keys validated using root anchors retrieved over HTTPS. @@ -58,6 +61,8 @@ The root anchors bootstrap may fail for various reasons, in this case you need t You've just enabled DNSSEC! +.. note:: Bootstrapping and automatic update need write access to keyfile direcory. If you want to manage root anchors manually you should use ``trust_anchors.add_file('root.keys', true)``. + CLI interface ============= diff --git a/daemon/daemon.mk b/daemon/daemon.mk index a455c2c25386a21d2aa532f82fa389deb9d600c9..cf28be0ff010c8e11a22bea21914d6454ef93962 100644 --- a/daemon/daemon.mk +++ b/daemon/daemon.mk @@ -56,6 +56,7 @@ daemon-install: kresd-install bindings-install ifneq ($(SED),) $(SED) -e "s/@VERSION@/$(VERSION)/" -e "s/@DATE@/$(date)/" \ -e "s|@MODULEDIR@|$(MODULEDIR)|" \ + -e "s|@KEYFILE_DEFAULT@|$(KEYFILE_DEFAULT)|" \ doc/kresd.8.in > doc/kresd.8 $(INSTALL) -d -m 0755 $(DESTDIR)$(MANDIR)/man8/ $(INSTALL) -m 0644 doc/kresd.8 $(DESTDIR)$(MANDIR)/man8/ @@ -65,7 +66,7 @@ daemon-clean: kresd-clean daemon/lua/zonefile.lua daemon/lua/trust_anchors.lua: daemon/lua/trust_anchors.lua.in - @$(call quiet,SED,$<) -e "s|@ETCDIR@|$(ETCDIR)|g" $< > $@ + @$(call quiet,SED,$<) -e "s|@ETCDIR@|$(ETCDIR)|g;s|@KEYFILE_DEFAULT@|$(KEYFILE_DEFAULT)|g" $< > $@ LIBZSCANNER_COMMENTS := \ $(shell pkg-config libzscanner --atleast-version=2.4.2 && echo true || echo false) diff --git a/daemon/engine.c b/daemon/engine.c index 8eb782442a533abe6c80a8b20bc7133ca294594e..b7e69db7bc5155500a35b55ecaf59d9a181dbedf 100644 --- a/daemon/engine.c +++ b/daemon/engine.c @@ -812,9 +812,8 @@ int engine_ipc(struct engine *engine, const char *expr) } } -static int engine_loadconf(struct engine *engine, const char *config_path) +int engine_load_sandbox(struct engine *engine) { - int ret = 0; /* Init environment */ static const char sandbox_bytecode[] = { #include "daemon/lua/sandbox.inc" @@ -824,22 +823,13 @@ static int engine_loadconf(struct engine *engine, const char *config_path) lua_pop(engine->L, 1); return kr_error(ENOEXEC); } - /* Load config file */ - if (config_path) { - if (strcmp(config_path, "-") == 0) { - return ret; /* No config and no defaults. */ - } - ret = l_dosandboxfile(engine->L, config_path); - } - if (ret == 0) { - /* Load defaults */ - static const char config_bytecode[] = { - #include "daemon/lua/config.inc" - }; - ret = l_dobytecode(engine->L, config_bytecode, sizeof(config_bytecode), "config"); - } + return kr_ok(); +} - /* Evaluate */ +int engine_loadconf(struct engine *engine, const char *config_path) +{ + assert(config_path != NULL); + int ret = l_dosandboxfile(engine->L, config_path); if (ret != 0) { fprintf(stderr, "%s\n", lua_tostring(engine->L, -1)); lua_pop(engine->L, 1); @@ -847,14 +837,22 @@ static int engine_loadconf(struct engine *engine, const char *config_path) return ret; } -int engine_start(struct engine *engine, const char *config_path) +int engine_load_defaults(struct engine *engine) { - /* Load configuration. */ - int ret = engine_loadconf(engine, config_path); + /* Load defaults */ + static const char config_bytecode[] = { + #include "daemon/lua/config.inc" + }; + int ret = l_dobytecode(engine->L, config_bytecode, sizeof(config_bytecode), "config"); if (ret != 0) { - return ret; + fprintf(stderr, "%s\n", lua_tostring(engine->L, -1)); + lua_pop(engine->L, 1); } + return ret; +} +int engine_start(struct engine *engine) +{ /* Clean up stack and restart GC */ lua_settop(engine->L, 0); lua_gc(engine->L, LUA_GCCOLLECT, 0); diff --git a/daemon/engine.h b/daemon/engine.h index 25ee30a124602895f241313b20b423e21660cf92..dea87c118d6e1a6cce9dec4b7a261cc32afbe479 100644 --- a/daemon/engine.h +++ b/daemon/engine.h @@ -83,12 +83,13 @@ int engine_pcall(struct lua_State *L, int argc); int engine_ipc(struct engine *engine, const char *expr); -/** Start the lua engine and execute the config. - * - * @note Special path "-" means that even default config won't be done - * (like listening on localhost). - */ -int engine_start(struct engine *engine, const char *config_path); + +int engine_load_sandbox(struct engine *engine); +int engine_loadconf(struct engine *engine, const char *config_path); +int engine_load_defaults(struct engine *engine); + +/** Start the lua engine and execute the config. */ +int engine_start(struct engine *engine); void engine_stop(struct engine *engine); int engine_register(struct engine *engine, const char *name, const char *precedence, const char* ref); int engine_unregister(struct engine *engine, const char *name); diff --git a/daemon/lua/config.lua b/daemon/lua/config.lua index cc6e2f2f23afbc2a75066c3881024dfa44068761..7abf181845cad1a975e6e8c1d7633b3806dbeaf9 100644 --- a/daemon/lua/config.lua +++ b/daemon/lua/config.lua @@ -18,3 +18,13 @@ end if kres.context().root_hints.nsset.root == nil then _hint_root_file() end + +if not trust_anchors.keysets['\0'] and trust_anchors.keyfile_default then + if io.open(trust_anchors.keyfile_default, 'r') then + trust_anchors.config(trust_anchors.keyfile_default, true) + else + panic("cannot open default trust anchor file:'%s'", + trust_anchors.keyfile_default + ) + end +end diff --git a/daemon/lua/trust_anchors.lua.in b/daemon/lua/trust_anchors.lua.in index d21a34d2c95648ae40216f8206f8568281e1ee5c..7c9e27dad61be687dbbd09132a459368d5457aad 100644 --- a/daemon/lua/trust_anchors.lua.in +++ b/daemon/lua/trust_anchors.lua.in @@ -42,8 +42,10 @@ local function bootstrap(url, ca) return false, string.format('[ ta ] failed to get any record from "%s"', url) end local msg = '[ ta ] Root trust anchors bootstrapped over https with pinned certificate.\n' - .. ' You may want to verify them manually, as described on:\n' - .. ' https://data.iana.org/root-anchors/old/draft-icann-dnssec-trust-anchor.html#sigs' + .. ' You SHOULD verify them manually against original source:\n' + .. ' https://www.iana.org/dnssec/files\n' + .. '[ ta ] Current root trust anchors are:' + .. rr return rr, msg end @@ -367,9 +369,16 @@ update = function (keyset, new_keys, is_initial) end local add_file = function (path, unmanaged) - -- Bootstrap if requested and keyfile doesn't exist + if not unmanaged then + if not io.open(path .. '.lock', 'w') then + error("[ ta ] ERROR: write access needed to keyfile dir '"..path.."'") + end + os.remove(path .. ".lock") + end + -- Bootstrap if requested and keyfile doesn't exist if not unmanaged and not io.open(path, 'r') then + log("[ ta ] keyfile '%s': doesn't exist, bootstrapping", path); local tas, msg = bootstrap(trust_anchors.bootstrap_url, trust_anchors.bootstrap_ca) if not tas then msg = msg .. '\n' @@ -395,13 +404,14 @@ local add_file = function (path, unmanaged) -- Parse the file and check its sanity local keyset, err = keyset_read(path) - if not unmanaged then keyset.filename = path end if not keyset then panic("[ ta ] ERROR: failed to read anchors from '%s' (%s)", path, err) end + if not unmanaged then keyset.filename = path end if not keyset[1] then panic("[ ta ] ERROR: failed to read anchors from '%s'", path) end + if not unmanaged then keyset.filename = path end local owner = keyset[1].owner for _, ta in ipairs(keyset) do if ta.owner ~= owner then @@ -446,6 +456,8 @@ trust_anchors = { bootstrap_url = 'https://data.iana.org/root-anchors/root-anchors.xml', bootstrap_ca = '@ETCDIR@/icann-ca.pem', + -- change empty string to nil + keyfile_default = ('@KEYFILE_DEFAULT@' ~= '' and '@KEYFILE_DEFAULT@') or nil, -- Load keys from a file, 5011-managed by default. -- If managed and the file doesn't exist, try bootstrapping the root into it. diff --git a/daemon/main.c b/daemon/main.c index 4329000185b2534d337055c57df640757143df2c..0d212696285e68050edd761dd2a070b281895569 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -18,7 +18,6 @@ #include <signal.h> #include <stdlib.h> #include <string.h> -#include <signal.h> #include <getopt.h> #include <libgen.h> #include <uv.h> @@ -39,17 +38,32 @@ #include "daemon/engine.h" #include "daemon/bindings.h" #include "daemon/tls.h" +#include "lib/dnssec/ta.h" /* We can fork early on Linux 3.9+ and do SO_REUSEPORT for better performance. */ #if defined(UV_VERSION_HEX) && defined(SO_REUSEPORT) && defined(__linux__) #define CAN_FORK_EARLY 1 #endif -/* - * Globals - */ -static bool g_quiet = false; -static bool g_interactive = true; +/* @internal Array of ip address shorthand. */ +typedef array_t(char*) addr_array_t; + +struct args { + int forks; + addr_array_t addr_set; + addr_array_t tls_set; + fd_array_t fd_set; + fd_array_t tls_fd_set; + char *keyfile; + int keyfile_unmanaged; + const char *moduledir; + const char *config; + int control_fd; + const char *rundir; + bool interactive; + bool quiet; + bool tty_binary_output; +}; /* lua_pcall helper function */ static inline char *lua_strerror(int lua_err) { @@ -66,9 +80,8 @@ static inline char *lua_strerror(int lua_err) { * * For parameters see http://docs.libuv.org/en/v1.x/stream.html#c.uv_read_cb * - * - This is just basic read-eval-print; libedit is supported through krsec; - * - stream->data represents a bool determining binary output mode (used by kresc); - * - binary output: uint32_t length in network order, followed by that many bytes. + * - This is just basic read-eval-print; libedit is supported through kresc; + * - stream->data contains program arguments (struct args); */ static void tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { @@ -77,6 +90,7 @@ static void tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t /* Set output streams */ FILE *out = stdout; uv_os_fd_t stream_fd = 0; + struct args *args = stream->data; if (uv_fileno((uv_handle_t *)stream, &stream_fd)) { uv_close((uv_handle_t *)stream, (uv_close_cb) free); free(cmd); @@ -111,11 +125,9 @@ static void tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t cmd[nread] = '\0'; } - /* Pseudo-command for switching to "binary output"; - * beware: void* <-> bool */ - bool is_binary = stream->data; + /* Pseudo-command for switching to "binary output"; */ if (strcmp(cmd, "__binary") == 0) { - stream->data = (void *)(is_binary = true); + args->tty_binary_output = true; goto finish; } @@ -128,7 +140,7 @@ static void tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t } /* Simpler output in binary mode */ - if (is_binary) { + if (args->tty_binary_output) { size_t len_s = strlen(message); if (len_s > UINT32_MAX) goto finish; @@ -140,12 +152,12 @@ static void tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t } /* Log to remote socket if connected */ - const char *delim = g_quiet ? "" : "> "; + const char *delim = args->quiet ? "" : "> "; if (stream_fd != STDIN_FILENO) { fprintf(stdout, "%s\n", cmd); /* Duplicate command to logs */ if (message) fprintf(out, "%s", message); /* Duplicate output to sender */ - if (message || !g_quiet) + if (message || !args->quiet) fprintf(out, "\n"); fprintf(out, "%s", delim); } @@ -153,7 +165,7 @@ static void tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t FILE *fp_out = ret ? stderr : stdout; if (message) fprintf(fp_out, "%s", message); - if (message || !g_quiet) + if (message || !args->quiet) fprintf(fp_out, "\n"); fprintf(fp_out, "%s", delim); lua_settop(L, 0); @@ -175,16 +187,17 @@ static void tty_alloc(uv_handle_t *handle, size_t suggested, uv_buf_t *buf) { static void tty_accept(uv_stream_t *master, int status) { uv_tcp_t *client = malloc(sizeof(*client)); + struct args *args = master->data; if (client) { uv_tcp_init(master->loop, client); if (uv_accept(master, (uv_stream_t *)client) != 0) { free(client); return; } - client->data = 0; + client->data = args; uv_read_start((uv_stream_t *)client, tty_alloc, tty_process_input); /* Write command line */ - if (!g_quiet) { + if (!args->quiet) { uv_buf_t buf = { "> ", 2 }; uv_try_write((uv_stream_t *)client, &buf, 1); } @@ -347,7 +360,8 @@ static void help(int argc, char *argv[]) " -S, --fd=[fd] Listen on given fd (handed out by supervisor).\n" " -T, --tlsfd=[fd] Listen using TLS on given fd (handed out by supervisor).\n" " -c, --config=[path] Config file path (relative to [rundir]) (default: config).\n" - " -k, --keyfile=[path] File containing trust anchors (DS or DNSKEY).\n" + " -k, --keyfile=[path] File with root domain trust anchors (DS or DNSKEY), automatically updated.\n" + " -K, --keyfile-ro=[path] File with read-only root domain trust anchors, for use with an external updater.\n" " -m, --moduledir=[path] Override the default module path (" MODULEDIR ").\n" " -f, --forks=N Start N forks sharing the configuration.\n" " -q, --quiet Quiet output, no prompt in interactive mode.\n" @@ -362,23 +376,23 @@ static void help(int argc, char *argv[]) " [rundir] Path to the working directory (default: .)\n"); } -static int run_worker(uv_loop_t *loop, struct engine *engine, fd_array_t *ipc_set, bool leader, int control_fd) +static int run_worker(uv_loop_t *loop, struct engine *engine, fd_array_t *ipc_set, bool leader, struct args *args) { /* Control sockets or TTY */ auto_free char *sock_file = NULL; uv_pipe_t pipe; uv_pipe_init(loop, &pipe, 0); - pipe.data = 0; - if (g_interactive) { - if (!g_quiet) + pipe.data = args; + if (args->interactive) { + if (!args->quiet) printf("[system] interactive mode\n> "); fflush(stdout); uv_pipe_open(&pipe, 0); uv_read_start((uv_stream_t*) &pipe, tty_alloc, tty_process_input); } else { int pipe_ret = -1; - if (control_fd != -1) { - pipe_ret = uv_pipe_open(&pipe, control_fd); + if (args->control_fd != -1) { + pipe_ret = uv_pipe_open(&pipe, args->control_fd); } else { (void) mkdir("tty", S_IRWXU|S_IRWXG); sock_file = afmt("tty/%ld", getpid()); @@ -422,105 +436,49 @@ static void free_sd_socket_names(char **socket_names, int count) } #endif -static int init_keyfile(struct engine *engine, const char *keyfile) +static int set_keyfile(struct engine *engine, char *keyfile, bool unmanaged) { - auto_free char *dirname_storage = strdup(keyfile); - if (!dirname_storage) { - return kr_error(ENOMEM); - } - - /* Resolve absolute path to the keyfile directory */ - auto_free char *keyfile_dir = malloc(PATH_MAX); - if (!keyfile_dir) { - return kr_error(ENOMEM); - } - if (realpath(dirname(dirname_storage), keyfile_dir) == NULL) { - kr_log_error("[ ta ]: keyfile '%s' directory: %s\n", keyfile, strerror(errno)); - return kr_error(ENOTDIR); - } - - auto_free char *basename_storage = strdup(keyfile); - if (!basename_storage) { - return kr_error(ENOMEM); - } - - char *_filename = basename(basename_storage); - int dirlen = strlen(keyfile_dir); - int namelen = strlen(_filename); - if (dirlen + 1 + namelen >= PATH_MAX) { - kr_log_error("[ ta ]: keyfile '%s' PATH_MAX exceeded\n", - keyfile); - return kr_error(ENAMETOOLONG); - } - keyfile_dir[dirlen++] = '/'; - keyfile_dir[dirlen] = '\0'; - - auto_free char *keyfile_path = malloc(dirlen + namelen + 1); - if (!keyfile_path) { - return kr_error(ENOMEM); - } - memcpy(keyfile_path, keyfile_dir, dirlen); - memcpy(keyfile_path + dirlen, _filename, namelen + 1); - - int unmanaged = 0; - - /* Note: config has been executed, so access() is OK, - * as we've dropped privileges already if configured. */ - if (access(keyfile_path, F_OK) != 0) { - kr_log_info("[ ta ] keyfile '%s': doesn't exist, bootstrapping\n", keyfile_path); - if (access(keyfile_dir, W_OK) != 0) { - kr_log_error("[ ta ] keyfile '%s': write access to '%s' needed\n", keyfile_path, keyfile_dir); - return kr_error(EPERM); - } - } else if (access(keyfile_path, R_OK) == 0) { - if ((access(keyfile_path, W_OK) != 0) || (access(keyfile_dir, W_OK) != 0)) { - kr_log_error("[ ta ] keyfile '%s': not writeable, starting in unmanaged mode\n", keyfile_path); - unmanaged = 1; - } - } else { - kr_log_error("[ ta ] keyfile '%s': %s\n", keyfile_path, strerror(errno)); - return kr_error(EPERM); - } - - auto_free char *cmd = afmt("trust_anchors.config('%s',%s)", keyfile_path, unmanaged?"true":"nil"); + assert(keyfile != NULL); + auto_free char *cmd = afmt("trust_anchors.config('%s',%s)", + keyfile, unmanaged ? "true" : "nil"); if (!cmd) { + kr_log_error("[system] not enough memory\n"); return kr_error(ENOMEM); } - int lua_ret = engine_cmd(engine->L, cmd, false); if (lua_ret != 0) { if (lua_gettop(engine->L) > 0) { - kr_log_error("%s", lua_tostring(engine->L, -1)); - lua_settop(engine->L, 0); + kr_log_error("%s\n", lua_tostring(engine->L, -1)); } else { kr_log_error("[ ta ] keyfile '%s': failed to load (%s)\n", - keyfile_path, lua_strerror(lua_ret)); + keyfile, lua_strerror(lua_ret)); } - return kr_error(EIO); + return lua_ret; } lua_settop(engine->L, 0); - return 0; + return kr_ok(); } -int main(int argc, char **argv) + +static void args_init(struct args *args) { - int forks = 1; - array_t(char*) addr_set; - array_t(char*) tls_set; - array_init(addr_set); - array_init(tls_set); - array_t(int) fd_set; - array_init(fd_set); - array_t(int) tls_fd_set; - array_init(tls_fd_set); - char *keyfile = NULL; - char *moduledir = MODULEDIR; - const char *config = NULL; - int control_fd = -1; + memset(args, 0, sizeof(struct args)); + args->forks = -1; + array_init(args->addr_set); + array_init(args->tls_set); + array_init(args->fd_set); + array_init(args->tls_fd_set); + args->moduledir = MODULEDIR; + args->control_fd = -1; + args->interactive = true; + args->quiet = false; +} +int parse_args(int argc, char **argv, struct args *args) +{ /* Long options. */ - int c = 0, li = 0, ret = 0; + int c = 0, li = 0; struct option opts[] = { {"addr", required_argument, 0, 'a'}, {"tls", required_argument, 0, 't'}, @@ -528,6 +486,7 @@ int main(int argc, char **argv) {"tlsfd", required_argument, 0, 'T'}, {"config", required_argument, 0, 'c'}, {"keyfile",required_argument, 0, 'k'}, + {"keyfile-ro",required_argument, 0, 'K'}, {"forks",required_argument, 0, 'f'}, {"moduledir", required_argument, 0, 'm'}, {"verbose", no_argument, 0, 'v'}, @@ -536,38 +495,44 @@ int main(int argc, char **argv) {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; - while ((c = getopt_long(argc, argv, "a:t:S:T:c:f:m:k:vqVh", opts, &li)) != -1) { + while ((c = getopt_long(argc, argv, "a:t:S:T:c:f:m:K:k:vqVh", opts, &li)) != -1) { switch (c) { case 'a': - array_push(addr_set, optarg); + array_push(args->addr_set, optarg); break; case 't': - array_push(tls_set, optarg); + array_push(args->tls_set, optarg); break; case 'S': - array_push(fd_set, strtol(optarg, NULL, 10)); + array_push(args->fd_set, strtol(optarg, NULL, 10)); break; case 'T': - array_push(tls_fd_set, strtol(optarg, NULL, 10)); + array_push(args->tls_fd_set, strtol(optarg, NULL, 10)); break; case 'c': - config = optarg; + args->config = optarg; break; case 'f': - g_interactive = false; - forks = strtol(optarg, NULL, 10); - if (forks <= 0) { + args->interactive = false; + args->forks = strtol(optarg, NULL, 10); + if (args->forks <= 0) { kr_log_error("[system] error '-f' requires a positive" " number, not '%s'\n", optarg); return EXIT_FAILURE; } break; + case 'K': + args->keyfile_unmanaged = 1; case 'k': - keyfile = optarg; + if (args->keyfile != NULL) { + kr_log_error("[system] error only one of '--keyfile' and '--keyfile-ro' allowed\n"); + return EXIT_FAILURE; + } + args->keyfile = optarg; break; case 'm': - moduledir = optarg; + args->moduledir = optarg; break; case 'v': kr_verbose_set(true); @@ -576,7 +541,7 @@ int main(int argc, char **argv) #endif break; case 'q': - g_quiet = true; + args->quiet = true; break; case 'V': kr_log_info("%s, version %s\n", "Knot DNS Resolver", PACKAGE_VERSION); @@ -589,6 +554,49 @@ int main(int argc, char **argv) help(argc, argv); return EXIT_FAILURE; } + } + if (optind < argc) { + args->rundir = argv[optind]; + } + return EXIT_SUCCESS; +} + +static int bind_fds(struct network *net, fd_array_t *fd_set, bool tls) { + int ret = 0; + for (size_t i = 0; i < fd_set->len; ++i) { + ret = network_listen_fd(net, fd_set->at[i], tls); + if (ret != 0) { + kr_log_error("[system] %slisten on fd=%d %s\n", + tls ? "TLS " : "", fd_set->at[i], kr_strerror(ret)); + break; + } + } + return ret; +} + +static int bind_sockets(struct network *net, addr_array_t *addr_set, bool tls) { + uint32_t flags = tls ? NET_TCP|NET_TLS : NET_UDP|NET_TCP; + int ret = 0; + for (size_t i = 0; i < addr_set->len; ++i) { + int port = tls ? KR_DNS_TLS_PORT : KR_DNS_PORT; + const char *addr = set_addr(addr_set->at[i], &port); + ret = network_listen(net, addr, (uint16_t)port, flags); + if (ret != 0) { + kr_log_error("[system] bind to '%s@%d' %s%s\n", + addr, port, tls ? "(TLS) " : "", kr_strerror(ret)); + break; + } + } + return ret; +} + +int main(int argc, char **argv) +{ + int ret = 0; + struct args args; + args_init(&args); + if ((ret = parse_args(argc, argv, &args)) != EXIT_SUCCESS) { + return ret; } #ifdef HAS_SYSTEMD @@ -598,45 +606,44 @@ int main(int argc, char **argv) for (int i = 0; i < sd_nsocks; ++i) { int fd = SD_LISTEN_FDS_START + i; /* when run under systemd supervision, do not use interactive mode */ - g_interactive = false; - if (forks != 1) { + args.interactive = false; + if (args.forks != 1) { kr_log_error("[system] when run under systemd-style supervision, " - "use single-process only (bad: --fork=%d).\n", forks); + "use single-process only (bad: --fork=%d).\n", args.forks); free_sd_socket_names(socket_names, sd_nsocks); return EXIT_FAILURE; } if (!strcasecmp("control",socket_names[i])) { - control_fd = fd; + args.control_fd = fd; } else if (!strcasecmp("tls",socket_names[i])) { - array_push(tls_fd_set, fd); + array_push(args.tls_fd_set, fd); } else { - array_push(fd_set, fd); + array_push(args.fd_set, fd); } } free_sd_socket_names(socket_names, sd_nsocks); #endif /* Switch to rundir. */ - if (optind < argc) { - const char *rundir = argv[optind]; + if (args.rundir != NULL) { /* FIXME: access isn't a good way if we start as root and drop privileges later */ - if (access(rundir, W_OK) != 0) { - kr_log_error("[system] rundir '%s': %s\n", rundir, strerror(errno)); + if (access(args.rundir, W_OK) != 0) { + kr_log_error("[system] rundir '%s': %s\n", args.rundir, strerror(errno)); return EXIT_FAILURE; } - ret = chdir(rundir); + ret = chdir(args.rundir); if (ret != 0) { - kr_log_error("[system] rundir '%s': %s\n", rundir, strerror(errno)); + kr_log_error("[system] rundir '%s': %s\n", args.rundir, strerror(errno)); return EXIT_FAILURE; } } - if (config && strcmp(config, "-") != 0 && access(config, R_OK) != 0) { - kr_log_error("[system] config '%s': %s\n", config, strerror(errno)); + if (args.config && strcmp(args.config, "-") != 0 && access(args.config, R_OK) != 0) { + kr_log_error("[system] config '%s': %s\n", args.config, strerror(errno)); return EXIT_FAILURE; } - if (!config && access("config", R_OK) == 0) { - config = "config"; + if (!args.config && access("config", R_OK) == 0) { + args.config = "config"; } #ifndef CAN_FORK_EARLY @@ -654,7 +661,7 @@ int main(int argc, char **argv) fd_array_t ipc_set; array_init(ipc_set); /* Fork subprocesses if requested */ - int fork_id = fork_workers(&ipc_set, forks); + int fork_id = fork_workers(&ipc_set, args.forks); if (fork_id < 0) { return EXIT_FAILURE; } @@ -673,54 +680,20 @@ int main(int argc, char **argv) return EXIT_FAILURE; } /* Create worker */ - struct worker_ctx *worker = worker_create(&engine, &pool, fork_id, forks); + struct worker_ctx *worker = worker_create(&engine, &pool, fork_id, args.forks); if (!worker) { kr_log_error("[system] not enough memory\n"); return EXIT_FAILURE; } - /* Bind to passed fds and run */ - for (size_t i = 0; i < fd_set.len; ++i) { - ret = network_listen_fd(&engine.net, fd_set.at[i], false); - if (ret != 0) { - kr_log_error("[system] listen on fd=%d %s\n", fd_set.at[i], kr_strerror(ret)); - ret = EXIT_FAILURE; - break; - } - } - /* Do the same for TLS */ - for (size_t i = 0; i < tls_fd_set.len; ++i) { - ret = network_listen_fd(&engine.net, tls_fd_set.at[i], true); - if (ret != 0) { - kr_log_error("[system] TLS listen on fd=%d %s\n", tls_fd_set.at[i], kr_strerror(ret)); - ret = EXIT_FAILURE; - break; - } - } - /* Bind to sockets and run */ - if (ret == 0) { - for (size_t i = 0; i < addr_set.len; ++i) { - int port = 53; - const char *addr = set_addr(addr_set.at[i], &port); - ret = network_listen(&engine.net, addr, (uint16_t)port, NET_UDP|NET_TCP); - if (ret != 0) { - kr_log_error("[system] bind to '%s@%d' %s\n", addr, port, kr_strerror(ret)); - ret = EXIT_FAILURE; - break; - } - } - } - /* Bind to TLS sockets */ - if (ret == 0) { - for (size_t i = 0; i < tls_set.len; ++i) { - int port = KR_DNS_TLS_PORT; - const char *addr = set_addr(tls_set.at[i], &port); - ret = network_listen(&engine.net, addr, (uint16_t)port, NET_TCP|NET_TLS); - if (ret != 0) { - kr_log_error("[system] bind to '%s@%d' (TLS) %s\n", addr, port, kr_strerror(ret)); - ret = EXIT_FAILURE; - break; - } - } + + /* Bind to passed fds and sockets*/ + if (bind_fds(&engine.net, &args.fd_set, false) != 0 || + bind_fds(&engine.net, &args.tls_fd_set, true) != 0 || + bind_sockets(&engine.net, &args.addr_set, false) != 0 || + bind_sockets(&engine.net, &args.tls_set, true) != 0 + ) { + ret = EXIT_FAILURE; + goto cleanup; } /* Workaround for https://github.com/libuv/libuv/issues/45 @@ -735,7 +708,7 @@ int main(int argc, char **argv) goto cleanup; } - engine_set_moduledir(&engine, moduledir); + engine_set_moduledir(&engine, args.moduledir); /* Block signals. */ uv_loop_t *loop = uv_default_loop(); @@ -748,23 +721,34 @@ int main(int argc, char **argv) worker->loop = loop; loop->data = worker; - ret = engine_start(&engine, config); - if (ret != 0) { + if (engine_load_sandbox(&engine) != 0) { ret = EXIT_FAILURE; goto cleanup; } - - if (keyfile) { - ret = init_keyfile(&engine, keyfile); - if (ret != 0) { - kr_log_error("[system] failed to initialized keyfile: %s\n", kr_strerror(ret)); + if (args.config != NULL && strcmp(args.config, "-") != 0) { + if(engine_loadconf(&engine, args.config) != 0) { ret = EXIT_FAILURE; goto cleanup; } + lua_settop(engine.L, 0); + } + if (args.keyfile != NULL && set_keyfile(&engine, args.keyfile, args.keyfile_unmanaged) != 0) { + ret = EXIT_FAILURE; + goto cleanup; + } + if (args.config == NULL || strcmp(args.config, "-") !=0) { + if(engine_load_defaults(&engine) != 0) { + ret = EXIT_FAILURE; + goto cleanup; + } + } + if (engine_start(&engine) != 0) { + ret = EXIT_FAILURE; + goto cleanup; } /* Run the event loop */ - ret = run_worker(loop, &engine, &ipc_set, fork_id == 0, control_fd); + ret = run_worker(loop, &engine, &ipc_set, fork_id == 0, &args); if (ret != 0) { perror("[system] worker failed"); ret = EXIT_FAILURE; @@ -775,8 +759,8 @@ int main(int argc, char **argv) engine_deinit(&engine); worker_reclaim(worker); mp_delete(pool.ctx); - array_clear(addr_set); - array_clear(tls_set); + array_clear(args.addr_set); + array_clear(args.tls_set); kr_crypto_cleanup(); return ret; } diff --git a/doc/build.rst b/doc/build.rst index 0032ce2bcdf76a3e46f12f014d632a74c2ce96c6..6ac99ba759adbf279b0370ac692c000012c117d4 100644 --- a/doc/build.rst +++ b/doc/build.rst @@ -197,10 +197,12 @@ All paths are prefixed with ``PREFIX`` variable by default if not specified othe "daemon", "``SBINDIR``", "``$(PREFIX)/sbin``", "" "configuration", "``ETCDIR``", "``$(PREFIX)/etc/kresd``", "Configuration file, templates." "modules", "``MODULEDIR``", "``$(LIBDIR)/kdns_modules``", "Runtime directory for loading dynamic modules [#]_." + "trust anchor file", "``KEYFILE_DEFAULT``", "*(none)*", "Path to read-only trust anchor file, which is used as fallback when no other file is specified. [#]_" "work directory", "", "the current directory", "Run directory for daemon. (Only relevant during run time, not e.g. during installation.)" .. [#] The ``libkres.pc`` is installed in ``$(LIBDIR)/pkgconfig``. .. [#] The default moduledir can be changed with `-m` option to `kresd` daemon or by calling `moduledir()` function from lua. +.. [#] If no other trust anchor is specified by user, the compiled-in path ``KEYFILE_DEFAULT`` must contain a valid trust anchor. This is typically used by distributions which provide DNSSEC root trust anchors as part of distribution package. Users can disable the built-in trust anchor by adding ``trust_anchors.keyfile_default = nil`` to their configuration. .. note:: Each module is self-contained and may install additional bundled files within ``$(MODULEDIR)/$(modulename)``. These files should be read-only, non-executable. diff --git a/doc/kresd.8.in b/doc/kresd.8.in index a1be6e24e0d81e0adebaec7e497549fb4d529d90..eb42bbdd06126822f570f8652e95f4b57d7529c7 100644 --- a/doc/kresd.8.in +++ b/doc/kresd.8.in @@ -24,6 +24,8 @@ .IR config ] .RB [ \-k | \-\-keyfile .IR keyfile ] +.RB [ \-K | \-\-keyfile-ro +.IR keyfile ] .RB [ \-m | \-\-moduledir .IR path ] .RB [ \-f | \-\-forks @@ -121,10 +123,20 @@ file at the default location (\fIconfig\fR). The syntax is described in \fIdaemon/README.md\fR. .TP .B \-k\fI keyfile\fR, \fB\-\-keyfile=\fI<keyfile> -Use given for keeping root trust anchors. If the file doesn't exist, it will be -automatically boostrapped from IANA and warning for you will be issued to check it -before trusting it. The file contains DNSKEY/DS records in presentation format, -and is compatible with Unbound or BIND9 root key files. +(Recommended!) Automatically managed root trust anchors file. +Root trust anchors in this file are managed using standard RFC 5011 (Automated Updates of DNS Security Trust Anchors). +Kresd needs write access to the directory containing the keyfile. + +If the file does not exist, it will be automatically boostrapped from IANA using HTTPS protocol +and warning that you need to to check the key before trusting it will be issued. + +The file contains DNSKEY/DS records in presentation format, +and is compatible with Unbound and BIND 9 root key files. +.TP +.B \-K\fI keyfile\fR, \fB\-\-keyfile-ro=\fI<keyfile> +(Discouraged) Static root trust anchors file. The file is not updated by kresd. Use of this option is discouraged because it will break your installation when the trust anchor key changes! + +Default: "@KEYFILE_DEFAULT@" (can be empty if your distribution did not provide one) .TP .B \-m\fI path\fR, \fB\-\-moduledir=\fI<path> Override the directory that is searched for modules. Default: @MODULEDIR@ diff --git a/modules/hints/hints_test.lua b/modules/hints/tests/hints.test.lua similarity index 85% rename from modules/hints/hints_test.lua rename to modules/hints/tests/hints.test.lua index 2b8a1a73609ab70ecbdec0882f0a9254ab5e8a18..b60d2a364ef62236c182ebd6d2863c75eb52372d 100644 --- a/modules/hints/hints_test.lua +++ b/modules/hints/tests/hints.test.lua @@ -6,7 +6,7 @@ modules = { 'hints' } -- test for default configuration local function test_default() -- get loaded root hints and change names to lowercase - hints_data = utils.table_keys_to_lower(hints.root()) + local hints_data = utils.table_keys_to_lower(hints.root()) -- root hints loaded from default location -- check correct ip address of a.root-server.net @@ -16,11 +16,11 @@ end -- test loading from config file local function test_custom() -- load custom root hints file with fake ip address for a.root-server.net - err_msg = hints.root_file(TEST_DIR .. 'hints_test.zone') + local err_msg = hints.root_file(TEST_DIR .. 'hints_test.zone') same(err_msg, '', 'load root hints from file') -- get loaded root hints and change names to lowercase - hints_data = utils.table_keys_to_lower(hints.root()) + local hints_data = utils.table_keys_to_lower(hints.root()) isnt(hints_data['a.root-servers.net.'], nil, 'can retrieve root hints') -- check loaded ip address of a.root-server.net @@ -33,4 +33,4 @@ end return { test_default, test_custom -} \ No newline at end of file +} diff --git a/modules/hints/hints_test.zone b/modules/hints/tests/hints_test.zone similarity index 100% rename from modules/hints/hints_test.zone rename to modules/hints/tests/hints_test.zone diff --git a/modules/policy/policy_test.lua b/modules/policy/policy.test.lua similarity index 100% rename from modules/policy/policy_test.lua rename to modules/policy/policy.test.lua diff --git a/modules/predict/predict_test.lua b/modules/predict/tests/predict.test.lua similarity index 100% rename from modules/predict/predict_test.lua rename to modules/predict/tests/predict.test.lua diff --git a/tests/config/basic_test.lua b/tests/config/basic.test.lua similarity index 100% rename from tests/config/basic_test.lua rename to tests/config/basic.test.lua diff --git a/tests/config/cache_test.lua b/tests/config/cache.test.lua similarity index 100% rename from tests/config/cache_test.lua rename to tests/config/cache.test.lua diff --git a/tests/config/keyfile/bad_args.args b/tests/config/keyfile/bad_args.args new file mode 100644 index 0000000000000000000000000000000000000000..6661ce0078691209a9a3fdc85730107bdfee3e94 --- /dev/null +++ b/tests/config/keyfile/bad_args.args @@ -0,0 +1 @@ +--keyfile-ro root.keys --keyfile root.keys \ No newline at end of file diff --git a/tests/config/keyfile/bad_args.returncode b/tests/config/keyfile/bad_args.returncode new file mode 100644 index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de --- /dev/null +++ b/tests/config/keyfile/bad_args.returncode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/config/keyfile/bad_args.test.lua b/tests/config/keyfile/bad_args.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/config/keyfile/load_ta.args b/tests/config/keyfile/load_ta.args new file mode 100644 index 0000000000000000000000000000000000000000..2d1897de7882fc62dca4dca0620ab8e9aa9d1c47 --- /dev/null +++ b/tests/config/keyfile/load_ta.args @@ -0,0 +1 @@ +--keyfile-ro root2.keys \ No newline at end of file diff --git a/tests/config/keyfile/load_ta.test.lua b/tests/config/keyfile/load_ta.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..bfe851b7c6822c2f8033a9325a0b8f58912c3c9b --- /dev/null +++ b/tests/config/keyfile/load_ta.test.lua @@ -0,0 +1,37 @@ +-- test fixtures + +-- count warning message, fail with other than allowed message +warn_msg = {} +overriding_msg="[ ta ] warning: overriding previously set trust anchors for ." +warn_msg[overriding_msg] = 0 +function warn(fmt, ...) + msg = string.format(fmt, ...) + if warn_msg[msg] == nil then + fail(string.format("Not allowed warn message: %s", msg)) + else + warn_msg[msg] = warn_msg[msg] + 1 + end +end + +-- tests + +boom(trust_anchors.add_file, {'nonwriteable/root.keys', false}, + "Managed trust anchor in non-writeable directory") + +boom(trust_anchors.add_file, {'nonexist.keys', true}, + "Nonexist unmanaged trust anchor file") + +trust_anchors.add_file('root2.keys', true) +trust_anchors.add_file('root1.keys', true) +is(warn_msg[overriding_msg], 1, "Warning message when override trust anchors") + +is(trust_anchors.keysets['\0'][1].key_tag, 19036, + "Loaded KeyTag from root1.keys") + +local function test_loading_from_cmdline() + is(trust_anchors.keysets['\0'][1].key_tag , 20326, + "Loaded KeyTag from cmdline file root2.keys") + is(warn_msg[overriding_msg], 2, "Warning message when override trust anchors") +end + +return {test_loading_from_cmdline} diff --git a/tests/config/keyfile/nonexist_keyfile1.args b/tests/config/keyfile/nonexist_keyfile1.args new file mode 100644 index 0000000000000000000000000000000000000000..6fead684f9c0739184bef3d6babb41a09dd29045 --- /dev/null +++ b/tests/config/keyfile/nonexist_keyfile1.args @@ -0,0 +1 @@ +--keyfile-ro nonexist \ No newline at end of file diff --git a/tests/config/keyfile/nonexist_keyfile1.returncode b/tests/config/keyfile/nonexist_keyfile1.returncode new file mode 100644 index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de --- /dev/null +++ b/tests/config/keyfile/nonexist_keyfile1.returncode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/config/keyfile/nonexist_keyfile1.test.lua b/tests/config/keyfile/nonexist_keyfile1.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..be73f32f460cee0f936a445729cb5bdc3162b914 --- /dev/null +++ b/tests/config/keyfile/nonexist_keyfile1.test.lua @@ -0,0 +1,2 @@ +-- simulate building without KEYFILE_DEFAULT +trust_anchors.keyfile_default = nil diff --git a/tests/config/keyfile/nonexist_keyfile2.args b/tests/config/keyfile/nonexist_keyfile2.args new file mode 100644 index 0000000000000000000000000000000000000000..6fead684f9c0739184bef3d6babb41a09dd29045 --- /dev/null +++ b/tests/config/keyfile/nonexist_keyfile2.args @@ -0,0 +1 @@ +--keyfile-ro nonexist \ No newline at end of file diff --git a/tests/config/keyfile/nonexist_keyfile2.returncode b/tests/config/keyfile/nonexist_keyfile2.returncode new file mode 100644 index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de --- /dev/null +++ b/tests/config/keyfile/nonexist_keyfile2.returncode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/config/keyfile/nonexist_keyfile2.test.lua b/tests/config/keyfile/nonexist_keyfile2.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..bb2f98bf14b29837728075987332c8f7647c2b50 --- /dev/null +++ b/tests/config/keyfile/nonexist_keyfile2.test.lua @@ -0,0 +1,2 @@ +-- simulate building with KEYFILE_DEFAULT +trust_anchors.keyfile_default = "root1.keys" diff --git a/tests/config/keyfile/root1.keys b/tests/config/keyfile/root1.keys new file mode 100644 index 0000000000000000000000000000000000000000..c7343371b9f01ac3ca7540d75044e02a56c86350 --- /dev/null +++ b/tests/config/keyfile/root1.keys @@ -0,0 +1 @@ +. 172800 DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0= ; Valid: ; KeyTag:19036 diff --git a/tests/config/keyfile/root2.keys b/tests/config/keyfile/root2.keys new file mode 100644 index 0000000000000000000000000000000000000000..5e9d6ac6e0e3964863dd4ea98280e1eb1fb5862e --- /dev/null +++ b/tests/config/keyfile/root2.keys @@ -0,0 +1 @@ +. 172800 DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU= ; Valid: ; KeyTag:20326 diff --git a/tests/config/runtest.sh b/tests/config/runtest.sh index 48dad22e2fac474ab86419c881527d83e842db94..11d9b460b73e25679fdad11f25646fa8c5d7f7b5 100755 --- a/tests/config/runtest.sh +++ b/tests/config/runtest.sh @@ -1,6 +1,7 @@ #!/bin/bash -e -export SOURCE_PATH=$(cd "$(dirname "$0")" && pwd -P) -export TEST_FILE=${2} +export SOURCE_PATH="$(cd "$(dirname "$0")" && pwd -P)" +export TEST_FILE="${2}" +TEST_DIR="$(dirname $TEST_FILE)" export TMP_RUNDIR="$(mktemp -d)" export KRESD_NO_LISTEN=1 function finish { @@ -8,5 +9,15 @@ function finish { } trap finish EXIT + echo "# $(basename ${TEST_FILE})" -${DEBUGGER} ${1} -f 1 -c ${SOURCE_PATH}/test.cfg "${TMP_RUNDIR}" \ No newline at end of file +cp -a "${TEST_DIR}/"* "${TMP_RUNDIR}/" +CMDLINE_ARGS="$(cat "${TEST_FILE%.test.lua}.args" 2>/dev/null || echo "")" +EXPECTED_RETURNCODE="$(cat "${TEST_FILE%.test.lua}.returncode" 2>/dev/null || echo 0)" +set +e +${DEBUGGER} ${1} -f 1 -c ${SOURCE_PATH}/test.cfg $CMDLINE_ARGS "${TMP_RUNDIR}" +RETCODE="$?" +if [ "$RETCODE" -ne "$EXPECTED_RETURNCODE" ]; then + echo "Expected return code '$EXPECTED_RETURNCODE' got '$RETCODE'." +fi +test "$RETCODE" -eq "$EXPECTED_RETURNCODE" diff --git a/tests/config/test_config.mk b/tests/config/test_config.mk index 28a34bfb481d8dc07da58fedc86dd842b8c4f4b1..58d7d1987d7f988740ca0f52ec1584b05d5182fa 100644 --- a/tests/config/test_config.mk +++ b/tests/config/test_config.mk @@ -6,8 +6,10 @@ # Check return code of kresd. Passed test have to call quit(). tests_config := \ - $(wildcard modules/*/*_test.lua) \ - $(wildcard tests/config/*_test.lua) + $(wildcard modules/*/*.test.lua) \ + $(wildcard modules/*/*/*.test.lua) \ + $(wildcard tests/config/*.test.lua) \ + $(wildcard tests/config/*/*.test.lua) define make_config_test $(1): check-install-precond diff --git a/tests/config/test_utils.lua b/tests/config/test_utils.lua index 3c2c63271e6f5a08f5cb909214e939276135fc76..edec11f713ab3d37b77436d32f56f953bb766d42 100644 --- a/tests/config/test_utils.lua +++ b/tests/config/test_utils.lua @@ -38,4 +38,4 @@ function M.not_contains(table, value, message) return contains(fail, pass, table, value, message) end -return M \ No newline at end of file +return M diff --git a/tests/config/tests/keyfile/nonexist_keyfile1.args b/tests/config/tests/keyfile/nonexist_keyfile1.args new file mode 100644 index 0000000000000000000000000000000000000000..6fead684f9c0739184bef3d6babb41a09dd29045 --- /dev/null +++ b/tests/config/tests/keyfile/nonexist_keyfile1.args @@ -0,0 +1 @@ +--keyfile-ro nonexist \ No newline at end of file diff --git a/tests/config/tests/keyfile/nonexist_keyfile1.returncode b/tests/config/tests/keyfile/nonexist_keyfile1.returncode new file mode 100644 index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de --- /dev/null +++ b/tests/config/tests/keyfile/nonexist_keyfile1.returncode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/config/tests/keyfile/nonexist_keyfile1.test.lua b/tests/config/tests/keyfile/nonexist_keyfile1.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..be73f32f460cee0f936a445729cb5bdc3162b914 --- /dev/null +++ b/tests/config/tests/keyfile/nonexist_keyfile1.test.lua @@ -0,0 +1,2 @@ +-- simulate building without KEYFILE_DEFAULT +trust_anchors.keyfile_default = nil diff --git a/tests/config/tests/keyfile/nonexist_keyfile2.args b/tests/config/tests/keyfile/nonexist_keyfile2.args new file mode 100644 index 0000000000000000000000000000000000000000..6fead684f9c0739184bef3d6babb41a09dd29045 --- /dev/null +++ b/tests/config/tests/keyfile/nonexist_keyfile2.args @@ -0,0 +1 @@ +--keyfile-ro nonexist \ No newline at end of file diff --git a/tests/config/tests/keyfile/nonexist_keyfile2.returncode b/tests/config/tests/keyfile/nonexist_keyfile2.returncode new file mode 100644 index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de --- /dev/null +++ b/tests/config/tests/keyfile/nonexist_keyfile2.returncode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/config/tests/keyfile/nonexist_keyfile2.test.lua b/tests/config/tests/keyfile/nonexist_keyfile2.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..bb2f98bf14b29837728075987332c8f7647c2b50 --- /dev/null +++ b/tests/config/tests/keyfile/nonexist_keyfile2.test.lua @@ -0,0 +1,2 @@ +-- simulate building with KEYFILE_DEFAULT +trust_anchors.keyfile_default = "root1.keys"