• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

/build/buildd-opendnssec_1.3.2-1~bpo60+1-sparc-g2IJWF/opendnssec-1.3.2/signer/src/signer/denial.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (c) 2011 NLNet Labs. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00021  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00023  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00025  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  */
00028 
00034 #include "config.h"
00035 #include "shared/allocator.h"
00036 #include "shared/log.h"
00037 #include "signer/denial.h"
00038 #include "signer/domain.h"
00039 #include "signer/nsec3params.h"
00040 
00041 #include <ldns/ldns.h>
00042 
00043 #define SE_MAX_RRTYPE_COUNT 65536
00044 
00045 static const char* denial_str = "denial";
00046 
00047 
00052 denial_type*
00053 denial_create(ldns_rdf* owner)
00054 {
00055     allocator_type* allocator = NULL;
00056     denial_type* denial = NULL;
00057     char* str = NULL;
00058 
00059     if (!owner) {
00060         ods_log_error("[%s] unable to create denial of existence data point: "
00061             "no owner name", denial_str);
00062         return NULL;
00063     }
00064     ods_log_assert(owner);
00065 
00066     allocator = allocator_create(malloc, free);
00067     if (!allocator) {
00068         str = ldns_rdf2str(owner);
00069         ods_log_error("[%s] unable to create denial of existence data point: "
00070             "%s: create allocator failed", denial_str, str?str:"(null)");
00071         free((void*)str);
00072         return NULL;
00073     }
00074     ods_log_assert(allocator);
00075 
00076     denial = (denial_type*) allocator_alloc(allocator, sizeof(denial_type));
00077     if (!denial) {
00078         str = ldns_rdf2str(denial->owner);
00079         ods_log_error("[%s] unable to create denial of existence data point: "
00080             "%s: allocator failed", denial_str, str?str:"(null)");
00081         free((void*)str);
00082         allocator_cleanup(allocator);
00083         return NULL;
00084     }
00085     ods_log_assert(denial);
00086 
00087     denial->allocator = allocator;
00088     denial->owner = ldns_rdf_clone(owner);
00089     denial->bitmap_changed = 0;
00090     denial->nxt_changed = 0;
00091     denial->rrset = NULL;
00092     denial->domain = NULL;
00093     return denial;
00094 }
00095 
00096 
00101 static void
00102 denial_create_bitmap(denial_type* denial, ldns_rr_type types[],
00103     size_t* types_count)
00104 {
00105     ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00106     domain_type* domain = NULL;
00107     rrset_type* rrset = NULL;
00108 
00109     ods_log_assert(denial->domain);
00110 
00111     domain = (domain_type*) denial->domain;
00112     node = ldns_rbtree_first(domain->rrsets);
00113 
00114     while (node && node != LDNS_RBTREE_NULL) {
00115         rrset = (rrset_type*) node->data;
00116         types[*types_count] = rrset->rr_type;
00117         *types_count = *types_count + 1;
00118         node = ldns_rbtree_next(node);
00119     }
00120     return;
00121 }
00122 
00123 
00128 static ldns_rr*
00129 denial_create_nsec(denial_type* denial, denial_type* nxt, uint32_t ttl,
00130     ldns_rr_class klass)
00131 {
00132     ldns_rr* nsec_rr = NULL;
00133     ldns_rdf* rdf = NULL;
00134     ldns_rr_type types[SE_MAX_RRTYPE_COUNT];
00135     size_t types_count = 0;
00136 
00137     ods_log_assert(denial);
00138     ods_log_assert(denial->owner);
00139     ods_log_assert(nxt);
00140     ods_log_assert(nxt->owner);
00141 
00142     nsec_rr = ldns_rr_new();
00143     if (!nsec_rr) {
00144         ods_log_alert("[%s] unable to create NSEC RR: ldns error",
00145             denial_str);
00146         return NULL;
00147     }
00148     ods_log_assert(nsec_rr);
00149 
00150     ldns_rr_set_type(nsec_rr, LDNS_RR_TYPE_NSEC);
00151     rdf = ldns_rdf_clone(denial->owner);
00152     if (!rdf) {
00153         ods_log_alert("[%s] unable to create NSEC RR: failed to clone owner",
00154             denial_str);
00155         ldns_rr_free(nsec_rr);
00156         return NULL;
00157     }
00158     ldns_rr_set_owner(nsec_rr, rdf);
00159 
00160     rdf = ldns_rdf_clone(nxt->owner);
00161     if (!rdf) {
00162         ods_log_alert("[%s] unable to create NSEC RR: failed to clone nxt",
00163             denial_str);
00164         ldns_rr_free(nsec_rr);
00165         return NULL;
00166     }
00167     ldns_rr_push_rdf(nsec_rr, rdf);
00168 
00169     /* create types bitmap */
00170     denial_create_bitmap(denial, types, &types_count);
00171     types[types_count] = LDNS_RR_TYPE_RRSIG;
00172     types_count++;
00173     types[types_count] = LDNS_RR_TYPE_NSEC;
00174     types_count++;
00175 
00176     rdf = ldns_dnssec_create_nsec_bitmap(types,
00177         types_count, LDNS_RR_TYPE_NSEC);
00178     if (!rdf) {
00179         ods_log_alert("[%s] unable to create NSEC RR: failed to create bitmap",
00180             denial_str);
00181         ldns_rr_free(nsec_rr);
00182         return NULL;
00183     }
00184     ldns_rr_push_rdf(nsec_rr, rdf);
00185     ldns_rr_set_ttl(nsec_rr, ttl);
00186     ldns_rr_set_class(nsec_rr, klass);
00187     return nsec_rr;
00188 }
00189 
00190 
00195 ods_status
00196 denial_nsecify(denial_type* denial, denial_type* nxt, uint32_t ttl,
00197     ldns_rr_class klass)
00198 {
00199     ldns_rr* nsec_rr = NULL;
00200     ods_status status = ODS_STATUS_OK;
00201 
00202     if (!denial) {
00203         ods_log_error("[%s] unable to nsecify: no data point", denial_str);
00204         return ODS_STATUS_ASSERT_ERR;
00205     }
00206     ods_log_assert(denial);
00207 
00208     if (!nxt) {
00209         ods_log_error("[%s] unable to nsecify: no next", denial_str);
00210         return ODS_STATUS_ASSERT_ERR;
00211     }
00212     ods_log_assert(nxt);
00213 
00214     if (denial->nxt_changed || denial->bitmap_changed) {
00215         /* assert there is a NSEC RRset */
00216         if (!denial->rrset) {
00217             denial->rrset = rrset_create(LDNS_RR_TYPE_NSEC);
00218             if (!denial->rrset) {
00219                  ods_log_alert("[%s] unable to nsecify: failed to "
00220                 "create NSEC RRset", denial_str);
00221                 return ODS_STATUS_ERR;
00222             }
00223         }
00224         ods_log_assert(denial->rrset);
00225         /* create new NSEC rr */
00226         nsec_rr = denial_create_nsec(denial, nxt, ttl, klass);
00227         if (!nsec_rr) {
00228             ods_log_alert("[%s] unable to nsecify: failed to "
00229                 "create NSEC RR", denial_str);
00230             return ODS_STATUS_ERR;
00231         }
00232         /* delete old NSEC RR(s)... */
00233         status = rrset_wipe_out(denial->rrset);
00234         if (status != ODS_STATUS_OK) {
00235             ods_log_alert("[%s] unable to nsecify: failed to "
00236                 "wipe out NSEC RRset", denial_str);
00237             ldns_rr_free(nsec_rr);
00238             return status;
00239         }
00240         /* ...and add the new one */
00241         if (!rrset_add_rr(denial->rrset, nsec_rr)) {
00242             ods_log_alert("[%s] unable to nsecify: failed to "
00243                 "add NSEC to RRset", denial_str);
00244             ldns_rr_free(nsec_rr);
00245             return ODS_STATUS_ERR;
00246         }
00247         /* commit */
00248         status = rrset_commit(denial->rrset);
00249         if (status != ODS_STATUS_OK) {
00250             ods_log_alert("[%s] unable to nsecify: failed to "
00251                 "commit the NSEC RRset", denial_str);
00252             return status;
00253         }
00254 
00255         /* ok */
00256         denial->bitmap_changed = 0;
00257         denial->nxt_changed = 0;
00258     }
00259     return ODS_STATUS_OK;
00260 }
00261 
00262 
00267 static ldns_rr*
00268 denial_create_nsec3(denial_type* denial, denial_type* nxt, uint32_t ttl,
00269     ldns_rr_class klass, nsec3params_type* nsec3params)
00270 {
00271     ldns_status status = LDNS_STATUS_OK;
00272     ldns_rr* nsec_rr = NULL;
00273     ldns_rdf* rdf = NULL;
00274     ldns_rdf* next_owner_label = NULL;
00275     ldns_rdf* next_owner_rdf = NULL;
00276     char* next_owner_string = NULL;
00277     domain_type* domain = NULL;
00278     ldns_rr_type types[SE_MAX_RRTYPE_COUNT];
00279     size_t types_count = 0;
00280     int i = 0;
00281 
00282     ods_log_assert(denial);
00283     ods_log_assert(denial->owner);
00284     ods_log_assert(nxt);
00285     ods_log_assert(nxt->owner);
00286     ods_log_assert(nsec3params);
00287 
00288     nsec_rr = ldns_rr_new();
00289     if (!nsec_rr) {
00290         ods_log_alert("[%s] unable to create NSEC3 RR: ldns error",
00291             denial_str);
00292         return NULL;
00293     }
00294     ods_log_assert(nsec_rr);
00295 
00296     ldns_rr_set_type(nsec_rr, LDNS_RR_TYPE_NSEC3);
00297     rdf = ldns_rdf_clone(denial->owner);
00298     if (!rdf) {
00299         ods_log_alert("[%s] unable to create NSEC3 RR: failed to clone owner",
00300             denial_str);
00301         ldns_rr_free(nsec_rr);
00302         return NULL;
00303     }
00304     ldns_rr_set_owner(nsec_rr, rdf);
00305 
00306     /* set all to NULL first, then call nsec3_add_param_rdfs. */
00307     for (i=0; i < SE_NSEC3_RDATA_NSEC3PARAMS; i++) {
00308         ldns_rr_push_rdf(nsec_rr, NULL);
00309     }
00310     ldns_nsec3_add_param_rdfs(nsec_rr, nsec3params->algorithm,
00311         nsec3params->flags, nsec3params->iterations,
00312         nsec3params->salt_len, nsec3params->salt_data);
00313     /* nxt owner label */
00314     next_owner_label = ldns_dname_label(nxt->owner, 0);
00315     if (!next_owner_label) {
00316         ods_log_alert("[%s] unable to create NSEC3 RR: failed to get nxt "
00317             "owner label", denial_str);
00318         ldns_rr_free(nsec_rr);
00319         return NULL;
00320     }
00321     next_owner_string = ldns_rdf2str(next_owner_label);
00322     if (!next_owner_string) {
00323         ods_log_alert("[%s] unable to create NSEC3 RR: failed to get nxt "
00324             "owner string", denial_str);
00325         ldns_rdf_deep_free(next_owner_label);
00326         ldns_rr_free(nsec_rr);
00327         return NULL;
00328     }
00329     if (next_owner_string[strlen(next_owner_string)-1] == '.') {
00330         next_owner_string[strlen(next_owner_string)-1] = '\0';
00331     }
00332     status = ldns_str2rdf_b32_ext(&next_owner_rdf, next_owner_string);
00333     free((void*)next_owner_string);
00334     ldns_rdf_deep_free(next_owner_label);
00335     if (status != LDNS_STATUS_OK) {
00336         ods_log_alert("[%s] unable to create NSEC3 RR: failed to create nxt "
00337             "owner rdf: %s", denial_str, ldns_get_errorstr_by_id(status));
00338         ldns_rr_free(nsec_rr);
00339         return NULL;
00340     }
00341     ldns_rr_push_rdf(nsec_rr, next_owner_rdf);
00342 
00343     /* create types bitmap */
00344     denial_create_bitmap(denial, types, &types_count);
00345     /* only add RRSIG type if we have authoritative data to sign */
00346     domain = (domain_type*) denial->domain;
00347     if (domain_count_rrset(domain) > 0 &&
00348         (domain->dstatus == DOMAIN_STATUS_APEX ||
00349          domain->dstatus == DOMAIN_STATUS_AUTH ||
00350          domain->dstatus == DOMAIN_STATUS_DS)) {
00351         types[types_count] = LDNS_RR_TYPE_RRSIG;
00352         types_count++;
00353     }
00354     /* and don't add NSEC3 type... */
00355     rdf = ldns_dnssec_create_nsec_bitmap(types,
00356         types_count, LDNS_RR_TYPE_NSEC3);
00357     if (!rdf) {
00358         ods_log_alert("[%s] unable to create NSEC3 RR: failed to create "
00359             "bitmap", denial_str);
00360         ldns_rr_free(nsec_rr);
00361         return NULL;
00362     }
00363     ldns_rr_push_rdf(nsec_rr, rdf);
00364     ldns_rr_set_ttl(nsec_rr, ttl);
00365     ldns_rr_set_class(nsec_rr, klass);
00366     return nsec_rr;
00367 }
00368 
00369 
00374 ods_status
00375 denial_nsecify3(denial_type* denial, denial_type* nxt, uint32_t ttl,
00376     ldns_rr_class klass, nsec3params_type* nsec3params)
00377 {
00378     ldns_rr* nsec_rr = NULL;
00379     ods_status status = ODS_STATUS_OK;
00380 
00381     if (!denial) {
00382         ods_log_error("[%s] unable to nsecify3: no data point", denial_str);
00383         return ODS_STATUS_ASSERT_ERR;
00384     }
00385     ods_log_assert(denial);
00386 
00387     if (!nxt) {
00388         ods_log_error("[%s] unable to nsecify3: no next", denial_str);
00389         return ODS_STATUS_ASSERT_ERR;
00390     }
00391     ods_log_assert(nxt);
00392 
00393     if (denial->nxt_changed || denial->bitmap_changed) {
00394         /* assert there is a NSEC RRset */
00395         if (!denial->rrset) {
00396             denial->rrset = rrset_create(LDNS_RR_TYPE_NSEC3);
00397             if (!denial->rrset) {
00398                  ods_log_alert("[%s] unable to nsecify3: failed to "
00399                 "create NSEC3 RRset", denial_str);
00400                 return ODS_STATUS_ERR;
00401             }
00402         }
00403         ods_log_assert(denial->rrset);
00404         /* create new NSEC3 rr */
00405         nsec_rr = denial_create_nsec3(denial, nxt, ttl, klass, nsec3params);
00406         if (!nsec_rr) {
00407             ods_log_alert("[%s] unable to nsecify3: failed to "
00408                 "create NSEC3 RR", denial_str);
00409             return ODS_STATUS_ERR;
00410         }
00411         ods_log_assert(nsec_rr);
00412         /* delete old NSEC RR(s) */
00413         status = rrset_wipe_out(denial->rrset);
00414         if (status != ODS_STATUS_OK) {
00415             ods_log_alert("[%s] unable to nsecify3: failed to "
00416                 "wipe out NSEC3 RRset", denial_str);
00417             return status;
00418         }
00419        /* add the new one */
00420         if (!rrset_add_rr(denial->rrset, nsec_rr)) {
00421             ods_log_alert("[%s] unable to nsecify3: failed to "
00422                 "add NSEC3 to RRset", denial_str);
00423             return ODS_STATUS_ERR;
00424         }
00425         /* commit */
00426         status = rrset_commit(denial->rrset);
00427         if (status != ODS_STATUS_OK) {
00428             ods_log_alert("[%s] unable to nsecify3: failed to "
00429                 "commit the NSEC3 RRset", denial_str);
00430             return status;
00431         }
00432         /* ok */
00433         denial->bitmap_changed = 0;
00434         denial->nxt_changed = 0;
00435     }
00436     return ODS_STATUS_OK;
00437 }
00438 
00439 
00444 void
00445 denial_cleanup(denial_type* denial)
00446 {
00447     allocator_type* allocator;
00448 
00449     if (!denial) {
00450         return;
00451     }
00452     allocator = denial->allocator;
00453 
00454     if (denial->owner) {
00455         ldns_rdf_deep_free(denial->owner);
00456         denial->owner = NULL;
00457     }
00458     if (denial->rrset) {
00459         rrset_cleanup(denial->rrset);
00460         denial->rrset = NULL;
00461     }
00462 
00463     allocator_deallocate(allocator, (void*) denial);
00464     allocator_cleanup(allocator);
00465     return;
00466 
00467 }

Generated on Sat Dec 17 2011 11:48:48 for OpenDNSSEC-signer by  doxygen 1.7.1