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