-
Notifications
You must be signed in to change notification settings - Fork 26
/
nsec.c
148 lines (132 loc) · 4.13 KB
/
nsec.c
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 <[email protected]>
* 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 };