1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * 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 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup
36 * @ingroup dnsdb
37 * @brief
38 *
39 *
40 *
41 * @{
42 */
43 /*------------------------------------------------------------------------------
44 *
45 * USE INCLUDES */
46 #include "dnsdb/dnsdb-config.h"
47 #include <dnscore/u32_set.h>
48 #include <dnscore/logger.h>
49 #include "dnsdb/zdb-zone-maintenance.h"
50 #include "dnsdb/rrsig.h"
51
52 extern logger_handle* g_database_logger;
53 #define MODULE_MSG_HANDLE g_database_logger
54
55 /**
56 * Updates the signatures of a zone incrementally.
57 * Each call goes a bit further.
58 *
59 * @param zone
60 * @param signature_count_loose_limit
61 * @param present_signatures_are_verified
62 * @return the number of actions counted
63 */
64
65 int
zdb_zone_maintenance_nsec(zdb_zone_maintenance_ctx * mctx,const zone_diff_fqdn * diff_fqdn,ptr_vector * rrset_to_sign)66 zdb_zone_maintenance_nsec(zdb_zone_maintenance_ctx* mctx, const zone_diff_fqdn *diff_fqdn, ptr_vector *rrset_to_sign)
67 {
68 // if NSEC created :
69 // _ add the NSEC record & signature if missing
70 // _ update the NSEC RRSIG
71 // _ add the NSEC node to the collection
72
73 // if NSEC removal :
74 // _ remove the NSEC record & signature
75 // _ remove the NSEC node from the collection
76
77 // NSEC signatures should be handled with the general signatures
78
79 int ret = 0;
80
81 if((mctx->nsec_chain_status & (NSEC_ZONE_GENERATING|NSEC_ZONE_REMOVING)) == NSEC_ZONE_GENERATING)
82 {
83 // add
84 zdb_packed_ttlrdata *nsec_rrset = zdb_record_find(&mctx->label->resource_record_set, TYPE_NSEC);
85 if(nsec_rrset == NULL)
86 {
87 // need to add the NSEC record and its signature
88 // difficult as the next record has to be known
89
90 ret = dnssec_chain_add_from_diff_fqdn(&mctx->nsec_chain_updater, diff_fqdn, 0);
91 }
92 }
93 else if((mctx->nsec_chain_status & (NSEC_ZONE_GENERATING|NSEC_ZONE_REMOVING)) == NSEC_ZONE_REMOVING)
94 {
95 // del
96 zdb_packed_ttlrdata *nsec_rrset = zdb_record_find(&mctx->label->resource_record_set, TYPE_NSEC);
97 if(nsec_rrset != NULL)
98 {
99 // need to remove the NSEC record(s) and its signature(s)
100 // simple to do
101 ret = dnssec_chain_del_from_diff_fqdn(&mctx->nsec_chain_updater, diff_fqdn, 0);
102 }
103 }
104 else
105 {
106 if(rrset_to_sign != NULL)
107 {
108 #if DEBUG
109 log_debug1("maintenance: %{dnsname}: looking at NSEC RRSIG coverage", mctx->zone->origin);
110 #endif
111 if(zone_diff_will_have_rrset_type(diff_fqdn, TYPE_NSEC))
112 {
113 zone_diff_fqdn_rr_set *nsec_rrset = zone_diff_fqdn_rr_set_get((zone_diff_fqdn *) diff_fqdn, TYPE_NSEC);
114
115 if(nsec_rrset != NULL)
116 {
117 #if DEBUG
118 log_debug1("maintenance: %{dnsname}: NSEC RRSET exists", mctx->zone->origin);
119 #endif
120 #if 0
121 zone_diff_fqdn_rr_set *rrsig_rrset = zone_diff_fqdn_rr_set_get((zone_diff_fqdn *) diff_fqdn, TYPE_RRSIG);
122 #endif
123 bool sign_nsec_rrset = TRUE;
124 #if 0
125 if(rrsig_rrset != NULL)
126 {
127 bool has_one_valid_signature = FALSE;
128 sign_nsec_rrset = FALSE;
129
130 ptr_set_iterator rr_iter;
131 ptr_set_iterator_init(&rrsig_rrset->rr, &rr_iter);
132 while(ptr_set_iterator_hasnext(&rr_iter))
133 {
134 ptr_node *node = ptr_set_iterator_next_node(&rr_iter);
135 zone_diff_label_rr *rr = (zone_diff_label_rr *)node->key;
136
137 if((rr->state & ZONE_DIFF_RR_REMOVE) != 0)
138 {
139 continue; // signature is being removed already: ignore
140 }
141
142 u16 covered_type = rrsig_get_type_covered_from_rdata(rr->rdata, rr->rdata_size);
143
144 if(covered_type == TYPE_NSEC)
145 {
146 s32 key_index = -2;
147 if(rrsig_should_remove_signature_from_rdata(
148 rr->rdata, rr->rdata_size,
149 &mctx->zsks, mctx->now, mctx->zone->sig_validity_regeneration_seconds, &key_index) && (key_index != -1))
150 {
151 #if DEBUG
152 log_debug1("maintenance: %{dnsname}: NSEC RRSET signature should be removed", mctx->zone->origin);
153 #endif
154 sign_nsec_rrset = TRUE;
155 break;
156 }
157 else
158 {
159 #if DEBUG
160 log_debug1("maintenance: %{dnsname}: NSEC RRSET is covered by at least one signature", mctx->zone->origin);
161 #endif
162 has_one_valid_signature = TRUE;
163 }
164 }
165 }
166
167 sign_nsec_rrset |= has_one_valid_signature;
168 }
169 else
170 {
171 #if DEBUG
172 log_debug1("maintenance: %{dnsname}: NSEC RRSET and there are no signatures at all on the label", mctx->zone->origin);
173 #endif
174 sign_nsec_rrset = TRUE;
175 }
176 #endif
177 if(sign_nsec_rrset) // always true ...
178 {
179 for(int i = 0; i <= ptr_vector_last_index(rrset_to_sign); ++i)
180 {
181 if(ptr_vector_get(rrset_to_sign, i) == nsec_rrset)
182 {
183 sign_nsec_rrset = FALSE;
184 break;
185 }
186 }
187
188 if(sign_nsec_rrset)
189 {
190 #if DEBUG
191 u16 rtype = TYPE_NSEC;
192 log_debug1("maintenance: %{dnsname}: %{dnsname} %{dnstype} will have its RRSIGs updated",
193 mctx->zone->origin,
194 diff_fqdn->fqdn,
195 &rtype);
196 #endif
197 ptr_vector_append(rrset_to_sign, nsec_rrset);
198 ++ret;
199 }
200 else
201 {
202 log_debug1("maintenance: %{dnsname}: NSEC RRSET is already marked for signature", mctx->zone->origin);
203 }
204 }
205 else
206 {
207 #if DEBUG
208 log_debug1("maintenance: %{dnsname}: NSEC RRSET does not need to be signed again", mctx->zone->origin);
209 #endif
210 }
211 }
212 }
213 }
214 }
215 return ret;
216 }
217
218 /** @} */
219