33 #include "cmdhandler.h"
39 #include "clientpipe.h"
42 #include "libhsmdns.h"
49 static const char *module_str =
"keystate_export_cmd";
58 get_dnskey(
const char *
id,
const char *zone,
const char *keytype,
int alg, uint32_t ttl)
61 hsm_sign_params_t *sign_params;
64 hsm_ctx_t *hsm_ctx = hsm_create_context();
66 ods_log_error(
"[%s] Could not connect to HSM", module_str);
69 if (!(key = hsm_find_key_by_id(hsm_ctx,
id))) {
70 hsm_destroy_context(hsm_ctx);
76 sign_params = hsm_sign_params_new();
77 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone);
78 sign_params->algorithm = (ldns_algorithm) alg;
79 sign_params->flags = LDNS_KEY_ZONE_KEY;
81 if (keytype && !strcasecmp(keytype,
"KSK"))
82 sign_params->flags = sign_params->flags | LDNS_KEY_SEP_KEY;
85 dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params);
88 hsm_sign_params_free(sign_params);
89 hsm_destroy_context(hsm_ctx);
93 ldns_rr_set_ttl(dnskey_rr, ttl);
109 print_ds_from_id(
int sockfd,
key_data_t *key,
const char *zone,
110 const char* state,
int bind_style,
int print_sha1)
138 ds_sha_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA1);
139 rrstr = ldns_rr2str(ds_sha_rr);
140 ldns_rr_free(ds_sha_rr);
142 (void)client_printf(sockfd,
";%s %s DS record (SHA1):\n%s", state,
key_data_role_text(key), rrstr);
145 ds_sha_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA256);
146 rrstr = ldns_rr2str(ds_sha_rr);
147 ldns_rr_free(ds_sha_rr);
149 (void)client_printf(sockfd,
";%s %s DS record (SHA256):\n%s", state,
key_data_role_text(key), rrstr);
153 rrstr = ldns_rr2str_fmt(ldns_output_format_nocomments, dnskey_rr);
155 (void)client_printf(sockfd,
"%s", rrstr);
159 ldns_rr_free(dnskey_rr);
165 const char *zonename,
const char *keytype,
const char *keystate,
166 int all,
int bind_style,
int print_sha1)
172 const char *azonename = NULL;
185 ods_log_error(
"[%s] Error fetching from database", module_str);
192 client_printf_err(sockfd,
"Unable to get list of keys, memory allocation or database error!\n");
202 if (keystate && strcasecmp(
map_keystate(key), keystate)) {
206 if (!keytype && !keystate &&
217 ods_log_error(
"[%s] Error fetching from database", module_str);
218 client_printf_err(sockfd,
"Error fetching from database \n");
223 if (print_ds_from_id(sockfd, key, (
const char*)azonename?azonename:zonename, (
const char*)
map_keystate(key), bind_style, print_sha1)) {
224 ods_log_error(
"[%s] Error in print_ds_from_id", module_str);
225 client_printf_err(sockfd,
"Error in print_ds_from_id \n");
228 ods_log_error(
"[%s] Error fetching from database", module_str);
229 client_printf_err(sockfd,
"Error fetching from database \n");
243 client_printf(sockfd,
245 " --zone <zone> | --all aka -z | -a \n"
246 " --keystate <state> aka -e\n"
247 " --keytype <type> aka -t \n"
248 " [--ds [--sha1]] aka -d [-s]\n"
255 client_printf(sockfd,
256 "Export DNSKEY(s) for a given zone or all of them from the database.\n"
257 "If keytype and keystate are not specified, KSKs which are waiting for command ds-submit, ds-seen, ds-retract and ds-gone are shown. Otherwise both keystate and keytype must be given.\n"
260 "zone|all specify a zone or all of them\n"
261 "keystate limit the output to a given state\n"
262 "keytype limit the output to a given type, can be ZSK, KSK, or CSK\n"
263 "ds export DS in BIND format which can be used for upload to a registry\n"
264 "sha1 When outputting DS print sha1 instead of sha256\n");
268 run(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
271 char buf[ODS_SE_MAXLINE];
272 const char *argv[
NARGV];
274 const char *zonename = NULL;
275 const char* keytype = NULL;
276 const char* keystate = NULL;
281 int long_index = 0, opt = 0;
284 static struct option long_options[] = {
285 {
"zone", required_argument, 0,
'z'},
286 {
"keytype", required_argument, 0,
't'},
287 {
"keystate", required_argument, 0,
'e'},
288 {
"all", no_argument, 0,
'a'},
289 {
"ds", no_argument, 0,
'd'},
290 {
"sha1", no_argument, 0,
's'},
297 strncpy(buf, cmd,
sizeof(buf));
298 buf[
sizeof(buf)-1] =
'\0';
301 argc = ods_str_explode(buf,
NARGV, argv);
303 client_printf_err(sockfd,
"too many arguments\n");
304 ods_log_error(
"[%s] too many arguments for %s command",
310 while ((opt = getopt_long(argc, (
char*
const*)argv,
"z:t:e:ads", long_options, &long_index)) != -1) {
331 client_printf_err(sockfd,
"unknown arguments\n");
332 ods_log_error(
"[%s] unknown arguments for %s command",
339 if (strcasecmp(keytype,
"KSK") && strcasecmp(keytype,
"ZSK") && strcasecmp(keytype,
"CSK")) {
340 ods_log_error(
"[%s] unknown keytype, should be one of KSK, ZSK, or CSK", module_str);
341 client_printf_err(sockfd,
"unknown keytype, should be one of KSK, ZSK, or CSK\n");
347 if (strcasecmp(keystate,
"generate") && strcasecmp(keystate,
"publish") && strcasecmp(keystate,
"ready") && strcasecmp(keystate,
"active") && strcasecmp(keystate,
"retire") && strcasecmp(keystate,
"unknown") && strcasecmp(keystate,
"mixed")) {
348 ods_log_error(
"[%s] unknown keystate", module_str);
349 client_printf_err(sockfd,
"unknown keystate\n");
355 if ((!zonename && !all) || (zonename && all)) {
356 ods_log_error(
"[%s] expected either --zone or --all for %s command", module_str,
key_export_funcblock.cmdname);
357 client_printf_err(sockfd,
"expected either --zone or --all \n");
361 ods_log_error(
"[%s] Unknown zone: %s", module_str, zonename);
362 client_printf_err(sockfd,
"Unknown zone: %s\n", zonename);
372 if ((keytype && !keystate) || (!keytype && keystate)) {
373 ods_log_error(
"[%s] expected both --keystate and --keytype together or none of them", module_str);
374 client_printf_err(sockfd,
"expected both --keystate and --keytype together or none of them\n");
379 return perform_keystate_export(sockfd, dbconn, zonename, (
const char*) keytype, (
const char*) keystate, all, ds, bsha1);
383 "key export", &usage, &help, NULL, &run