Commit 9318d88c authored by Daniel Salzman's avatar Daniel Salzman

keymgr: add config and confdb parameters

parent 80852ee0
......@@ -451,6 +451,8 @@ src/utils/keymgr/legacy/privkey.c
src/utils/keymgr/legacy/privkey.h
src/utils/keymgr/legacy/pubkey.c
src/utils/keymgr/legacy/pubkey.h
src/utils/keymgr/options.c
src/utils/keymgr/options.h
src/utils/khost/khost_main.c
src/utils/khost/khost_params.c
src/utils/khost/khost_params.h
......
libtap
src
src/contrib
src/dnssec
src/dnssec/lib
src/dnssec/lib/dnssec
src/dnssec/shared
src/dnssec/utils
src/zscanner
tests
tests-fuzz
......
......@@ -246,6 +246,8 @@ keymgr_SOURCES = \
utils/keymgr/legacy/privkey.h \
utils/keymgr/legacy/pubkey.c \
utils/keymgr/legacy/pubkey.h \
utils/keymgr/options.c \
utils/keymgr/options.h \
utils/keymgr/keymgr.c
knotc_SOURCES = \
......@@ -422,7 +424,8 @@ libknotd_la_LDFLAGS = $(AM_LDFLAGS) $(systemd_LIBS) $(liburcu_LIBS)
libknotd_la_LIBADD = libknot.la libknot-yparser.la zscanner/libzscanner.la $(liburcu_LIBS)
keymgr_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/dnssec/lib/dnssec -I$(srcdir)/dnssec $(gnutls_CFLAGS)
keymgr_LDADD = dnssec/libdnssec.la dnssec/libshared.la zscanner/libzscanner.la $(gnutls_LIBS)
keymgr_LDADD = libknotd.la libknotus.la dnssec/libdnssec.la dnssec/libshared.la \
zscanner/libzscanner.la $(gnutls_LIBS)
knotd_CPPFLAGS = $(AM_CPPFLAGS) $(liburcu_CFLAGS)
knotd_LDADD = libknotd.la $(liburcu_LIBS)
knotc_CPPFLAGS = $(AM_CPPFLAGS) $(libedit_CFLAGS)
......
......@@ -31,6 +31,7 @@
#include "cmdparse/parameter.h"
#include "cmdparse/value.h"
#include "legacy/key.h"
#include "options.h"
#include "shared/dname.h"
#include "shared/print.h"
#include "shared/shared.h"
......@@ -46,12 +47,6 @@
/* -- global options ------------------------------------------------------- */
struct options {
char *kasp_dir;
};
typedef struct options options_t;
static options_t global = { 0 };
/* -- internal ------------------------------------------------------------- */
......@@ -95,12 +90,21 @@ static void cleanup_list(dnssec_list_t **list_ptr)
/* -- frequent operations -------------------------------------------------- */
static dnssec_kasp_t *get_kasp(void)
static dnssec_kasp_t *get_zone_kasp(const char *zone_name)
{
int r = options_zone_kasp_path(&global, zone_name);
if (r != DNSSEC_EOK) {
return NULL;
}
dnssec_kasp_t *kasp = NULL;
dnssec_kasp_init_dir(&kasp);
int r = dnssec_kasp_open(kasp, global.kasp_dir);
r = options_zone_kasp_init(&global, zone_name, &kasp);
if (r != DNSSEC_EOK) {
return NULL;
}
r = dnssec_kasp_open(kasp, global.kasp_dir);
if (r != DNSSEC_EOK) {
error("Cannot open KASP directory (%s).", dnssec_strerror(r));
dnssec_kasp_deinit(kasp);
......@@ -110,6 +114,11 @@ static dnssec_kasp_t *get_kasp(void)
return kasp;
}
static dnssec_kasp_t *get_kasp(void)
{
return get_zone_kasp(NULL);
}
static dnssec_kasp_zone_t *get_zone(dnssec_kasp_t *kasp, const char *name)
{
dnssec_kasp_zone_t *zone = NULL;
......@@ -660,7 +669,7 @@ static int cmd_zone_add(int argc, char *argv[])
// create zone
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
if (!kasp) {
return 1;
}
......@@ -710,7 +719,7 @@ static int cmd_zone_list(int argc, char *argv[])
return 1;
}
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(match);
if (!kasp) {
return 1;
}
......@@ -740,7 +749,7 @@ static int cmd_zone_show(int argc, char *argv[])
char *zone_name = argv[0];
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
if (!kasp) {
return 1;
}
......@@ -796,7 +805,7 @@ static int cmd_zone_remove(int argc, char *argv[])
// delete zone
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
if (!kasp) {
return 1;
}
......@@ -836,7 +845,7 @@ static int cmd_zone_key_list(int argc, char *argv[])
// list the keys
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
if (!kasp) {
return 1;
}
......@@ -871,7 +880,7 @@ static int cmd_zone_key_show(int argc, char *argv[])
// list the keys
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
if (!kasp) {
return 1;
}
......@@ -960,7 +969,7 @@ static int cmd_zone_key_ds(int argc, char *argv[])
const char *zone_name = argv[0];
const char *key_name = argv[1];
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
_cleanup_zone_ dnssec_kasp_zone_t *zone = get_zone(kasp, zone_name);
dnssec_list_t *keys = dnssec_kasp_zone_get_keys(zone);
......@@ -1048,7 +1057,7 @@ static int cmd_zone_key_generate(int argc, char *argv[])
// open KASP and key store
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(config.name);
if (!kasp) {
return 1;
}
......@@ -1144,7 +1153,7 @@ static int cmd_zone_key_set(int argc, char *argv[])
// update the key
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
if (!kasp) {
return 1;
}
......@@ -1188,7 +1197,7 @@ static int cmd_zone_key_import(int argc, char *argv[])
char *zone_name = argv[0];
char *input_file = argv[1];
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
if (!kasp) {
return 1;
}
......@@ -1275,7 +1284,7 @@ static int cmd_zone_set(int argc, char *argv[])
char *zone_name = argv[0];
_cleanup_kasp_ dnssec_kasp_t *kasp = get_kasp();
_cleanup_kasp_ dnssec_kasp_t *kasp = get_zone_kasp(zone_name);
if (!kasp) {
return 1;
}
......@@ -1313,16 +1322,22 @@ static int cmd_zone_set(int argc, char *argv[])
static int cmd_zone(int argc, char *argv[])
{
static const command_t commands[] = {
static command_t commands[] = {
{ "key", cmd_zone_key },
// legacy operations
{ "add", cmd_zone_add },
{ "list", cmd_zone_list },
{ "remove", cmd_zone_remove },
{ "show", cmd_zone_show },
{ "key", cmd_zone_key },
{ "set", cmd_zone_set },
{ NULL }
};
// disable legacy operations
if (!global.legacy) {
commands[1].name = NULL;
}
return subcommand(commands, argc, argv);
}
......@@ -1800,15 +1815,24 @@ int main(int argc, char *argv[])
// global options
static const struct option opts[] = {
{ "config", required_argument, NULL, 'c' },
{ "confdb", required_argument, NULL, 'C' },
{ "dir", required_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "legacy", no_argument, NULL, 'l' },
{ "version", no_argument, NULL, 'V' },
{ NULL }
};
int c = 0;
while (c = getopt_long(argc, argv, "+", opts, NULL), c != -1) {
while (c = getopt_long(argc, argv, "+c:C:d:hlV", opts, NULL), c != -1) {
switch (c) {
case 'c':
global.config = optarg;
break;
case 'C':
global.confdb = optarg;
break;
case 'd':
free(global.kasp_dir);
global.kasp_dir = strdup(optarg);
......@@ -1817,50 +1841,48 @@ int main(int argc, char *argv[])
print_help();
exit_code = 0;
goto failed;
case 'l':
global.legacy = true;
break;
case 'V':
print_version();
exit_code = 0;
goto failed;
case '?':
goto failed;
default:
assert_unreachable();
goto failed;
}
}
// global configuration
if (global.kasp_dir == NULL) {
char *env = getenv("KEYMGR_DIR");
if (env) {
global.kasp_dir = strdup(env);
} else {
global.kasp_dir = getcwd(NULL, 0);
}
int r = options_init(&global);
if (r != DNSSEC_EOK) {
goto failed;
}
assert(global.kasp_dir);
// subcommands
static const command_t commands[] = {
{ "init", cmd_init },
static command_t commands[] = {
{ "tsig", cmd_tsig },
{ "zone", cmd_zone },
// legacy operations
{ "init", cmd_init },
{ "policy", cmd_policy },
{ "keystore", cmd_keystore },
{ "tsig", cmd_tsig },
{ NULL }
};
dnssec_crypto_init();
// disable legacy operations
if (!global.legacy) {
commands[2].name = NULL;
}
dnssec_crypto_init();
exit_code = subcommand(commands, argc - optind, argv + optind);
failed:
dnssec_crypto_cleanup();
free(global.kasp_dir);
failed:
options_cleanup(&global);
return exit_code;
}
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/stat.h>
#include <unistd.h>
#include <dnssec/error.h>
#include "knot/conf/conf.h"
#include "knot/dnssec/context.h"
#include "options.h"
#include "shared/print.h"
int options_init(options_t *options)
{
if (options == NULL) {
return DNSSEC_EINVAL;
}
if (options->kasp_dir == NULL) {
char *env = getenv("KEYMGR_DIR");
if (env != NULL) {
options->kasp_dir = strdup(env);
}
}
if (options->legacy) {
if (options->kasp_dir == NULL) {
options->kasp_dir = getcwd(NULL, 0);
}
return DNSSEC_EOK;
}
if (options->config != NULL && options->confdb != NULL) {
error("Ambiguous configuration source.");
return DNSSEC_EINVAL;
}
// Choose the optimal config source.
struct stat st;
bool import = false;
if (options->confdb != NULL) {
import = false;
} else if (options->config != NULL) {
import = true;
} else if (stat(CONF_DEFAULT_DBDIR, &st) == 0) {
import = false;
options->confdb = CONF_DEFAULT_DBDIR;
} else if (stat(CONF_DEFAULT_FILE, &st) == 0) {
import = true;
options->config = CONF_DEFAULT_FILE;
} else if (options->kasp_dir == NULL) {
options->kasp_dir = getcwd(NULL, 0);
}
// Prepare config flags.
conf_flag_t flags = CONF_FNOHOSTNAME;
if (options->confdb != NULL) {
flags |= CONF_FREADONLY;
}
// Open confdb.
conf_t *new_conf = NULL;
if (conf_new(&new_conf, conf_scheme, options->confdb, flags) != KNOT_EOK) {
error("Failed to open configuration database '%s'.",
(options->confdb != NULL) ? options->confdb : "");
return DNSSEC_EINVAL;
}
// Import the config file.
if (import) {
if (conf_import(new_conf, options->config, true) != KNOT_EOK) {
error("Failed to open configuration file '%s'.",
options->config);
conf_free(new_conf);
return DNSSEC_EINVAL;
}
}
// Update to the new config.
conf_update(new_conf);
return DNSSEC_EOK;
}
void options_cleanup(options_t *options)
{
if (options == NULL) {
return;
}
if (!options->legacy) {
conf_update(NULL);
}
free(options->kasp_dir);
}
int options_zone_kasp_path(options_t *options, const char *zone_name)
{
if (options == NULL) {
return DNSSEC_EINVAL;
}
if (options->kasp_dir != NULL) {
return DNSSEC_EOK;
}
if (options->legacy || zone_name == NULL) {
return DNSSEC_EINVAL;
}
uint8_t buff[KNOT_DNAME_MAXLEN];
knot_dname_t *zone = knot_dname_from_str(buff, zone_name, sizeof(buff));
if (zone == NULL || knot_dname_to_lower(zone) != KNOT_EOK) {
error("Invalid zone name.");
return DNSSEC_EINVAL;
}
// Check if such a zone is configured.
if (!conf_rawid_exists(conf(), C_ZONE, zone, knot_dname_size(zone))) {
error("Zone not configured.");
return DNSSEC_EINVAL;
}
conf_val_t val = conf_zone_get(conf(), C_STORAGE, zone);
char *storage = conf_abs_path(&val, NULL);
val = conf_zone_get(conf(), C_KASP_DB, zone);
options->kasp_dir = conf_abs_path(&val, storage);
free(storage);
if (options->kasp_dir == NULL) {
return DNSSEC_EINVAL;
}
return DNSSEC_EOK;
}
int options_zone_kasp_init(options_t *options, const char *zone_name,
dnssec_kasp_t **kasp)
{
if (options == NULL) {
return DNSSEC_EINVAL;
}
if (options->legacy) {
dnssec_kasp_init_dir(kasp);
return DNSSEC_EOK;
}
if (zone_name == NULL || kasp == NULL) {
return DNSSEC_EINVAL;
}
kdnssec_ctx_t ctx = {
.legacy = options->legacy
};
int ret = kdnssec_kasp_init(&ctx, options->kasp_dir, zone_name);
kdnssec_ctx_deinit(&ctx);
if (ret != DNSSEC_EOK) {
error("Failed to initialize KASP directory '%s'.", options->kasp_dir);
return ret;
}
return kdnssec_kasp(kasp, options->legacy);
}
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "knot/dnssec/context.h"
struct options {
bool legacy;
char *kasp_dir;
char *config;
char *confdb;
};
typedef struct options options_t;
int options_init(options_t *options);
void options_cleanup(options_t *options);
int options_zone_kasp_path(options_t *options, const char *zone_name);
int options_zone_kasp_init(options_t *options, const char *zone_name,
dnssec_kasp_t **kasp);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment