1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
/*
* Part of DNS zone file validator `validns`.
604800 NSEC example.com. NS DS RRSIG NSEC
604800 RRSIG NSEC 10 3 604800 20130321184221 (
20130219184221 35615 example.com.
WWg7EiYoY8Hp593I2i5Mkl2ezg7YuAnq0y75
oymTCuEfGwh4OxbMT/mWNqAFL5Y8f0YoQOOY
wZP0m/sGK/EJN7ulNsfQyULY4WsyHIGlKMwT
KdyDXJLrmrzlmRnGv7pFb0bo53n3osE0uFfH
yMQYOkQRYfqa4yWXF9Nl48dy67frtVih0foy
9Mm76mmJSDUd/jGsYQmaoFGVU/a64rWapVQ9
O/mXPqr6Pw2ZCHecsF4ElMEp41YqG1DfR5QR
khTjvTlg4aTKvgX1YuvDhjUygSHit47xn2NC
2WwEZF+vYXT9DIUCMcKdVeb4bjWwUXbWNFqz
Ca3jb/mpOpUDFnrRPw== )
*
* Copyright 2011-2014 Anton Berezin <tobez@tobez.org>
* Modified BSD license.
* (See LICENSE file in the distribution.)
*
*/
#include <ctype.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "common.h"
#include "textparse.h"
#include "mempool.h"
#include "carp.h"
#include "rr.h"
static struct rr* nsec_parse(char *name, long ttl, int type, char *s)
{
struct rr_nsec *rr = getmem(sizeof(*rr));
struct binary_data bitmap;
char *str_type = NULL;
int ltype;
rr->next_domain = extract_name(&s, "next domain", KEEP_CAPITALIZATION);
/* TODO: validate next_domain, http://tools.ietf.org/html/rfc4034#section-4.1.1 */
bitmap = new_set();
while (s && *s) {
str_type = extract_label(&s, "type list", "temporary");
if (!str_type) return NULL;
ltype = str2rdtype(str_type, NULL);
if (ltype < 0)
return NULL;
add_bit_to_set(&bitmap, ltype);
}
if (!s)
return NULL;
if (!str_type) {
return bitch("NSEC type list should not be empty");
}
rr->type_bitmap = compressed_set(&bitmap);
G.dnssec_active = 1;
return store_record(type, name, ttl, rr);
}
static char* nsec_human(struct rr *rrv)
{
RRCAST(nsec);
char ss[1024];
char *s = ss;
int l;
char *base;
int i, k;
int type;
char *type_name;
l = snprintf(s, 1024, "%s", rr->next_domain);
s += l;
base = rr->type_bitmap.data;
while (base - rr->type_bitmap.data < rr->type_bitmap.length) {
for (i = 0; i < base[1]; i++) {
for (k = 0; k <= 7; k++) {
if (base[2+i] & (0x80 >> k)) {
type = ((unsigned char)base[0])*256 + i*8 + k;
type_name = rdtype2str(type);
l = snprintf(s, 1024-(s-ss), " %s", type_name);
s += l;
}
}
}
base += base[1]+2;
}
return quickstrdup_temp(ss);
}
static struct binary_data nsec_wirerdata(struct rr *rrv)
{
RRCAST(nsec);
return compose_binary_data("dd", 1,
name2wire_name(rr->next_domain), rr->type_bitmap);
}
static void* nsec_validate(struct rr *rrv)
{
RRCAST(nsec);
struct named_rr *named_rr;
named_rr = rr->rr.rr_set->named_rr;
if (!check_typemap(rr->type_bitmap, named_rr, rrv))
return NULL;
return rr;
}
void validate_nsec_chain(void)
{
struct rr_set *rr_set;
struct named_rr *named_rr;
rr_set = find_rr_set(T_NSEC, zone_apex);
if (!rr_set) {
named_rr = find_named_rr(zone_apex);
moan(named_rr->file_name, named_rr->line, "apex NSEC not found");
return;
}
while (1) {
char name[1024];
struct rr_nsec *rr = (struct rr_nsec *)rr_set->tail;
char *s, *t;
if (strcasecmp(rr->next_domain, zone_apex) == 0) /* chain complete */
break;
freeall_temp();
s = rr->next_domain;
t = name;
while (*s) *t++ = tolower(*s++);
*t = 0;
rr_set = find_rr_set(T_NSEC, name);
if (!rr_set) {
moan(rr->rr.file_name, rr->rr.line, "broken NSEC chain %s -> %s",
rr->rr.rr_set->named_rr->name, rr->next_domain);
break;
}
}
freeall_temp();
}
struct rr_methods nsec_methods = { nsec_parse, nsec_human, nsec_wirerdata, NULL, nsec_validate };
|