keystate_rollover_cmd.c
Go to the documentation of this file.
/*
* Copyright (c) 2011 Surfnet
* Copyright (c) 2011 .SE (The Internet Infrastructure Foundation).
* Copyright (c) 2011 OpenDNSSEC AB (svb)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include <getopt.h>
#include "cmdhandler.h"
#include "daemon/enforcercommands.h"
#include "daemon/engine.h"
#include "str.h"
#include "enforcer/enforce_task.h"
#include "clientpipe.h"
#include "db/zone_db.h"
#include "log.h"
#include "file.h"
#include "keystate/keystate_rollover_cmd.h"
static const char *module_str = "keystate_rollover_cmd";
static int
perform_keystate_rollover(int sockfd, db_connection_t *dbconn, const char * policyname,
const char *zonename, int nkeyrole)
{
policy_t* policy = NULL;
zone_db_t* zone = NULL;
zone_list_db_t *zonelist = NULL;
int reterror = 0;
int error = 0;
int listsize = 0;
if (policyname) {
policy = policy_new(dbconn);
if (policy_get_by_name(policy, policyname)){
policy_free(policy);
policy = NULL;
client_printf_err(sockfd, "unknown policy %s\n", policyname);
return -1;
}
if (policy_retrieve_zone_list(policy)) {
ods_log_error("[%s] Error fetching zones", module_str);
client_printf_err(sockfd, "[%s] Error fetching zones", module_str);
policy_free(policy);
policy = NULL;
return 1;
}
zonelist = policy_zone_list(policy);
listsize = zone_list_db_size(zonelist);
if (listsize == 0) {
client_printf (sockfd, "No zones on policy %s\n", policy_name(policy));
client_printf (sockfd, "No keys to be rolled\n");
policy_free(policy);
return 0;
}
zone = zone_list_db_get_next(zonelist);
}
else if (zonename) {
listsize = 1;
if (!(zone = zone_db_new_get_by_name(dbconn, zonename))) {
client_printf(sockfd, "zone %s not found\n", zonename);
return 1;
}
}
while (listsize > 0) {
error = 0;
switch (nkeyrole) {
case 0:
if (zone_db_set_roll_ksk_now(zone, 1) ||
zone_db_set_roll_zsk_now(zone, 1) ||
zone_db_set_roll_csk_now(zone, 1)) {error = 1; break;}
client_printf(sockfd, "rolling all keys for zone %s\n", zone_db_name(zone));
ods_log_info("[%s] Manual rollover initiated for all keys on Zone: %s",
module_str, zone_db_name(zone));
break;
case KEY_DATA_ROLE_KSK:
if (zone_db_set_roll_ksk_now(zone, 1)) {error = 1; break;};
client_printf(sockfd, "rolling KSK for zone %s\n", zone_db_name(zone));
ods_log_info("[%s] Manual rollover initiated for KSK on Zone: %s", module_str, zone_db_name(zone));
break;
case KEY_DATA_ROLE_ZSK:
if (zone_db_set_roll_zsk_now(zone, 1)) {error = 1; break;}
client_printf(sockfd, "rolling ZSK for zone %s\n", zone_db_name(zone));
ods_log_info("[%s] Manual rollover initiated for ZSK on Zone: %s", module_str, zone_db_name(zone));
break;
case KEY_DATA_ROLE_CSK:
if (zone_db_set_roll_csk_now(zone, 1)) {error = 1; break;}
client_printf(sockfd, "rolling CSK for zone %s\n", zone_db_name(zone));
ods_log_info("[%s] Manual rollover initiated for CSK on Zone: %s", module_str, zone_db_name(zone));
break;
default:
ods_log_assert(false && "nkeyrole out of range");
ods_log_error_and_printf(sockfd, module_str,
"nkeyrole out of range");
error = 1;
}
error = error || zone_db_set_next_change(zone, 0) || zone_db_update(zone);
if (error) {
ods_log_error_and_printf(sockfd, module_str,
"updating zone %s in the database failed", zone_db_name(zone));
}
reterror = error || reterror;
listsize--;
zone_db_free(zone);
if (listsize > 0)
zone = zone_list_db_get_next(zonelist);
}
policy_free(policy);
return reterror;
}
static void
usage(int sockfd)
{
client_printf(sockfd,
"key rollover\n"
" --zone <zone> | --policy <policy> aka -z | -p \n"
" [--keytype <keytype>] aka -t\n"
);
}
static void
help(int sockfd)
{
client_printf(sockfd,
"Start a key rollover of the desired type *now*. The process is the same\n"
"as for the scheduled automated rollovers however it does not wait for\n"
"the keys lifetime to expire before rolling. The next rollover is due\n"
"after the newest key aged passed its lifetime.\n"
"\nOptions:\n"
"zone limit the output to the given the zone\n"
"policy limit the output to the given the policy\n"
"keytype limit the output to the given type, can be KSK, ZSK or CSK (default is all)\n\n"
);
}
static int
run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
{
char buf[ODS_SE_MAXLINE];
#define NARGV 6
const char *argv[NARGV];
int argc = 0, error, nkeytype = 0;
int long_index = 0, opt = 0;
const char *zone = NULL, *keytype = NULL, *policy = NULL;
db_connection_t* dbconn = getconnectioncontext(context);
engine_type* engine = getglobalcontext(context);
static struct option long_options[] = {
{"zone", required_argument, 0, 'z'},
{"policy", required_argument, 0, 'p'},
{"keytype", required_argument, 0, 't'},
{0, 0, 0, 0}
};
ods_log_debug("[%s] %s command", module_str, key_rollover_funcblock.cmdname);
/* Use buf as an intermediate buffer for the command. */
strncpy(buf, cmd, sizeof(buf));
buf[sizeof(buf)-1] = '\0';
/* separate the arguments */
argc = ods_str_explode(buf, NARGV, argv);
if (argc == -1) {
client_printf_err(sockfd, "too many arguments\n");
ods_log_error("[%s] too many arguments for %s command",
module_str, key_rollover_funcblock.cmdname);
return -1;
}
optind = 0;
while ((opt = getopt_long(argc, (char* const*)argv, "p:z:t:", long_options, &long_index)) != -1) {
switch (opt) {
case 'z':
zone = optarg;
break;
case 'p':
policy = optarg;
break;
case 't':
keytype = optarg;
break;
default:
client_printf_err(sockfd, "unknown arguments\n");
ods_log_error("[%s] unknown arguments for %s command",
module_str, key_rollover_funcblock.cmdname);
return -1;
}
}
if (!zone && !policy) {
ods_log_warning("[%s] expected either --zone <zone> or --policy <policy> for %s command",
module_str, key_rollover_funcblock.cmdname);
client_printf(sockfd,"expected either --zone <zone> or --policy <policy> option\n");
return -1;
}
else if (zone && policy) {
ods_log_warning("[%s] expected either --zone <zone> or --policy <policy> for %s command",
module_str, key_rollover_funcblock.cmdname);
client_printf(sockfd,"expected either --zone <zone> or --policy <policy> option\n");
return -1;
}
if (keytype) {
if (!strncasecmp(keytype, "KSK", 3)) {
nkeytype = KEY_DATA_ROLE_KSK;
} else if (!strncasecmp(keytype, "ZSK", 3)) {
nkeytype = KEY_DATA_ROLE_ZSK;
} else if (!strncasecmp(keytype, "CSK", 3)) {
nkeytype = KEY_DATA_ROLE_CSK;
} else {
ods_log_warning("[%s] given keytype \"%s\" invalid",
module_str,keytype);
client_printf(sockfd, "given keytype \"%s\" invalid\n",
keytype);
return 1;
}
}
error = perform_keystate_rollover(sockfd, dbconn, policy, zone, nkeytype);
/* YBS: TODO only affected zones */
enforce_task_flush_all(engine, dbconn);
return error;
}
struct cmd_func_block key_rollover_funcblock = {
"key rollover", &usage, &help, NULL, &run
};
zone_db_new_get_by_name
zone_db_t * zone_db_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: zone_db.c:1569
zone_db_free
void zone_db_free(zone_db_t *zone)
Definition: zone_db.c:325
KEY_DATA_ROLE_ZSK
Definition: key_data.h:43
zone_db.h
zone_list_db_get_next
zone_db_t * zone_list_db_get_next(zone_list_db_t *zone_list)
Definition: zone_db.c:2669
engine.h
NARGV
#define NARGV
policy_name
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
zone_db_set_roll_ksk_now
int zone_db_set_roll_ksk_now(zone_db_t *zone, unsigned int roll_ksk_now)
Definition: zone_db.c:1031
zone_db_set_roll_zsk_now
int zone_db_set_roll_zsk_now(zone_db_t *zone, unsigned int roll_zsk_now)
Definition: zone_db.c:1041
KEY_DATA_ROLE_CSK
Definition: key_data.h:44
enforce_task_flush_all
void enforce_task_flush_all(engine_type *engine, db_connection_t *dbconn)
Definition: enforce_task.c:179
getglobalcontext
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
Definition: enforcercommands.c:102
getconnectioncontext
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
Definition: enforcercommands.c:108
enforce_task.h
policy_free
void policy_free(policy_t *policy)
Definition: policy.c:518
zone_db
Definition: zone_db.h:46
zone_db_name
const char * zone_db_name(const zone_db_t *zone)
Definition: zone_db.c:782
policy_new
policy_t * policy_new(const db_connection_t *connection)
Definition: policy.c:479
policy_retrieve_zone_list
int policy_retrieve_zone_list(policy_t *policy)
Definition: policy.c:1111
enforcercommands.h
zone_list_db
Definition: zone_db.h:466
keystate_rollover_cmd.h
key_rollover_funcblock
struct cmd_func_block key_rollover_funcblock
Definition: keystate_rollover_cmd.c:254
policy_zone_list
zone_list_db_t * policy_zone_list(policy_t *policy)
Definition: policy.c:1093
policy_get_by_name
int policy_get_by_name(policy_t *policy, const char *name)
Definition: policy.c:2040
engine_struct
Definition: engine.h:47
KEY_DATA_ROLE_KSK
Definition: key_data.h:42
policy
Definition: policy.h:60
db_connection
Definition: db_connection.h:46
zone_db_set_next_change
int zone_db_set_next_change(zone_db_t *zone, int next_change)
Definition: zone_db.c:991
zone_db_update
int zone_db_update(zone_db_t *zone)
Definition: zone_db.c:1589
zone_list_db_size
size_t zone_list_db_size(zone_list_db_t *zone_list)
Definition: zone_db.c:2705
zone_db_set_roll_csk_now
int zone_db_set_roll_csk_now(zone_db_t *zone, unsigned int roll_csk_now)
Definition: zone_db.c:1051