OpenDNSSEC-enforcer 2.1.10
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
47static const char *module_str = "backup_hsmkeys_cmd";
48
49enum {
53 LIST
54};
55
56static int
57hsmkeys_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
88static int
89prepare(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
100static int
101commit(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
112static int
113rollback(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
124static int
125list(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
147static void
148usage(int sockfd)
149{
150 client_printf(sockfd,
151 "backup [list|prepare|commit|rollback]\n"
152 " --repository <repository> aka -r\n");
153}
154
155static void
156help(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
179static int
180handles(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
190static int
191run(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
259struct 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 char * hsm_key_locator(const hsm_key_t *hsm_key)
Definition: hsm_key.c:520
const hsm_key_t * hsm_key_list_next(hsm_key_list_t *hsm_key_list)
Definition: hsm_key.c:1924
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
db_clause_t * hsm_key_backup_clause(db_clause_list_t *clause_list, hsm_key_backup_t backup)
Definition: hsm_key.c:906
int hsm_key_set_backup(hsm_key_t *hsm_key, hsm_key_backup_t backup)
Definition: hsm_key.c:716
db_clause_t * hsm_key_repository_clause(db_clause_list_t *clause_list, const char *repository_text)
Definition: hsm_key.c:882
hsm_key_t * hsm_key_list_get_next(hsm_key_list_t *hsm_key_list)
Definition: hsm_key.c:1990
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