OpenDNSSEC-enforcer 2.1.13
keystate_rollover_cmd.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Surfnet
3 * Copyright (c) 2011 .SE (The Internet Infrastructure Foundation).
4 * Copyright (c) 2011 OpenDNSSEC AB (svb)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#include "config.h"
31#include <getopt.h>
32
33#include "cmdhandler.h"
35#include "daemon/engine.h"
36#include "str.h"
38#include "clientpipe.h"
39#include "db/zone_db.h"
40#include "log.h"
41#include "file.h"
42#include "longgetopt.h"
43
45
46static const char *module_str = "keystate_rollover_cmd";
47
48static int
49perform_keystate_rollover(int sockfd, db_connection_t *dbconn, const char * policyname,
50 const char *zonename, int nkeyrole)
51{
52 policy_t* policy = NULL;
53 zone_db_t* zone = NULL;
54 zone_list_db_t *zonelist = NULL;
55 int reterror = 0;
56 int error = 0;
57 int listsize = 0;
58
59 if (policyname) {
60 policy = policy_new(dbconn);
61 if (policy_get_by_name(policy, policyname)){
63 policy = NULL;
64 client_printf_err(sockfd, "unknown policy %s\n", policyname);
65 return -1;
66 }
68 ods_log_error("[%s] Error fetching zones", module_str);
69 client_printf_err(sockfd, "[%s] Error fetching zones", module_str);
71 policy = NULL;
72 return 1;
73 }
74 zonelist = policy_zone_list(policy);
75 listsize = zone_list_db_size(zonelist);
76 if (listsize == 0) {
77 client_printf (sockfd, "No zones on policy %s\n", policy_name(policy));
78 client_printf (sockfd, "No keys to be rolled\n");
80 return 0;
81 }
82 zone = zone_list_db_get_next(zonelist);
83 }
84 else if (zonename) {
85 listsize = 1;
86 if (!(zone = zone_db_new_get_by_name(dbconn, zonename))) {
87 client_printf(sockfd, "zone %s not found\n", zonename);
88 return 1;
89 }
90 }
91
92 while (listsize > 0) {
93 error = 0;
94 switch (nkeyrole) {
95 case 0:
96 if (zone_db_set_roll_ksk_now(zone, 1) ||
97 zone_db_set_roll_zsk_now(zone, 1) ||
98 zone_db_set_roll_csk_now(zone, 1)) {error = 1; break;}
99 client_printf(sockfd, "rolling all keys for zone %s\n", zone_db_name(zone));
100 ods_log_info("[%s] Manual rollover initiated for all keys on Zone: %s",
101 module_str, zone_db_name(zone));
102 break;
104 if (zone_db_set_roll_ksk_now(zone, 1)) {error = 1; break;};
105 client_printf(sockfd, "rolling KSK for zone %s\n", zone_db_name(zone));
106 ods_log_info("[%s] Manual rollover initiated for KSK on Zone: %s", module_str, zone_db_name(zone));
107 break;
109 if (zone_db_set_roll_zsk_now(zone, 1)) {error = 1; break;}
110 client_printf(sockfd, "rolling ZSK for zone %s\n", zone_db_name(zone));
111 ods_log_info("[%s] Manual rollover initiated for ZSK on Zone: %s", module_str, zone_db_name(zone));
112 break;
114 if (zone_db_set_roll_csk_now(zone, 1)) {error = 1; break;}
115 client_printf(sockfd, "rolling CSK for zone %s\n", zone_db_name(zone));
116 ods_log_info("[%s] Manual rollover initiated for CSK on Zone: %s", module_str, zone_db_name(zone));
117 break;
118 default:
119 ods_log_assert(false && "nkeyrole out of range");
120 ods_log_error_and_printf(sockfd, module_str,
121 "nkeyrole out of range");
122 error = 1;
123 }
124 error = error || zone_db_set_next_change(zone, 0) || zone_db_update(zone);
125 if (error) {
126 ods_log_error_and_printf(sockfd, module_str,
127 "updating zone %s in the database failed", zone_db_name(zone));
128 }
129 reterror = error || reterror;
130 listsize--;
131 zone_db_free(zone);
132 if (listsize > 0)
133 zone = zone_list_db_get_next(zonelist);
134 }
136 return reterror;
137}
138
139static void
140usage(int sockfd)
141{
142 client_printf(sockfd,
143 "key rollover\n"
144 " --zone <zone> | --policy <policy> aka -z | -p \n"
145 " [--keytype <keytype>] aka -t\n"
146 );
147
148}
149
150static void
151help(int sockfd)
152{
153 client_printf(sockfd,
154 "Start a key rollover of the desired type *now*. The process is the same\n"
155 "as for the scheduled automated rollovers however it does not wait for\n"
156 "the keys lifetime to expire before rolling. The next rollover is due\n"
157 "after the newest key aged passed its lifetime.\n"
158 "\nOptions:\n"
159 "zone limit the output to the given the zone\n"
160 "policy limit the output to the given the policy\n"
161 "keytype limit the output to the given type, can be KSK, ZSK or CSK (default is all)\n\n"
162 );
163}
164
165static int
166run(cmdhandler_ctx_type* context, int argc, char* argv[])
167{
168 int sockfd = context->sockfd;
169 struct longgetopt optctx;
170 int error, nkeytype = 0;
171 int long_index = 0, opt = 0;
172 const char *zone = NULL, *keytype = NULL, *policy = NULL;
173 db_connection_t* dbconn = getconnectioncontext(context);
174 engine_type* engine = getglobalcontext(context);
175
176 static struct option long_options[] = {
177 {"zone", required_argument, 0, 'z'},
178 {"policy", required_argument, 0, 'p'},
179 {"keytype", required_argument, 0, 't'},
180 {0, 0, 0, 0}
181 };
182
183 for(opt = longgetopt(argc, argv, "p:z:t:", long_options, &long_index, &optctx); opt != -1;
184 opt = longgetopt(argc, argv, NULL, long_options, &long_index, &optctx)) {
185 switch (opt) {
186 case 'z':
187 zone = optctx.optarg;
188 break;
189 case 'p':
190 policy = optctx.optarg;
191 break;
192 case 't':
193 keytype = optctx.optarg;
194 break;
195 default:
196 client_printf_err(sockfd, "unknown arguments\n");
197 ods_log_error("[%s] unknown arguments for key rollover command", module_str);
198 return -1;
199 }
200 }
201
202 if (!zone && !policy) {
203 ods_log_warning("[%s] expected either --zone <zone> or --policy <policy> for key rollover command", module_str);
204 client_printf(sockfd,"expected either --zone <zone> or --policy <policy> option\n");
205 return -1;
206 }
207 else if (zone && policy) {
208 ods_log_warning("[%s] expected either --zone <zone> or --policy <policy> for key rollover command", module_str);
209 client_printf(sockfd,"expected either --zone <zone> or --policy <policy> option\n");
210 return -1;
211 }
212
213 if (keytype) {
214 if (!strncasecmp(keytype, "KSK", 3)) {
215 nkeytype = KEY_DATA_ROLE_KSK;
216 } else if (!strncasecmp(keytype, "ZSK", 3)) {
217 nkeytype = KEY_DATA_ROLE_ZSK;
218 } else if (!strncasecmp(keytype, "CSK", 3)) {
219 nkeytype = KEY_DATA_ROLE_CSK;
220 } else {
221 ods_log_warning("[%s] given keytype \"%s\" invalid",
222 module_str,keytype);
223 client_printf(sockfd, "given keytype \"%s\" invalid\n",
224 keytype);
225 return 1;
226 }
227 }
228
229 error = perform_keystate_rollover(sockfd, dbconn, policy, zone, nkeytype);
230
231 /* YBS: TODO only affected zones */
232 enforce_task_flush_all(engine, dbconn);
233 return error;
234}
235
236struct cmd_func_block key_rollover_funcblock = {
237 "key rollover", &usage, &help, NULL, NULL, &run, NULL
238};
void enforce_task_flush_all(engine_type *engine, db_connection_t *dbconn)
Definition: enforce_task.c:179
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
@ KEY_DATA_ROLE_ZSK
Definition: key_data.h:43
@ KEY_DATA_ROLE_KSK
Definition: key_data.h:42
@ KEY_DATA_ROLE_CSK
Definition: key_data.h:44
struct cmd_func_block key_rollover_funcblock
policy_t * policy_new(const db_connection_t *connection)
Definition: policy.c:479
zone_list_db_t * policy_zone_list(policy_t *policy)
Definition: policy.c:1093
int policy_get_by_name(policy_t *policy, const char *name)
Definition: policy.c:2040
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
int policy_retrieve_zone_list(policy_t *policy)
Definition: policy.c:1111
void policy_free(policy_t *policy)
Definition: policy.c:518
Definition: policy.h:60
void zone_db_free(zone_db_t *zone)
Definition: zone_db.c:325
int zone_db_set_roll_zsk_now(zone_db_t *zone, unsigned int roll_zsk_now)
Definition: zone_db.c:1041
int zone_db_set_roll_csk_now(zone_db_t *zone, unsigned int roll_csk_now)
Definition: zone_db.c:1051
const char * zone_db_name(const zone_db_t *zone)
Definition: zone_db.c:782
zone_db_t * zone_list_db_get_next(zone_list_db_t *zone_list)
Definition: zone_db.c:2669
size_t zone_list_db_size(zone_list_db_t *zone_list)
Definition: zone_db.c:2705
int zone_db_set_roll_ksk_now(zone_db_t *zone, unsigned int roll_ksk_now)
Definition: zone_db.c:1031
int zone_db_update(zone_db_t *zone)
Definition: zone_db.c:1589
zone_db_t * zone_db_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: zone_db.c:1569
int zone_db_set_next_change(zone_db_t *zone, int next_change)
Definition: zone_db.c:991