1 /*
2 * util.c
3 * some handy function needed in drill and not implemented
4 * in ldns
5 * (c) 2005 NLnet Labs
6 *
7 * See the file LICENSE for the license
8 *
9 */
10
11 #include "drill.h"
12 #include <ldns/ldns.h>
13
14 #include <errno.h>
15
16 static int
read_line(FILE * input,char * line,size_t len)17 read_line(FILE *input, char *line, size_t len)
18 {
19 int i;
20 int c;
21
22 for (i = 0; i < (int)len-1; i++) {
23 c = getc(input);
24 if (c == EOF) {
25 return -1;
26 } else if (c != '\n') {
27 line[i] = c;
28 } else {
29 break;
30 }
31 }
32 line[i] = '\0';
33 return i;
34 }
35
36 /* key_list must be initialized with ldns_rr_list_new() */
37 ldns_status
read_key_file(const char * filename,ldns_rr_list * key_list,bool silently)38 read_key_file(const char *filename, ldns_rr_list *key_list, bool silently)
39 {
40 int line_len = 0;
41 int line_nr = 0;
42 int key_count = 0;
43 char line[LDNS_MAX_LINELEN];
44 ldns_status status;
45 FILE *input_file;
46 ldns_rr *rr;
47
48 input_file = fopen(filename, "r");
49 if (!input_file) {
50 if (! silently) {
51 fprintf(stderr, "Error opening %s: %s\n",
52 filename, strerror(errno));
53 }
54 return LDNS_STATUS_ERR;
55 }
56 while (line_len >= 0) {
57 line_len = (int) read_line(input_file, line, sizeof(line));
58 line_nr++;
59 if (line_len > 0 && line[0] != ';') {
60 status = ldns_rr_new_frm_str(&rr, line, 0, NULL, NULL);
61 if (status != LDNS_STATUS_OK) {
62 if (! silently) {
63 fprintf(stderr,
64 "Error parsing DNSKEY RR "
65 "in line %d: %s\n", line_nr,
66 ldns_get_errorstr_by_id(status)
67 );
68 }
69 } else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY ||
70 ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) {
71 ldns_rr_list_push_rr(key_list, rr);
72 key_count++;
73 } else {
74 ldns_rr_free(rr);
75 }
76 }
77 }
78 fclose(input_file);
79 if (key_count > 0) {
80 return LDNS_STATUS_OK;
81 } else {
82 /*fprintf(stderr, "No keys read\n");*/
83 return LDNS_STATUS_ERR;
84 }
85 }
86
87 ldns_rdf *
ldns_rdf_new_addr_frm_str(char * str)88 ldns_rdf_new_addr_frm_str(char *str)
89 {
90 ldns_rdf *a;
91
92 a = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, str);
93 if (!a) {
94 /* maybe ip6 */
95 a = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, str);
96 if (!a) {
97 return NULL;
98 }
99 }
100 return a;
101 }
102
103 static inline void
local_print_ds(FILE * out,const char * pre,ldns_rr * ds)104 local_print_ds(FILE* out, const char* pre, ldns_rr* ds)
105 {
106 if (out && ds) {
107 fprintf(out, "%s", pre);
108 ldns_rr_print(out, ds);
109 ldns_rr_free(ds);
110 }
111 }
112
113 /*
114 * For all keys in a packet print the DS
115 */
116 void
print_ds_of_keys(ldns_pkt * p)117 print_ds_of_keys(ldns_pkt *p)
118 {
119 ldns_rr_list *keys;
120 uint16_t i;
121 ldns_rr *ds;
122
123 /* TODO fix the section stuff, here or in ldns */
124 keys = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_DNSKEY,
125 LDNS_SECTION_ANSWER);
126
127 /* this also returns the question section rr, which does not
128 * have any data.... and this inturn crashes everything */
129
130 if (keys) {
131 for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
132 fprintf(stdout, ";\n; equivalent DS records for key %u:\n",
133 (unsigned int)ldns_calc_keytag(ldns_rr_list_rr(keys, i)));
134
135 ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA1);
136 local_print_ds(stdout, "; sha1: ", ds);
137 ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA256);
138 local_print_ds(stdout, "; sha256: ", ds);
139 }
140 ldns_rr_list_deep_free(keys);
141 }
142 }
143
144 static void
print_class_type(FILE * fp,ldns_rr * r)145 print_class_type(FILE *fp, ldns_rr *r)
146 {
147 ldns_lookup_table *lt;
148 lt = ldns_lookup_by_id(ldns_rr_classes, ldns_rr_get_class(r));
149 if (lt) {
150 fprintf(fp, " %s", lt->name);
151 } else {
152 fprintf(fp, " CLASS%d", ldns_rr_get_class(r));
153 }
154 /* okay not THE way - but the quickest */
155 switch (ldns_rr_get_type(r)) {
156 case LDNS_RR_TYPE_RRSIG:
157 fprintf(fp, " RRSIG ");
158 break;
159 case LDNS_RR_TYPE_DNSKEY:
160 fprintf(fp, " DNSKEY ");
161 break;
162 case LDNS_RR_TYPE_DS:
163 fprintf(fp, " DS ");
164 break;
165 default:
166 break;
167 }
168 }
169
170
171 void
print_ds_abbr(FILE * fp,ldns_rr * ds)172 print_ds_abbr(FILE *fp, ldns_rr *ds)
173 {
174 if (!ds || (ldns_rr_get_type(ds) != LDNS_RR_TYPE_DS)) {
175 return;
176 }
177
178 ldns_rdf_print(fp, ldns_rr_owner(ds));
179 fprintf(fp, " %d", (int)ldns_rr_ttl(ds));
180 print_class_type(fp, ds);
181 ldns_rdf_print(fp, ldns_rr_rdf(ds, 0)); fprintf(fp, " ");
182 ldns_rdf_print(fp, ldns_rr_rdf(ds, 1)); fprintf(fp, " ");
183 ldns_rdf_print(fp, ldns_rr_rdf(ds, 2)); fprintf(fp, " ");
184 ldns_rdf_print(fp, ldns_rr_rdf(ds, 3)); fprintf(fp, " ");
185 }
186
187 /* print some of the elements of a signature */
188 void
print_rrsig_abbr(FILE * fp,ldns_rr * sig)189 print_rrsig_abbr(FILE *fp, ldns_rr *sig) {
190 if (!sig || (ldns_rr_get_type(sig) != LDNS_RR_TYPE_RRSIG)) {
191 return;
192 }
193
194 ldns_rdf_print(fp, ldns_rr_owner(sig));
195 fprintf(fp, " %d", (int)ldns_rr_ttl(sig));
196 print_class_type(fp, sig);
197
198 /* print a number of rdf's */
199 /* typecovered */
200 ldns_rdf_print(fp, ldns_rr_rdf(sig, 0)); fprintf(fp, " ");
201 /* algo */
202 ldns_rdf_print(fp, ldns_rr_rdf(sig, 1)); fprintf(fp, " ");
203 /* labels */
204 ldns_rdf_print(fp, ldns_rr_rdf(sig, 2)); fprintf(fp, " (\n\t\t\t");
205 /* expir */
206 ldns_rdf_print(fp, ldns_rr_rdf(sig, 4)); fprintf(fp, " ");
207 /* incep */
208 ldns_rdf_print(fp, ldns_rr_rdf(sig, 5)); fprintf(fp, " ");
209 /* key-id */
210 ldns_rdf_print(fp, ldns_rr_rdf(sig, 6)); fprintf(fp, " ");
211 /* key owner */
212 ldns_rdf_print(fp, ldns_rr_rdf(sig, 7)); fprintf(fp, ")");
213 }
214
215 void
print_dnskey_abbr(FILE * fp,ldns_rr * key)216 print_dnskey_abbr(FILE *fp, ldns_rr *key)
217 {
218 if (!key || (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY)) {
219 return;
220 }
221
222 ldns_rdf_print(fp, ldns_rr_owner(key));
223 fprintf(fp, " %d", (int)ldns_rr_ttl(key));
224 print_class_type(fp, key);
225
226 /* print a number of rdf's */
227 /* flags */
228 ldns_rdf_print(fp, ldns_rr_rdf(key, 0)); fprintf(fp, " ");
229 /* proto */
230 ldns_rdf_print(fp, ldns_rr_rdf(key, 1)); fprintf(fp, " ");
231 /* algo */
232 ldns_rdf_print(fp, ldns_rr_rdf(key, 2));
233
234 if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 256) {
235 fprintf(fp, " ;{id = %u (zsk), size = %db}", (unsigned int)ldns_calc_keytag(key),
236 (int)ldns_rr_dnskey_key_size(key));
237 return;
238 }
239 if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 257) {
240 fprintf(fp, " ;{id = %u (ksk), size = %db}", (unsigned int)ldns_calc_keytag(key),
241 (int)ldns_rr_dnskey_key_size(key));
242 return;
243 }
244 fprintf(fp, " ;{id = %u, size = %db}", (unsigned int)ldns_calc_keytag(key),
245 (int)ldns_rr_dnskey_key_size(key));
246 }
247
248 void
print_rr_list_abbr(FILE * fp,ldns_rr_list * rrlist,const char * usr)249 print_rr_list_abbr(FILE *fp, ldns_rr_list *rrlist, const char *usr)
250 {
251 size_t i;
252 ldns_rr_type tp;
253
254 for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
255 tp = ldns_rr_get_type(ldns_rr_list_rr(rrlist, i));
256 if (i == 0 && tp != LDNS_RR_TYPE_RRSIG) {
257 if (usr) {
258 fprintf(fp, "%s ", usr);
259 }
260 }
261 switch(tp) {
262 case LDNS_RR_TYPE_DNSKEY:
263 print_dnskey_abbr(fp, ldns_rr_list_rr(rrlist, i));
264 break;
265 case LDNS_RR_TYPE_RRSIG:
266 print_rrsig_abbr(fp, ldns_rr_list_rr(rrlist, i));
267 break;
268 case LDNS_RR_TYPE_DS:
269 print_ds_abbr(fp, ldns_rr_list_rr(rrlist, i));
270 break;
271 default:
272 /* not handled */
273 break;
274 }
275 fputs("\n", fp);
276 }
277 }
278
279 void *
xmalloc(size_t s)280 xmalloc(size_t s)
281 {
282 void *p;
283
284 p = malloc(s);
285 if (!p) {
286 printf("Mem failure\n");
287 exit(EXIT_FAILURE);
288 }
289 return p;
290 }
291
292 void *
xrealloc(void * p,size_t size)293 xrealloc(void *p, size_t size)
294 {
295 void *q;
296
297 q = realloc(p, size);
298 if (!q) {
299 printf("Mem failure\n");
300 exit(EXIT_FAILURE);
301 }
302 return q;
303 }
304
305 void
xfree(void * p)306 xfree(void *p)
307 {
308 if (p) {
309 free(p);
310 }
311 }
312