OpenDNSSEC-enforcer  2.1.5
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"
37 #include "enforcer/enforce_task.h"
38 #include "clientpipe.h"
39 #include "db/zone_db.h"
40 #include "log.h"
41 #include "file.h"
42 
44 
45 static const char *module_str = "keystate_rollover_cmd";
46 
47 static int
48 perform_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;
102  case KEY_DATA_ROLE_KSK:
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;
107  case KEY_DATA_ROLE_ZSK:
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;
112  case KEY_DATA_ROLE_CSK:
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 
138 static void
139 usage(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 
149 static void
150 help(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 
164 static int
165 run(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 
254 struct cmd_func_block key_rollover_funcblock = {
255  "key rollover", &usage, &help, NULL, &run
256 };
zone_db_update
int zone_db_update(zone_db_t *zone)
Definition: zone_db.c:1589
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_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
NARGV
#define NARGV
policy_name
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
enforcercommands.h
zone_db_free
void zone_db_free(zone_db_t *zone)
Definition: zone_db.c:325
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.h
enforce_task_flush_all
void enforce_task_flush_all(engine_type *engine, db_connection_t *dbconn)
Definition: enforce_task.c:179
policy_zone_list
zone_list_db_t * policy_zone_list(policy_t *policy)
Definition: policy.c:1093
zone_db_name
const char * zone_db_name(const zone_db_t *zone)
Definition: zone_db.c:782
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
KEY_DATA_ROLE_KSK
@ KEY_DATA_ROLE_KSK
Definition: key_data.h:42
policy_retrieve_zone_list
int policy_retrieve_zone_list(policy_t *policy)
Definition: policy.c:1111
policy_free
void policy_free(policy_t *policy)
Definition: policy.c:518
zone_db
Definition: zone_db.h:46
KEY_DATA_ROLE_ZSK
@ KEY_DATA_ROLE_ZSK
Definition: key_data.h:43
getconnectioncontext
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
Definition: enforcercommands.c:108
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_new
policy_t * policy_new(const db_connection_t *connection)
Definition: policy.c:479
engine_struct
Definition: engine.h:47
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
KEY_DATA_ROLE_CSK
@ KEY_DATA_ROLE_CSK
Definition: key_data.h:44
policy
Definition: policy.h:60
zone_list_db_size
size_t zone_list_db_size(zone_list_db_t *zone_list)
Definition: zone_db.c:2705
engine.h
db_connection
Definition: db_connection.h:46
zone_list_db_get_next
zone_db_t * zone_list_db_get_next(zone_list_db_t *zone_list)
Definition: zone_db.c:2669
getglobalcontext
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
Definition: enforcercommands.c:102
enforce_task.h
policy_get_by_name
int policy_get_by_name(policy_t *policy, const char *name)
Definition: policy.c:2040