OpenDNSSEC-enforcer  2.0.3
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 
32 #include "daemon/cmdhandler.h"
33 #include "daemon/engine.h"
34 #include "str.h"
35 #include "enforcer/enforce_task.h"
36 #include "clientpipe.h"
37 #include "db/zone.h"
38 #include "log.h"
39 #include "file.h"
40 
42 
43 static const char *module_str = "keystate_rollover_cmd";
44 
45 static int
46 perform_keystate_rollover(int sockfd, db_connection_t *dbconn, const char * policyname,
47  const char *zonename, int nkeyrole)
48 {
49  policy_t* policy = NULL;
50  zone_t* zone = NULL;
51  zone_list_t *zonelist = NULL;
52  int reterror = 0;
53  int error = 0;
54  int listsize = 0;
55 
56  if (policyname) {
57  policy = policy_new(dbconn);
58  if (policy_get_by_name(policy, policyname)){
59  policy_free(policy);
60  policy = NULL;
61  client_printf_err(sockfd, "unknown policy %s\n", policyname);
62  return -1;
63  }
64  if (policy_retrieve_zone_list(policy)) {
65  ods_log_error("[%s] Error fetching zones", module_str);
66  client_printf_err(sockfd, "[%s] Error fetching zones", module_str);
67  policy_free(policy);
68  policy = NULL;
69  return 1;
70  }
71  zonelist = policy_zone_list(policy);
72  listsize = zone_list_size(zonelist);
73  if (listsize == 0) {
74  client_printf (sockfd, "No zones on policy %s\n", policy_name(policy));
75  client_printf (sockfd, "No keys to be rolled\n");
76  policy_free(policy);
77  return 0;
78  }
79  zone = zone_list_get_next(zonelist);
80  }
81  else if (zonename) {
82  listsize = 1;
83  if (!(zone = zone_new_get_by_name(dbconn, zonename))) {
84  client_printf(sockfd, "zone %s not found\n", zonename);
85  return 1;
86  }
87  }
88 
89  while (listsize > 0) {
90  error = 0;
91  switch (nkeyrole) {
92  case 0:
93  if (zone_set_roll_ksk_now(zone, 1) ||
94  zone_set_roll_zsk_now(zone, 1) ||
95  zone_set_roll_csk_now(zone, 1)) {error = 1; break;}
96  client_printf(sockfd, "rolling all keys for zone %s\n", zone_name(zone));
97  ods_log_info("[%s] Manual rollover initiated for all keys on Zone: %s",
98  module_str, zone_name(zone));
99  break;
100  case KEY_DATA_ROLE_KSK:
101  if (zone_set_roll_ksk_now(zone, 1)) {error = 1; break;};
102  client_printf(sockfd, "rolling KSK for zone %s\n", zone_name(zone));
103  ods_log_info("[%s] Manual rollover initiated for KSK on Zone: %s", module_str, zone_name(zone));
104  break;
105  case KEY_DATA_ROLE_ZSK:
106  if (zone_set_roll_zsk_now(zone, 1)) {error = 1; break;}
107  client_printf(sockfd, "rolling ZSK for zone %s\n", zone_name(zone));
108  ods_log_info("[%s] Manual rollover initiated for ZSK on Zone: %s", module_str, zone_name(zone));
109  break;
110  case KEY_DATA_ROLE_CSK:
111  if (zone_set_roll_csk_now(zone, 1)) {error = 1; break;}
112  client_printf(sockfd, "rolling CSK for zone %s\n", zone_name(zone));
113  ods_log_info("[%s] Manual rollover initiated for CSK on Zone: %s", module_str, zone_name(zone));
114  break;
115  default:
116  ods_log_assert(false && "nkeyrole out of range");
117  ods_log_error_and_printf(sockfd, module_str,
118  "nkeyrole out of range");
119  error = 1;
120  }
121  error = error || zone_set_next_change(zone, 0) || zone_update(zone);
122  if (error) {
123  ods_log_error_and_printf(sockfd, module_str,
124  "updating zone %s in the database failed", zone_name(zone));
125  }
126  reterror = error || reterror;
127  listsize--;
128  zone_free(zone);
129  if (listsize > 0)
130  zone = zone_list_get_next(zonelist);
131  }
132  policy_free(policy);
133  return reterror;
134 }
135 
136 static void
137 usage(int sockfd)
138 {
139  client_printf(sockfd,
140  "key rollover\n"
141  " --zone <zone> | --policy <policy> aka -z | -p \n"
142  " [--keytype <keytype>] aka -t\n"
143  );
144 
145 }
146 
147 static void
148 help(int sockfd)
149 {
150  client_printf(sockfd,
151  "Start a key rollover of the desired type *now*. The process is the same\n"
152  "as for the scheduled automated rollovers however it does not wait for\n"
153  "the keys lifetime to expire before rolling. The next rollover is due\n"
154  "after the newest key aged passed its lifetime.\n"
155  "\nOptions:\n"
156  "zone limit the output to the given the zone\n"
157  "policy limit the output to the given the policy\n"
158  "keytype limit the output to the given type, can be KSK, ZSK or CSK (default is all)\n\n"
159  );
160 }
161 
162 static int
163 handles(const char *cmd, ssize_t n)
164 {
165  return ods_check_command(cmd, n, key_rollover_funcblock()->cmdname)?1:0;
166 }
167 
168 static int
169 run(int sockfd, engine_type* engine, const char *cmd, ssize_t n,
170  db_connection_t *dbconn)
171 {
172  char buf[ODS_SE_MAXLINE];
173  #define NARGV 4
174  const char *argv[NARGV];
175  int argc, error, nkeytype = 0;
176  const char *zone = NULL, *keytype = NULL, *policy = NULL;
177 
178  ods_log_debug("[%s] %s command", module_str, key_rollover_funcblock()->cmdname);
179 
180  cmd = ods_check_command(cmd, n, key_rollover_funcblock()->cmdname);
181 
182  /* Use buf as an intermediate buffer for the command. */
183  strncpy(buf, cmd, sizeof(buf));
184  buf[sizeof(buf)-1] = '\0';
185 
186  /* separate the arguments */
187  argc = ods_str_explode(buf, NARGV, argv);
188  if (argc > NARGV) {
189  ods_log_warning("[%s] too many arguments for %s command",
190  module_str, key_rollover_funcblock()->cmdname);
191  client_printf(sockfd,"too many arguments\n");
192  return -1;
193  }
194 
195  (void)ods_find_arg_and_param(&argc,argv,"policy","p",&policy);
196  (void)ods_find_arg_and_param(&argc,argv,"zone","z",&zone);
197  (void)ods_find_arg_and_param(&argc,argv,"keytype","t",&keytype);
198 
199  if (argc) {
200  ods_log_warning("[%s] unknown arguments for %s command",
201  module_str, key_rollover_funcblock()->cmdname);
202  client_printf(sockfd,"unknown arguments\n");
203  return -1;
204  }
205  if (!zone && !policy) {
206  ods_log_warning("[%s] expected either --zone <zone> or --policy <policy> for %s command",
207  module_str, key_rollover_funcblock()->cmdname);
208  client_printf(sockfd,"expected either --zone <zone> or --policy <policy> option\n");
209  return -1;
210  }
211  else if (zone && policy) {
212  ods_log_warning("[%s] expected either --zone <zone> or --policy <policy> for %s command",
213  module_str, key_rollover_funcblock()->cmdname);
214  client_printf(sockfd,"expected either --zone <zone> or --policy <policy> option\n");
215  return -1;
216  }
217 
218  if (keytype) {
219  if (!strncasecmp(keytype, "KSK", 3)) {
220  nkeytype = KEY_DATA_ROLE_KSK;
221  } else if (!strncasecmp(keytype, "ZSK", 3)) {
222  nkeytype = KEY_DATA_ROLE_ZSK;
223  } else if (!strncasecmp(keytype, "CSK", 3)) {
224  nkeytype = KEY_DATA_ROLE_CSK;
225  } else {
226  ods_log_warning("[%s] given keytype \"%s\" invalid",
227  module_str,keytype);
228  client_printf(sockfd, "given keytype \"%s\" invalid\n",
229  keytype);
230  return 1;
231  }
232  }
233 
234  error = perform_keystate_rollover(sockfd, dbconn, policy, zone, nkeytype);
235  flush_enforce_task(engine, 0);
236  return error;
237 }
238 
239 static struct cmd_func_block funcblock = {
240  "key rollover", &usage, &help, &handles, &run
241 };
242 
243 struct cmd_func_block*
245 {
246  return &funcblock;
247 }
zone_list_t * policy_zone_list(policy_t *policy)
Definition: policy.c:1093
void(* help)(int sockfd)
Definition: cmdhandler.h:64
int zone_set_roll_csk_now(zone_t *zone, unsigned int roll_csk_now)
Definition: zone.c:1051
void ods_log_debug(const char *format,...)
Definition: log.c:41
#define NARGV
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
int zone_set_roll_zsk_now(zone_t *zone, unsigned int roll_zsk_now)
Definition: zone.c:1041
int zone_update(zone_t *zone)
Definition: zone.c:1589
void ods_log_info(const char *format,...)
Definition: log.c:55
int(* run)(int sockfd, struct engine_struct *engine, const char *cmd, ssize_t n, db_connection_t *dbconn)
Definition: cmdhandler.h:79
const char * cmdname
Definition: cmdhandler.h:59
void ods_log_error(const char *format,...)
Definition: log.c:69
void zone_free(zone_t *zone)
Definition: zone.c:325
void(* usage)(int sockfd)
Definition: cmdhandler.h:61
void policy_free(policy_t *policy)
Definition: policy.c:518
int zone_set_next_change(zone_t *zone, int next_change)
Definition: zone.c:991
int zone_set_roll_ksk_now(zone_t *zone, unsigned int roll_ksk_now)
Definition: zone.c:1031
policy_t * policy_new(const db_connection_t *connection)
Definition: policy.c:479
int policy_retrieve_zone_list(policy_t *policy)
Definition: policy.c:1111
zone_t * zone_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: zone.c:1569
size_t zone_list_size(zone_list_t *zone_list)
Definition: zone.c:2702
const char * zone_name(const zone_t *zone)
Definition: zone.c:782
zone_t * zone_list_get_next(zone_list_t *zone_list)
Definition: zone.c:2666
int policy_get_by_name(policy_t *policy, const char *name)
Definition: policy.c:2040
struct cmd_func_block * key_rollover_funcblock(void)
Definition: policy.h:60
Definition: zone.h:46
int(* handles)(const char *cmd, ssize_t n)
Definition: cmdhandler.h:67
void ods_log_warning(const char *format,...)
Definition: log.c:62
int flush_enforce_task(engine_type *engine, bool enforce_all)
Definition: enforce_task.c:323