OpenDNSSEC-enforcer  2.1.7
backup_hsmkeys_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<getopt.h>
31 #include "config.h"
32 
33 #include "cmdhandler.h"
35 #include "daemon/engine.h"
36 #include "file.h"
37 #include "log.h"
38 #include "str.h"
39 #include "duration.h"
40 #include "clientpipe.h"
41 #include "libhsm.h"
42 #include "db/hsm_key.h"
43 #include "db/hsm_key_ext.h"
44 
46 
47 static const char *module_str = "backup_hsmkeys_cmd";
48 
49 enum {
53  LIST
54 };
55 
56 static int
57 hsmkeys_from_to_state(db_connection_t *dbconn, db_clause_list_t* clause_list,
58  hsm_key_backup_t from_state, hsm_key_backup_t to_state)
59 {
60  hsm_key_list_t* hsmkey_list;
61  hsm_key_t *hsmkey;
62  int keys_marked = 0;
63 
64  if (!hsm_key_backup_clause(clause_list, from_state)
65  || !(hsmkey_list = hsm_key_list_new_get_by_clauses(dbconn, clause_list)))
66  {
67  ods_log_error("[%s] database error", module_str);
68  return -1;
69  }
70 
71  while ((hsmkey = hsm_key_list_get_next(hsmkey_list))) {
72  if (hsm_key_set_backup(hsmkey, to_state) ||
73  hsm_key_update(hsmkey))
74  {
75  ods_log_error("[%s] database error", module_str);
76  hsm_key_free(hsmkey);
77  hsm_key_list_free(hsmkey_list);
78  return -1;
79  }
80  keys_marked++;
81  hsm_key_free(hsmkey);
82  }
83  hsm_key_list_free(hsmkey_list);
84 
85  return keys_marked;
86 }
87 
88 static int
89 prepare(int sockfd, db_connection_t *dbconn, db_clause_list_t* clause_list)
90 {
91  int keys_marked = hsmkeys_from_to_state(dbconn, clause_list,
93  if (keys_marked < 0) {
94  return 1;
95  }
96  client_printf(sockfd,"info: keys flagged for backup: %d\n", keys_marked);
97  return 0;
98 }
99 
100 static int
101 commit(int sockfd, db_connection_t *dbconn, db_clause_list_t* clause_list)
102 {
103  int keys_marked = hsmkeys_from_to_state(dbconn, clause_list,
105  if (keys_marked < 0) {
106  return 1;
107  }
108  client_printf(sockfd,"info: keys marked backup done: %d\n", keys_marked);
109  return 0;
110 }
111 
112 static int
113 rollback(int sockfd, db_connection_t *dbconn, db_clause_list_t* clause_list)
114 {
115  int keys_marked = hsmkeys_from_to_state(dbconn, clause_list,
117  if (keys_marked < 0) {
118  return 1;
119  }
120  client_printf(sockfd,"info: keys unflagged for backup: %d\n", keys_marked);
121  return 0;
122 }
123 
124 static int
125 list(int sockfd, db_connection_t *dbconn, db_clause_list_t* clause_list)
126 {
127  hsm_key_list_t* hsmkey_list;
128  const hsm_key_t *hsmkey;
129  char const *fmt = "%-32s %-16s %-16s\n";
130 
131  if (!(hsmkey_list = hsm_key_list_new_get_by_clauses(dbconn, clause_list)))
132  {
133  ods_log_error("[%s] database error", module_str);
134  return -1;
135  }
136 
137  client_printf_err(sockfd, fmt, "Locator:", "Repository:", "Backup state:");
138  for (hsmkey = hsm_key_list_next(hsmkey_list); hsmkey;
139  hsmkey = hsm_key_list_next(hsmkey_list))
140  {
141  client_printf(sockfd, fmt, hsm_key_locator(hsmkey), hsm_key_repository(hsmkey), hsm_key_to_backup_state(hsmkey));
142  }
143  hsm_key_list_free(hsmkey_list);
144  return 0;
145 }
146 
147 static void
148 usage(int sockfd)
149 {
150  client_printf(sockfd,
151  "backup [list|prepare|commit|rollback]\n"
152  " --repository <repository> aka -r\n");
153 }
154 
155 static void
156 help(int sockfd)
157 {
158  client_printf(sockfd,
159  "If the <RequireBackup/> option is given for a <Repository> in "
160  "conf.xml, OpenDNSSEC will not publish records using key material "
161  "not marked as backed up. Backing up key material is "
162  "be done repository wide and is a 2-step process. First the "
163  "operator issues a 'prepare' and after backing up a 'commit'. "
164  "This avoids race conditions where the operator and the enforcer "
165  "disagree on which keys are actually backed up.\n\n"
166 
167  "NOTICE: OpenDNSSEC does not backup key material it self. It is "
168  "the operators responsibility to do this. This merely keeps track "
169  "of the state and acts as a safety net.\n\n"
170 
171  "backup list:\t Print backup status of keys.\n"
172  "backup prepare:\t Flag the keys as 'to be backed up'.\n"
173  "backup commit:\t Mark flagged keys as backed up.\n"
174  "backup rollback: Cancel a 'backup prepare' action.\n"
175  "\nOptions:\n"
176  "-r <repository>:\t Limit operations to this repository only.\n\n");
177 }
178 
179 static int
180 handles(const char *cmd)
181 {
182  if (ods_check_command(cmd, "backup")) return 1;
183  if (ods_check_command(cmd, "backup prepare")) return 1;
184  if (ods_check_command(cmd, "backup commit")) return 1;
185  if (ods_check_command(cmd, "backup rollback")) return 1;
186  if (ods_check_command(cmd, "backup list")) return 1;
187  return 0;
188 }
189 
190 static int
191 run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
192 {
193  #define NARGV 4
194  const char *argv[NARGV];
195  int argc = 0, long_index = 0, opt = 0;
196  const char *repository = NULL;
197  char buf[ODS_SE_MAXLINE];
198  int status;
199  db_clause_list_t* clause_list;
200  db_connection_t* dbconn = getconnectioncontext(context);
201 
202  static struct option long_options[] = {
203  {"repository", required_argument, 0, 'r'},
204  {0, 0, 0, 0}
205  };
206 
207  strncpy(buf, cmd, ODS_SE_MAXLINE);
208  buf[sizeof(buf)-1] = '\0';
209 
210  argc = ods_str_explode(buf, NARGV, argv);
211  if (argc == -1) {
212  client_printf_err(sockfd, "too many arguments\n");
213  ods_log_error("[%s] too many arguments for %s command",
214  module_str, backup_funcblock.cmdname);
215  return -1;
216  }
217 
218  optind = 0;
219  while ((opt = getopt_long(argc, (char* const*)argv, "r:", long_options, &long_index)) != -1) {
220  switch (opt) {
221  case 'r':
222  repository = optarg;
223  break;
224  default:
225  client_printf_err(sockfd, "unknown arguments\n");
226  ods_log_error("[%s] unknown arguments for %s command",
227  module_str, backup_funcblock.cmdname);
228  return -1;
229  }
230  }
231 
232  /* iterate the keys */
233  if (!(clause_list = db_clause_list_new())) {
234  ods_log_error("[%s] database error", module_str);
235  return 1;
236  }
237  if (repository && !hsm_key_repository_clause(clause_list, repository)) {
238  db_clause_list_free(clause_list);
239  ods_log_error("[%s] Could not get key list", module_str);
240  return 1;
241  }
242 
243  /* Find out what we need to do */
244  if (ods_check_command(cmd,"backup prepare"))
245  status = prepare(sockfd, dbconn, clause_list);
246  else if (ods_check_command(cmd,"backup commit"))
247  status = commit(sockfd, dbconn, clause_list);
248  else if (ods_check_command(cmd,"backup rollback"))
249  status = rollback(sockfd, dbconn, clause_list);
250  else if (ods_check_command(cmd,"backup list"))
251  status = list(sockfd, dbconn, clause_list);
252  else
253  status = -1;
254 
255  db_clause_list_free(clause_list);
256  return status;
257 }
258 
259 struct cmd_func_block backup_funcblock = {
260  "backup", &usage, &help, &handles, &run
261 };
@ COMMIT
@ LIST
@ PREPARE
@ ROLLBACK
struct cmd_func_block backup_funcblock
#define NARGV
db_clause_list_t * db_clause_list_new(void)
Definition: db_clause.c:202
void db_clause_list_free(db_clause_list_t *clause_list)
Definition: db_clause.c:209
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
void hsm_key_free(hsm_key_t *hsm_key)
Definition: hsm_key.c:286
const char * hsm_key_repository(const hsm_key_t *hsm_key)
Definition: hsm_key.c:568
const hsm_key_t * hsm_key_list_next(hsm_key_list_t *hsm_key_list)
Definition: hsm_key.c:1924
db_clause_t * hsm_key_backup_clause(db_clause_list_t *clause_list, hsm_key_backup_t backup)
Definition: hsm_key.c:906
hsm_key_t * hsm_key_list_get_next(hsm_key_list_t *hsm_key_list)
Definition: hsm_key.c:1990
int hsm_key_update(hsm_key_t *hsm_key)
Definition: hsm_key.c:1225
void hsm_key_list_free(hsm_key_list_t *hsm_key_list)
Definition: hsm_key.c:1496
int hsm_key_set_backup(hsm_key_t *hsm_key, hsm_key_backup_t backup)
Definition: hsm_key.c:716
const char * hsm_key_locator(const hsm_key_t *hsm_key)
Definition: hsm_key.c:520
db_clause_t * hsm_key_repository_clause(db_clause_list_t *clause_list, const char *repository_text)
Definition: hsm_key.c:882
hsm_key_list_t * hsm_key_list_new_get_by_clauses(const db_connection_t *connection, const db_clause_list_t *clause_list)
Definition: hsm_key.c:1726
enum hsm_key_backup hsm_key_backup_t
@ HSM_KEY_BACKUP_BACKUP_REQUESTED
Definition: hsm_key.h:68
@ HSM_KEY_BACKUP_BACKUP_DONE
Definition: hsm_key.h:69
@ HSM_KEY_BACKUP_BACKUP_REQUIRED
Definition: hsm_key.h:67
char const * hsm_key_to_backup_state(hsm_key_t const *hsm_key)
Definition: hsm_key_ext.c:34