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