33#include "cmdhandler.h"
39#include "clientpipe.h"
40#include "longgetopt.h"
51static const char *module_str =
"keystate_ds_x_cmd";
60get_dnskey(
const char *
id,
const char *zone,
int alg, uint32_t ttl)
63 hsm_sign_params_t *sign_params;
66 hsm_ctx_t *hsm_ctx = hsm_create_context();
68 ods_log_error(
"[%s] Could not connect to HSM", module_str);
71 if (!(key = hsm_find_key_by_id(hsm_ctx,
id))) {
72 hsm_destroy_context(hsm_ctx);
78 sign_params = hsm_sign_params_new();
79 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone);
80 sign_params->algorithm = (ldns_algorithm) alg;
81 sign_params->flags = LDNS_KEY_ZONE_KEY | LDNS_KEY_SEP_KEY;
84 dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params);
87 hsm_sign_params_free(sign_params);
88 hsm_destroy_context(hsm_ctx);
91 if (ttl) ldns_rr_set_ttl(dnskey_rr, ttl);
98exec_dnskey_by_id(
int sockfd,
key_data_t *key,
const char* ds_command,
102 int ttl = 0, status, i;
104 char *rrstr, *chrptr;
106 struct stat stat_ret;
114 ods_log_error_and_printf(sockfd, module_str,
115 "Error fetching from database");
135 if (!dnskey_rr)
return 2;
137 rrstr = ldns_rr2str(dnskey_rr);
140 for (i = 0; rrstr[i]; ++i) {
141 if (rrstr[i] ==
'\t') rrstr[i] =
' ';
146 if ((chrptr = strchr(rrstr,
';'))) {
151 if (!ds_command || ds_command[0] ==
'\0') {
152 ods_log_error_and_printf(sockfd, module_str,
153 "No \"DelegationSigner%sCommand\" "
154 "configured.", action);
157 pos = strstr(ds_command,
" --cka_id");
161 rrstr[strlen(rrstr)-1] =
'\0';
165 if (stat(ds_command, &stat_ret) != 0) {
166 ods_log_error_and_printf(sockfd, module_str,
167 "Cannot stat file %s: %s", ds_command,
170 }
else if (S_ISREG(stat_ret.st_mode) &&
171 !(stat_ret.st_mode & S_IXUSR ||
172 stat_ret.st_mode & S_IXGRP ||
173 stat_ret.st_mode & S_IXOTH)) {
177 ods_log_error_and_printf(sockfd, module_str,
178 "File %s is not executable", ds_command);
181 FILE *fp = popen(ds_command,
"w");
184 ods_log_error_and_printf(sockfd, module_str,
185 "failed to run command: %s: %s",ds_command,
190 bytes_written = fprintf(fp,
"%s; {cka_id = %s}\n", rrstr, locator);
192 bytes_written = fprintf(fp,
"%s", rrstr);
193 if (bytes_written < 0) {
195 ods_log_error_and_printf(sockfd, module_str,
196 "Failed to write to %s: %s", ds_command,
198 }
else if (pclose(fp) == -1) {
200 ods_log_error_and_printf(sockfd, module_str,
201 "failed to close %s: %s", ds_command,
204 client_printf(sockfd,
"key %sed to %s\n",
212 ldns_rr_free(dnskey_rr);
219 const char* ds_submit_command;
221 return exec_dnskey_by_id(sockfd, key, ds_submit_command,
"submit");
227 const char* ds_retract_command;
229 return exec_dnskey_by_id(sockfd, key, ds_retract_command,
"retract");
236 const char *fmth =
"%-31s %-13s %-13s %-40s\n";
237 const char *fmtl =
"%-31s %-13s %-13u %-40s\n";
268 client_printf(sockfd, fmth,
"Zone:",
"Key role:",
"Keytag:",
"Id:");
275 client_printf(sockfd, fmtl,
323 if (!keystate)
return 1;
338 keystate = keystate_next;
347 const char *zonename,
const hsm_key_t* hsmkey,
int keytag,
354 int status = 0, key_match = 0, key_mod = 0;
363 push_clauses(clause_list, zone, state_from, hsmkey, keytag) ||
369 client_printf_err(sockfd,
"Could not find ksk for zone %s, "
370 "does zone exist?\n", zonename);
371 ods_log_error(
"[%s] Error fetching from database", module_str);
385 ods_log_error(
"[%s] Error fetching from database", module_str);
396 (void)submit_dnskey_by_id(sockfd, key, engine);
400 (void)retract_dnskey_by_id(sockfd, key, engine);
407 ods_log_error(
"[%s] Error writing to database", module_str);
408 client_printf(sockfd,
"[%s] Error writing to database", module_str);
422 client_printf(sockfd,
"%d KSK matches found.\n", key_match);
423 if (!key_match) status = 11;
424 client_printf(sockfd,
"%d KSKs changed.\n", key_mod);
425 if (zone && key_mod > 0) {
434run_ds_cmd(cmdhandler_ctx_type* context,
int argc,
char* argv[],
438 int sockfd = context->sockfd;
439 struct longgetopt optctx;
440 const char *zonename = NULL, *cka_id = NULL, *keytag_s = NULL;
444 char buf[ODS_SE_MAXLINE];
447 int long_index = 0, opt = 0;
449 static struct option long_options[] = {
450 {
"zone", required_argument, 0,
'z'},
451 {
"cka_id", required_argument, 0,
'k'},
452 {
"keytag", required_argument, 0,
'x'},
453 {
"all", no_argument, 0,
'a'},
457 for(opt = longgetopt(argc, argv,
"z:k:x:a", long_options, &long_index, &optctx); opt != -1;
458 opt = longgetopt(argc, argv, NULL, long_options, &long_index, &optctx)) {
461 zonename = optctx.optarg;
464 cka_id = optctx.optarg;
467 keytag_s = optctx.optarg;
473 client_printf_err(sockfd,
"unknown arguments\n");
474 ods_log_error(
"[%s] unknown arguments for %s command",
475 module_str, argv[0]);
480 if (!all && !zonename && !cka_id && !keytag_s) {
481 return ds_list_keys(dbconn, sockfd, state_from);
485 keytag = atoi(keytag_s);
486 if (keytag < 0 || keytag >= 65536) {
487 ods_log_warning(
"[%s] value \"%d\" for --keytag is invalid",
489 client_printf_err(sockfd,
"value \"%d\" for --keytag is invalid\n",
496 if (all && zonename) {
497 ods_log_warning (
"[%s] Error: Unable to use --zone and --all together", module_str);
498 client_printf_err(sockfd,
"Error: Unable to use --zone and --all together\n");
503 ods_log_warning (
"[%s] Error: Unable to find a zone named \"%s\" in database\n", module_str, zonename);
504 client_printf_err(sockfd,
"Error: Unable to find a zone named \"%s\" in database\n", zonename);
511 if (!zonename && (keytag != -1 || cka_id)) {
512 ods_log_warning (
"[%s] Error: expected --zone <zone>", module_str);
513 client_printf_err(sockfd,
"Error: expected --zone <zone>\n");
517 if (!(zonename && ((cka_id && keytag == -1) || (!cka_id && keytag != -1))) && !all)
519 ods_log_warning(
"[%s] expected --zone and either --cka_id or "
520 "--keytag option or expected --all", module_str);
521 client_printf_err(sockfd,
"expected --zone and either --cka_id or "
522 "--keytag option or expected --all.\n");
527 client_printf_err(sockfd,
"CKA_ID %s can not be found!\n", cka_id);
531 state_from, state_to, engine);
db_clause_list_t * db_clause_list_new(void)
void db_clause_list_free(db_clause_list_t *clause_list)
int db_clause_set_type(db_clause_t *clause, db_clause_type_t type)
void enforce_task_flush_zone(engine_type *engine, char const *zonename)
void hsm_key_free(hsm_key_t *hsm_key)
const char * hsm_key_locator(const hsm_key_t *hsm_key)
hsm_key_t * hsm_key_new_get_by_locator(const db_connection_t *connection, const char *locator)
const db_value_t * hsm_key_id(const hsm_key_t *hsm_key)
zone_db_t * key_data_get_zone(const key_data_t *key_data)
db_clause_t * key_data_keytag_clause(db_clause_list_t *clause_list, unsigned int keytag)
int key_data_update(key_data_t *key_data)
void key_data_free(key_data_t *key_data)
const hsm_key_t * key_data_hsm_key(const key_data_t *key_data)
db_clause_t * key_data_hsm_key_id_clause(db_clause_list_t *clause_list, const db_value_t *hsm_key_id)
hsm_key_t * key_data_get_hsm_key(const key_data_t *key_data)
key_data_list_t * key_data_list_new_get_by_clauses(const db_connection_t *connection, const db_clause_list_t *clause_list)
int key_data_list_get_by_clauses(key_data_list_t *key_data_list, const db_clause_list_t *clause_list)
unsigned int key_data_keytag(const key_data_t *key_data)
const char * key_data_role_text(const key_data_t *key_data)
void key_data_list_free(key_data_list_t *key_data_list)
key_data_t * key_data_list_get_next(key_data_list_t *key_data_list)
int key_data_cache_hsm_key(key_data_t *key_data)
db_clause_t * key_data_ds_at_parent_clause(db_clause_list_t *clause_list, key_data_ds_at_parent_t ds_at_parent)
key_data_list_t * key_data_list_new(const db_connection_t *connection)
db_clause_t * key_data_role_clause(db_clause_list_t *clause_list, key_data_role_t role)
int key_data_set_ds_at_parent(key_data_t *key_data, key_data_ds_at_parent_t ds_at_parent)
int key_data_retrieve_key_state_list(key_data_t *key_data)
key_state_list_t * key_data_key_state_list(key_data_t *key_data)
const key_data_t * key_data_list_next(key_data_list_t *key_data_list)
unsigned int key_data_algorithm(const key_data_t *key_data)
db_clause_t * key_data_zone_id_clause(db_clause_list_t *clause_list, const db_value_t *zone_id)
enum key_data_ds_at_parent key_data_ds_at_parent_t
@ KEY_DATA_DS_AT_PARENT_SUBMITTED
@ KEY_DATA_DS_AT_PARENT_RETRACT
@ KEY_DATA_DS_AT_PARENT_SUBMIT
@ KEY_DATA_DS_AT_PARENT_RETRACTED
int key_data_cache_key_states(key_data_t *key_data)
const key_state_t * key_data_cached_dnskey(key_data_t *key_data)
key_state_t * key_state_list_get_next(key_state_list_t *key_state_list)
key_state_t * key_state_list_get_begin(key_state_list_t *key_state_list)
unsigned int key_state_ttl(const key_state_t *key_state)
void key_state_free(key_state_t *key_state)
int key_state_update(key_state_t *key_state)
int run_ds_cmd(cmdhandler_ctx_type *context, int argc, char *argv[], db_connection_t *dbconn, key_data_ds_at_parent_t state_from, key_data_ds_at_parent_t state_to, engine_type *engine)
int change_keys_from_to(db_connection_t *dbconn, int sockfd, const char *zonename, const hsm_key_t *hsmkey, int keytag, key_data_ds_at_parent_t state_from, key_data_ds_at_parent_t state_to, engine_type *engine)
engineconfig_type * config
const char * delegation_signer_submit_command
const char * delegation_signer_retract_command
void zone_db_free(zone_db_t *zone)
const char * zone_db_name(const zone_db_t *zone)
int zone_db_update(zone_db_t *zone)
zone_db_t * zone_db_new(const db_connection_t *connection)
const db_value_t * zone_db_id(const zone_db_t *zone)
int zone_db_get_by_name(zone_db_t *zone, const char *name)
zone_db_t * zone_db_new_get_by_name(const db_connection_t *connection, const char *name)
char * zone_db_ext_zonename_from_id(const db_connection_t *connection, const db_value_t *id)