OpenDNSSEC-enforcer 2.1.13
key_purge.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 NLNet Labs. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26#include "key_purge.h"
27#include "clientpipe.h"
28#include "log.h"
30
31static void free_all(key_data_list_t *key_list, key_data_t** keylist,
32 key_dependency_list_t *deplist, key_dependency_t **deplist2,
33 zone_db_t *zone)
34{
35 int i;
36
38 deplist = NULL;
39
40 key_data_list_free(key_list);
41 key_list = NULL;
42
43 if (keylist) {
44 int keylist_size = key_data_list_size(key_list);
45 for (i = 0; i < keylist_size; i++) {
46 key_data_free(keylist[i]);
47 }
48 free(keylist);
49 keylist = NULL;
50 }
51
52 if (deplist2) {
53 int deplist2_size = key_dependency_list_size(deplist);
54 for (i = 0; i < deplist2_size; i++){
55 key_dependency_free(deplist2[i]);
56 }
57 free(deplist2);
58 deplist2 = NULL;
59 }
60
61 zone_db_free(zone);
62}
63
64
65int removeDeadKeysNow(int sockfd, db_connection_t *dbconn,
66 policy_t *policy, zone_db_t *rzone, int purge)
67{
68 static const char *scmd = "removeDeadKeysNow";
69 size_t i, deplist2_size = 0;
70 int key_purgable, cmp;
71 int zone_key_purgable;
72 unsigned int j;
73 const key_state_t* state = NULL;
74 key_data_list_t *key_list = NULL;
75 key_data_t** keylist = NULL;
76 key_dependency_list_t *deplist = NULL;
77 key_dependency_t **deplist2 = NULL;
78 size_t keylist_size;
79 zone_list_db_t *zonelist = NULL;
80 zone_db_t *zone = NULL;
81 int listsize = 0;
82
83
84 if (!dbconn) {
85 ods_log_error("[%s] no dbconn", scmd);
86 client_printf_err(sockfd, "[%s] no dbconn", scmd);
87 return 1;
88 }
89
90 if (policy) {
92 ods_log_error("[%s] Error fetching zones", scmd);
93 client_printf_err(sockfd, "[%s] Error fetching zones", scmd);
94 return 1;
95 }
96 zonelist = policy_zone_list(policy);
97 listsize = zone_list_db_size(zonelist);
98 if (listsize == 0) {
99 client_printf (sockfd, "No zones on policy %s\n", policy_name(policy));
100 client_printf (sockfd, "No keys to purge\n");
101 return 0;
102 }
103 zone = zone_list_db_get_next(zonelist);
104 } else if (rzone) {
105 listsize = 1;
106 zone = zone_db_new_copy(rzone);
107 }
108
109
110 while (listsize > 0 ) {
111 zone_key_purgable = 0;
112 if (!(deplist = zone_db_get_key_dependencies(zone))) {
113 /* TODO: better log error */
114 ods_log_error("[%s] error zone_db_get_key_dependencies()", scmd);
115 client_printf_err(sockfd, "%s: error zone_db_get_key_dependencies()", scmd);
116 free_all(key_list, keylist, deplist, deplist2, zone);
117 return 1;
118 }
119
120 if (!(key_list = zone_db_get_keys(zone))) {
121 /* TODO: better log error */
122 ods_log_error("[%s] error zone_db_get_keys()", scmd);
123 client_printf_err(sockfd, "%s: error zone_db_get_keys()", scmd);
124 free_all(key_list, keylist, deplist, deplist2, zone);
125 return 1;
126 }
127 keylist_size = key_data_list_size(key_list);
128
129 if (keylist_size) {
130 if (!(keylist = (key_data_t**)calloc(keylist_size, sizeof(key_data_t*)))) {
131 /* TODO: better log error */
132 ods_log_error("[%s] error calloc(keylist_size)", scmd);
133 client_printf_err(sockfd, "[%s] error calloc(keylist_size)", scmd);
134 free_all(key_list, keylist, deplist, deplist2, zone);
135 return 1;
136 }
137 for (i = 0; i < keylist_size; i++) {
138 if (!i)
139 keylist[i] = key_data_list_get_begin(key_list);
140 else
141 keylist[i] = key_data_list_get_next(key_list);
142 if (!keylist[i]
143 || key_data_cache_hsm_key(keylist[i])
144 || key_data_cache_key_states(keylist[i])) {
145 ods_log_error("[%s] error key_data_list cache", scmd);
146 client_printf_err(sockfd, "[%s] error key_data_list cache", scmd);
147 free_all(key_list, keylist, deplist, deplist2, zone);
148 return 1;
149 }
150 }
151 }
152 key_data_list_free(key_list);
153 key_list = NULL;
154
155 deplist2_size = key_dependency_list_size(deplist);
156 deplist2 = (key_dependency_t**)calloc(deplist2_size, sizeof(key_dependency_t*));
157 /* deplist might be NULL but is always freeable */
158 if (deplist2_size > 0)
159 deplist2[0] = key_dependency_list_get_begin(deplist);
160 for (i = 1; i < deplist2_size; i++)
161 deplist2[i] = key_dependency_list_get_next(deplist);
163 deplist = NULL;
164
165 for (i = 0; i < keylist_size; i++) {
166 if (key_data_introducing(keylist[i])) continue;
167 key_purgable = 1;
168 for (j = 0; j<4; j++) {
169 switch(j){
170 case 0: state = key_data_cached_ds(keylist[i]); break;
171 case 1: state = key_data_cached_dnskey(keylist[i]); break;
172 case 2: state = key_data_cached_rrsigdnskey(keylist[i]); break;
173 case 3: state = key_data_cached_rrsig(keylist[i]); break;
174 default: state = NULL;
175 }
176 if (key_state_state(state) == KEY_STATE_STATE_NA) continue;
178 key_purgable = 0;
179 break;
180 }
181 }
182 if (key_purgable) {
183 zone_key_purgable = 1;
184 /* key is purgable */
185 ods_log_info("[%s] deleting key: %s", scmd,
187 client_printf (sockfd, "deleting key: %s\n",
189
190 /* FIXME: key_data_cached_ds spits out const
191 * key_state_delete discards that. */
192 if (key_state_delete(key_data_cached_ds(keylist[i]))
196 || key_data_delete(keylist[i])
198 /* TODO: better log error */
199 ods_log_error("[%s] key_state_delete() || key_data_delete() || hsm_key_factory_release_key() failed", scmd);
200 client_printf_err(sockfd, "[%s] key_state_delete() || key_data_delete() || hsm_key_factory_release_key() failed", scmd);
201 free_all(key_list, keylist, deplist, deplist2, zone);
202 return 1;
203 }
204 /* we can clean up dependency because key is purgable */
205
206 for (j = 0; j < deplist2_size; j++) {
207 if (!deplist2[j]) continue;
208 if (db_value_cmp(key_data_id(keylist[i]), key_dependency_from_key_data_id(deplist2[j]), &cmp)) {
209 /* TODO: better log error */
210 ods_log_error("[%s] cmp deplist from failed", scmd);
211 client_printf_err(sockfd, "[%s] cmp deplist from failed", scmd);
212 break;
213 }
214 if(cmp) continue;
215
216 if (key_dependency_delete(deplist2[j])) {
217 /* TODO: better log error */
218 ods_log_error("[%s] key_dependency_delete() failed", scmd);
219 client_printf_err(sockfd, "[%s] key_dependency_delete() failed", scmd);
220 break;
221 }
222 }
223 }
224
225 }
226 if (zone_key_purgable == 0)
227 client_printf (sockfd, "No keys to purge for %s \n", zone_db_name(zone));
228
229 free_all(key_list, keylist, deplist, deplist2, zone);
230
231 listsize--;
232 if (listsize > 0) {
233 zone = zone_list_db_get_next(zonelist);
234 }
235 }
236
237 if(purge) {
238 int deleteCount = hsm_key_factory_delete_key(dbconn);
239 if(deleteCount > 0)
240 client_printf (sockfd, "Number of keys deleted from HSM is %d\n", deleteCount);
241 else
242 client_printf (sockfd, "Found no keys to delete from HSM\n");
243 } else
244 client_printf (sockfd, "Refrained from deleting keys from HSM\n");
245
246 return 0;
247}
int db_value_cmp(const db_value_t *value_a, const db_value_t *value_b, int *result)
Definition db_value.c:102
const char * hsm_key_locator(const hsm_key_t *hsm_key)
Definition hsm_key.c:520
const db_value_t * hsm_key_id(const hsm_key_t *hsm_key)
Definition hsm_key.c:504
int hsm_key_factory_delete_key(const db_connection_t *connection)
int hsm_key_factory_release_key_id(const db_value_t *hsm_key_id, const db_connection_t *connection)
const db_value_t * key_data_id(const key_data_t *key_data)
Definition key_data.c:553
size_t key_data_list_size(key_data_list_t *key_data_list)
Definition key_data.c:2461
int key_data_delete(key_data_t *key_data)
Definition key_data.c:1587
void key_data_free(key_data_t *key_data)
Definition key_data.c:304
void key_data_list_free(key_data_list_t *key_data_list)
Definition key_data.c:1694
unsigned int key_data_introducing(const key_data_t *key_data)
Definition key_data.c:727
key_data_t * key_data_list_get_next(key_data_list_t *key_data_list)
Definition key_data.c:2425
int key_data_cache_hsm_key(key_data_t *key_data)
Definition key_data.c:615
key_data_t * key_data_list_get_begin(key_data_list_t *key_data_list)
Definition key_data.c:2323
const key_state_t * key_data_cached_rrsig(key_data_t *key_data)
int key_data_cache_key_states(key_data_t *key_data)
const key_state_t * key_data_cached_dnskey(key_data_t *key_data)
const hsm_key_t * key_data_cached_hsm_key(const key_data_t *key_data)
const key_state_t * key_data_cached_ds(key_data_t *key_data)
const key_state_t * key_data_cached_rrsigdnskey(key_data_t *key_data)
void key_dependency_free(key_dependency_t *key_dependency)
key_dependency_t * key_dependency_list_get_next(key_dependency_list_t *key_dependency_list)
void key_dependency_list_free(key_dependency_list_t *key_dependency_list)
const db_value_t * key_dependency_from_key_data_id(const key_dependency_t *key_dependency)
size_t key_dependency_list_size(key_dependency_list_t *key_dependency_list)
int key_dependency_delete(key_dependency_t *key_dependency)
key_dependency_t * key_dependency_list_get_begin(key_dependency_list_t *key_dependency_list)
int removeDeadKeysNow(int sockfd, db_connection_t *dbconn, policy_t *policy, zone_db_t *rzone, int purge)
Definition key_purge.c:65
int key_state_delete(const key_state_t *key_state)
Definition key_state.c:831
key_state_state
Definition key_state.h:49
@ KEY_STATE_STATE_NA
Definition key_state.h:55
@ KEY_STATE_STATE_HIDDEN
Definition key_state.h:51
zone_list_db_t * policy_zone_list(policy_t *policy)
Definition policy.c:1093
const char * policy_name(const policy_t *policy)
Definition policy.c:813
int policy_retrieve_zone_list(policy_t *policy)
Definition policy.c:1111
void zone_db_free(zone_db_t *zone)
Definition zone_db.c:325
const char * zone_db_name(const zone_db_t *zone)
Definition zone_db.c:782
zone_db_t * zone_list_db_get_next(zone_list_db_t *zone_list)
Definition zone_db.c:2669
size_t zone_list_db_size(zone_list_db_t *zone_list)
Definition zone_db.c:2705
zone_db_t * zone_db_new_copy(const zone_db_t *zone)
Definition zone_db.c:306
key_dependency_list_t * zone_db_get_key_dependencies(const zone_db_t *zone)
Definition zone_db_ext.c:76
key_data_list_t * zone_db_get_keys(const zone_db_t *zone)
Definition zone_db_ext.c:56