OpenDNSSEC-enforcer 2.1.12
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
44
45static const char *module_str = "keystate_rollover_cmd";
46
47static int
48perform_keystate_rollover(int sockfd, db_connection_t *dbconn, const char * policyname,
49 const char *zonename, int nkeyrole)
50{
51 policy_t* policy = NULL;
52 zone_db_t* zone = NULL;
53 zone_list_db_t *zonelist = NULL;
54 int reterror = 0;
55 int error = 0;
56 int listsize = 0;
57
58 if (policyname) {
59 policy = policy_new(dbconn);
60 if (policy_get_by_name(policy, policyname)){
62 policy = NULL;
63 client_printf_err(sockfd, "unknown policy %s\n", policyname);
64 return -1;
65 }
67 ods_log_error("[%s] Error fetching zones", module_str);
68 client_printf_err(sockfd, "[%s] Error fetching zones", module_str);
70 policy = NULL;
71 return 1;
72 }
73 zonelist = policy_zone_list(policy);
74 listsize = zone_list_db_size(zonelist);
75 if (listsize == 0) {
76 client_printf (sockfd, "No zones on policy %s\n", policy_name(policy));
77 client_printf (sockfd, "No keys to be rolled\n");
79 return 0;
80 }
81 zone = zone_list_db_get_next(zonelist);
82 }
83 else if (zonename) {
84 listsize = 1;
85 if (!(zone = zone_db_new_get_by_name(dbconn, zonename))) {
86 client_printf(sockfd, "zone %s not found\n", zonename);
87 return 1;
88 }
89 }
90
91 while (listsize > 0) {
92 error = 0;
93 switch (nkeyrole) {
94 case 0:
95 if (zone_db_set_roll_ksk_now(zone, 1) ||
96 zone_db_set_roll_zsk_now(zone, 1) ||
97 zone_db_set_roll_csk_now(zone, 1)) {error = 1; break;}
98 client_printf(sockfd, "rolling all keys for zone %s\n", zone_db_name(zone));
99 ods_log_info("[%s] Manual rollover initiated for all keys on Zone: %s",
100 module_str, zone_db_name(zone));
101 break;
103 if (zone_db_set_roll_ksk_now(zone, 1)) {error = 1; break;};
104 client_printf(sockfd, "rolling KSK for zone %s\n", zone_db_name(zone));
105 ods_log_info("[%s] Manual rollover initiated for KSK on Zone: %s", module_str, zone_db_name(zone));
106 break;
108 if (zone_db_set_roll_zsk_now(zone, 1)) {error = 1; break;}
109 client_printf(sockfd, "rolling ZSK for zone %s\n", zone_db_name(zone));
110 ods_log_info("[%s] Manual rollover initiated for ZSK on Zone: %s", module_str, zone_db_name(zone));
111 break;
113 if (zone_db_set_roll_csk_now(zone, 1)) {error = 1; break;}
114 client_printf(sockfd, "rolling CSK for zone %s\n", zone_db_name(zone));
115 ods_log_info("[%s] Manual rollover initiated for CSK on Zone: %s", module_str, zone_db_name(zone));
116 break;
117 default:
118 ods_log_assert(false && "nkeyrole out of range");
119 ods_log_error_and_printf(sockfd, module_str,
120 "nkeyrole out of range");
121 error = 1;
122 }
123 error = error || zone_db_set_next_change(zone, 0) || zone_db_update(zone);
124 if (error) {
125 ods_log_error_and_printf(sockfd, module_str,
126 "updating zone %s in the database failed", zone_db_name(zone));
127 }
128 reterror = error || reterror;
129 listsize--;
130 zone_db_free(zone);
131 if (listsize > 0)
132 zone = zone_list_db_get_next(zonelist);
133 }
135 return reterror;
136}
137
138static void
139usage(int sockfd)
140{
141 client_printf(sockfd,
142 "key rollover\n"
143 " --zone <zone> | --policy <policy> aka -z | -p \n"
144 " [--keytype <keytype>] aka -t\n"
145 );
146
147}
148
149static void
150help(int sockfd)
151{
152 client_printf(sockfd,
153 "Start a key rollover of the desired type *now*. The process is the same\n"
154 "as for the scheduled automated rollovers however it does not wait for\n"
155 "the keys lifetime to expire before rolling. The next rollover is due\n"
156 "after the newest key aged passed its lifetime.\n"
157 "\nOptions:\n"
158 "zone limit the output to the given the zone\n"
159 "policy limit the output to the given the policy\n"
160 "keytype limit the output to the given type, can be KSK, ZSK or CSK (default is all)\n\n"
161 );
162}
163
164static int
165run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
166{
167 char buf[ODS_SE_MAXLINE];
168 #define NARGV 6
169 const char *argv[NARGV];
170 int argc = 0, 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 ods_log_debug("[%s] %s command", module_str, key_rollover_funcblock.cmdname);
184
185 /* Use buf as an intermediate buffer for the command. */
186 strncpy(buf, cmd, sizeof(buf));
187 buf[sizeof(buf)-1] = '\0';
188
189 /* separate the arguments */
190 argc = ods_str_explode(buf, NARGV, argv);
191 if (argc == -1) {
192 client_printf_err(sockfd, "too many arguments\n");
193 ods_log_error("[%s] too many arguments for %s command",
194 module_str, key_rollover_funcblock.cmdname);
195 return -1;
196 }
197
198 optind = 0;
199 while ((opt = getopt_long(argc, (char* const*)argv, "p:z:t:", long_options, &long_index)) != -1) {
200 switch (opt) {
201 case 'z':
202 zone = optarg;
203 break;
204 case 'p':
205 policy = optarg;
206 break;
207 case 't':
208 keytype = optarg;
209 break;
210 default:
211 client_printf_err(sockfd, "unknown arguments\n");
212 ods_log_error("[%s] unknown arguments for %s command",
213 module_str, key_rollover_funcblock.cmdname);
214 return -1;
215 }
216 }
217
218 if (!zone && !policy) {
219 ods_log_warning("[%s] expected either --zone <zone> or --policy <policy> for %s command",
220 module_str, key_rollover_funcblock.cmdname);
221 client_printf(sockfd,"expected either --zone <zone> or --policy <policy> option\n");
222 return -1;
223 }
224 else if (zone && policy) {
225 ods_log_warning("[%s] expected either --zone <zone> or --policy <policy> for %s command",
226 module_str, key_rollover_funcblock.cmdname);
227 client_printf(sockfd,"expected either --zone <zone> or --policy <policy> option\n");
228 return -1;
229 }
230
231 if (keytype) {
232 if (!strncasecmp(keytype, "KSK", 3)) {
233 nkeytype = KEY_DATA_ROLE_KSK;
234 } else if (!strncasecmp(keytype, "ZSK", 3)) {
235 nkeytype = KEY_DATA_ROLE_ZSK;
236 } else if (!strncasecmp(keytype, "CSK", 3)) {
237 nkeytype = KEY_DATA_ROLE_CSK;
238 } else {
239 ods_log_warning("[%s] given keytype \"%s\" invalid",
240 module_str,keytype);
241 client_printf(sockfd, "given keytype \"%s\" invalid\n",
242 keytype);
243 return 1;
244 }
245 }
246
247 error = perform_keystate_rollover(sockfd, dbconn, policy, zone, nkeytype);
248
249 /* YBS: TODO only affected zones */
250 enforce_task_flush_all(engine, dbconn);
251 return error;
252}
253
254struct cmd_func_block key_rollover_funcblock = {
255 "key rollover", &usage, &help, NULL, &run
256};
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
#define NARGV
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