summaryrefslogtreecommitdiffstats
path: root/daemon/main.c
diff options
context:
space:
mode:
authorMarek Vavruša <mvavrusa@cloudflare.com>2018-01-18 01:55:52 +0100
committerMarek Vavruša <mvavrusa@cloudflare.com>2018-01-18 05:05:28 +0100
commit367318144f369c2cf3f32a68e2361234909276b6 (patch)
tree56aad1eedefdaa136f8a7f81dcec018729b93fb6 /daemon/main.c
parentlib/dnssec: variable declaration close to intended to avoid dead stores (diff)
downloadknot-resolver-367318144f369c2cf3f32a68e2361234909276b6.tar.xz
knot-resolver-367318144f369c2cf3f32a68e2361234909276b6.zip
daemon/main: refactored keyfile initialization from main()
this helps avoid false positive leaks caused by combination of cleanup functions and goto refs #291
Diffstat (limited to 'daemon/main.c')
-rw-r--r--daemon/main.c161
1 files changed, 84 insertions, 77 deletions
diff --git a/daemon/main.c b/daemon/main.c
index 916fcf38..43290001 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -422,6 +422,87 @@ static void free_sd_socket_names(char **socket_names, int count)
}
#endif
+static int init_keyfile(struct engine *engine, const char *keyfile)
+{
+ 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");
+ if (!cmd) {
+ 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);
+ } else {
+ kr_log_error("[ ta ] keyfile '%s': failed to load (%s)\n",
+ keyfile_path, lua_strerror(lua_ret));
+ }
+ return kr_error(EIO);
+ }
+
+ lua_settop(engine->L, 0);
+ return 0;
+}
+
int main(int argc, char **argv)
{
int forks = 1;
@@ -674,86 +755,12 @@ int main(int argc, char **argv)
}
if (keyfile) {
- auto_free char *dirname_storage = strdup(keyfile);
- if (!dirname_storage) {
- kr_log_error("[system] not enough memory: %s\n",
- strerror(errno));
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- auto_free char *basename_storage = strdup(keyfile);
- if (!basename_storage) {
- kr_log_error("[system] not enough memory: %s\n",
- strerror(errno));
- ret = EXIT_FAILURE;
- goto cleanup;
- }
-
- /* Resolve absolute path to the keyfile directory */
- auto_free char *keyfile_dir = malloc(PATH_MAX);
- if (realpath(dirname(dirname_storage), keyfile_dir) == NULL) {
- kr_log_error("[ ta ]: keyfile '%s' directory: %s\n",
- keyfile, strerror(errno));
- ret = EXIT_FAILURE;
- goto cleanup;
- }
-
- 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);
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- keyfile_dir[dirlen++] = '/';
- keyfile_dir[dirlen] = '\0';
-
- auto_free char *keyfile_path = malloc(dirlen + namelen + 1);
- 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);
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- } 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));
- ret = EXIT_FAILURE;
- goto cleanup;
- }
-
- auto_free char *cmd = afmt("trust_anchors.config('%s',%s)", keyfile_path, unmanaged?"true":"nil");
- if (!cmd) {
- kr_log_error("[system] not enough memory\n");
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- 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));
- } else {
- kr_log_error("[ ta ] keyfile '%s': failed to load (%s)\n",
- keyfile_path, lua_strerror(lua_ret));
- }
+ ret = init_keyfile(&engine, keyfile);
+ if (ret != 0) {
+ kr_log_error("[system] failed to initialized keyfile: %s\n", kr_strerror(ret));
ret = EXIT_FAILURE;
goto cleanup;
}
- lua_settop(engine.L, 0);
}
/* Run the event loop */