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