getdns_return_t getdns_convert_fqdn_to_dns_name( const char *fqdn_as_string, struct getdns_bindata **dns_name_wire_fmt) { ldns_rdf *rdf; if (ldns_str2rdf_dname(&rdf, fqdn_as_string) != LDNS_STATUS_OK) return GETDNS_RETURN_GENERIC_ERROR;; *dns_name_wire_fmt = malloc(sizeof(struct getdns_bindata)); if (*dns_name_wire_fmt) { (*dns_name_wire_fmt)->size = ldns_rdf_size(rdf); (*dns_name_wire_fmt)->data = ldns_rdf_data(rdf); } ldns_rdf_free(rdf); return *dns_name_wire_fmt ? GETDNS_RETURN_GOOD : GETDNS_RETURN_MEMORY_ERROR; }
/** parse ORIGIN */ static void get_origin(const char* name, int lineno, ldns_rdf** origin, char* parse) { /* snip off rest of the text so as to make the parse work in ldns */ char* end; char store; ldns_status status; ldns_rdf_free(*origin); *origin = NULL; end=parse; while(!isspace((int)*end) && !isendline(*end)) end++; store = *end; *end = 0; verbose(3, "parsing '%s'\n", parse); status = ldns_str2rdf_dname(origin, parse); *end = store; if (status != LDNS_STATUS_OK) error("%s line %d:\n\t%s: %s", name, lineno, ldns_get_errorstr_by_id(status), parse); }
/** read all key files, exit on error */ static ldns_key_list* read_keys(int num, char* names[], struct keysets* set) { int i; ldns_key_list* keys = ldns_key_list_new(); ldns_key* k; ldns_rdf* rdf; ldns_status s; int b; FILE* in; if(!keys) fatal_exit("alloc failure"); for(i=0; i<num; i++) { printf("read keyfile %s\n", names[i]); in = fopen(names[i], "r"); if(!in) fatal_exit("could not open %s: %s", names[i], strerror(errno)); s = ldns_key_new_frm_fp(&k, in); fclose(in); if(s != LDNS_STATUS_OK) fatal_exit("bad keyfile %s: %s", names[i], ldns_get_errorstr_by_id(s)); ldns_key_set_expiration(k, set->expi); ldns_key_set_inception(k, set->incep); s = ldns_str2rdf_dname(&rdf, set->owner); if(s != LDNS_STATUS_OK) fatal_exit("bad owner name %s: %s", set->owner, ldns_get_errorstr_by_id(s)); ldns_key_set_pubkey_owner(k, rdf); ldns_key_set_flags(k, set->flags); ldns_key_set_keytag(k, set->keytag); b = ldns_key_list_push_key(keys, k); log_assert(b); } return keys; }
/** process nsec3 params and perform hashing */ static void process_nsec3(int argc, char* argv[]) { char line[10240]; ldns_rdf* salt; ldns_rdf* in, *out; ldns_status status; status = ldns_str2rdf_nsec3_salt(&salt, argv[5]); if(status != LDNS_STATUS_OK) fatal_exit("Could not parse salt %s: %s", argv[5], ldns_get_errorstr_by_id(status)); log_assert(argc == 6); while(fgets(line, (int)sizeof(line), stdin)) { if(strlen(line) > 0) line[strlen(line)-1] = 0; /* remove trailing newline */ if(line[0]==0) continue; status = ldns_str2rdf_dname(&in, line); if(status != LDNS_STATUS_OK) fatal_exit("Could not parse name %s: %s", line, ldns_get_errorstr_by_id(status)); ldns_rdf_print(stdout, in); printf(" -> "); /* arg 3 is flags, unused */ out = ldns_nsec3_hash_name(in, (uint8_t)atoi(argv[2]), (uint16_t)atoi(argv[4]), ldns_rdf_data(salt)[0], ldns_rdf_data(salt)+1); if(!out) fatal_exit("Could not hash %s", line); ldns_rdf_print(stdout, out); printf("\n"); ldns_rdf_deep_free(in); ldns_rdf_deep_free(out); } ldns_rdf_deep_free(salt); }
void zkdns_start(const char* my_address, int port, const char* my_zone) { rp_handle = rp_initialize(my_zone); /* network */ int sock; ssize_t nb; struct sockaddr addr_me; struct sockaddr addr_him; socklen_t hislen = (socklen_t) sizeof(addr_him); uint8_t inbuf[INBUF_SIZE]; uint8_t *outbuf; /* dns */ ldns_status status; ldns_pkt *query_pkt; ldns_pkt *answer_pkt; size_t answer_size; ldns_rr *query_rr; ldns_rr_list *answer_qr; ldns_rr_list *answer_an; ldns_rr_list *answer_ns; ldns_rr_list *answer_ad; ldns_rdf *origin = NULL; /* zone */ ldns_zone *zone; int line_nr; FILE *zone_fp; if (ldns_str2rdf_dname(&origin, my_zone) != LDNS_STATUS_OK) { fprintf(stderr, "Bad origin, not a correct domain name\n"); exit(EXIT_FAILURE); } printf("Listening on port %d\n", port); sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { fprintf(stderr, "socket(): %s\n", strerror(errno)); exit(1); } memset(&addr_me, 0, sizeof(addr_me)); /* bind: try all ports in that range */ if (udp_bind(sock, port, my_address)) { fprintf(stderr, "cannot bind(): %s\n", strerror(errno)); exit(errno); } /* Done. Now receive */ while (1) { nb = recvfrom(sock, (void*)inbuf, INBUF_SIZE, 0, &addr_him, &hislen); if (nb < 1) { fprintf(stderr, "recvfrom(): %s\n", strerror(errno)); exit(1); } /* show(inbuf, nb, nn, hp, sp, ip, bp); */ status = ldns_wire2pkt(&query_pkt, inbuf, (size_t) nb); if (status != LDNS_STATUS_OK) { printf("Got bad packet: %s\n", ldns_get_errorstr_by_id(status)); } query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0); answer_qr = ldns_rr_list_new(); ldns_rr_list_push_rr(answer_qr, ldns_rr_clone(query_rr)); answer_an = get_rrset(zone, ldns_rr_owner(query_rr), ldns_rr_get_type(query_rr), ldns_rr_get_class(query_rr)); answer_pkt = ldns_pkt_new(); answer_ns = ldns_rr_list_new(); answer_ad = ldns_rr_list_new(); ldns_pkt_set_qr(answer_pkt, 1); ldns_pkt_set_aa(answer_pkt, 1); ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt)); ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_QUESTION, answer_qr); ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ANSWER, answer_an); ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_AUTHORITY, answer_ns); ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ADDITIONAL, answer_ad); status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size); if (status != LDNS_STATUS_OK) { printf("Error creating answer: %s\n", ldns_get_errorstr_by_id(status)); } else { nb = sendto(sock, (void*)outbuf, answer_size, 0, &addr_him, hislen); } ldns_pkt_free(query_pkt); ldns_pkt_free(answer_pkt); LDNS_FREE(outbuf); ldns_rr_list_free(answer_qr); ldns_rr_list_free(answer_an); ldns_rr_list_free(answer_ns); ldns_rr_list_free(answer_ad); } ldns_rdf_deep_free(origin); ldns_zone_deep_free(zone); rp_shutdown(rp_handle); }
int main(int argc, char **argv) { /* arguments */ int port; const char *zone_file; /* network */ int sock; ssize_t nb; struct sockaddr addr_me; struct sockaddr addr_him; socklen_t hislen = (socklen_t) sizeof(addr_him); uint8_t inbuf[INBUF_SIZE]; uint8_t *outbuf; /* dns */ ldns_status status; ldns_pkt *query_pkt; ldns_pkt *answer_pkt; size_t answer_size; ldns_rr *query_rr; ldns_rr_list *answer_qr; ldns_rr_list *answer_an; ldns_rr_list *answer_ns; ldns_rr_list *answer_ad; ldns_rdf *origin = NULL; /* zone */ ldns_zone *zone; int line_nr; FILE *zone_fp; /* use this to listen on specified interfaces later? */ char *my_address = NULL; if (argc < 5) { usage(stderr); exit(EXIT_FAILURE); } else { my_address = argv[1]; port = atoi(argv[2]); if (port < 1) { usage(stderr); exit(EXIT_FAILURE); } if (ldns_str2rdf_dname(&origin, argv[3]) != LDNS_STATUS_OK) { fprintf(stderr, "Bad origin, not a correct domain name\n"); usage(stderr); exit(EXIT_FAILURE); } zone_file = argv[4]; } printf("Reading zone file %s\n", zone_file); zone_fp = fopen(zone_file, "r"); if (!zone_fp) { fprintf(stderr, "Unable to open %s: %s\n", zone_file, strerror(errno)); exit(EXIT_FAILURE); } line_nr = 0; status = ldns_zone_new_frm_fp_l(&zone, zone_fp, origin, 0, LDNS_RR_CLASS_IN, &line_nr); if (status != LDNS_STATUS_OK) { printf("Zone reader failed, aborting\n"); exit(EXIT_FAILURE); } else { printf("Read %u resource records in zone file\n", (unsigned int) ldns_zone_rr_count(zone)); } fclose(zone_fp); printf("Listening on port %d\n", port); sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno)); exit(1); } memset(&addr_me, 0, sizeof(addr_me)); /* bind: try all ports in that range */ if (udp_bind(sock, port, my_address)) { fprintf(stderr, "%s: cannot bind(): %s\n", argv[0], strerror(errno)); exit(errno); } /* Done. Now receive */ while (1) { nb = recvfrom(sock, (void*)inbuf, INBUF_SIZE, 0, &addr_him, &hislen); if (nb < 1) { fprintf(stderr, "%s: recvfrom(): %s\n", argv[0], strerror(errno)); exit(1); } /* show(inbuf, nb, nn, hp, sp, ip, bp); */ printf("Got query of %u bytes\n", (unsigned int) nb); status = ldns_wire2pkt(&query_pkt, inbuf, (size_t) nb); if (status != LDNS_STATUS_OK) { printf("Got bad packet: %s\n", ldns_get_errorstr_by_id(status)); } else { ldns_pkt_print(stdout, query_pkt); } query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0); printf("QUERY RR: \n"); ldns_rr_print(stdout, query_rr); answer_qr = ldns_rr_list_new(); ldns_rr_list_push_rr(answer_qr, ldns_rr_clone(query_rr)); answer_an = get_rrset(zone, ldns_rr_owner(query_rr), ldns_rr_get_type(query_rr), ldns_rr_get_class(query_rr)); answer_pkt = ldns_pkt_new(); answer_ns = ldns_rr_list_new(); answer_ad = ldns_rr_list_new(); ldns_pkt_set_qr(answer_pkt, 1); ldns_pkt_set_aa(answer_pkt, 1); ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt)); ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_QUESTION, answer_qr); ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ANSWER, answer_an); ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_AUTHORITY, answer_ns); ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ADDITIONAL, answer_ad); status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size); printf("Answer packet size: %u bytes.\n", (unsigned int) answer_size); if (status != LDNS_STATUS_OK) { printf("Error creating answer: %s\n", ldns_get_errorstr_by_id(status)); } else { nb = sendto(sock, (void*)outbuf, answer_size, 0, &addr_him, hislen); } ldns_pkt_free(query_pkt); ldns_pkt_free(answer_pkt); LDNS_FREE(outbuf); ldns_rr_list_free(answer_qr); ldns_rr_list_free(answer_an); ldns_rr_list_free(answer_ns); ldns_rr_list_free(answer_ad); } /* No cleanup because of the infinite loop * * ldns_rdf_deep_free(origin); * ldns_zone_deep_free(zone); * return 0; */ }
ldns_rr_list* loadAnchorfile(const char *filename) { int col = 0; int line = 0; int grouped = 0; int tk_section = 0; FILE *key_file; char c; char linebuffer[LDNS_MAX_PACKETLEN]; ldns_rdf *rd; ldns_rr *rr; ldns_rr_list *trusted_keys; // Try open trusted key file key_file = fopen(filename, "r"); if (!key_file) { if (mp_verbose >= 1) fprintf(stderr,"Error opening trusted-key file %s: %s\n", filename, strerror(errno)); return NULL; } // Create empty list trusted_keys = ldns_rr_list_new(); // Read File do { c = getc(key_file); if ((c == '\n' && grouped == 0) || c == EOF) { linebuffer[col] = '\0'; line++; if(strstr(linebuffer, "trusted-keys")) { col = 0; tk_section = 1; continue; } // Strip leading spaces. char *cur = linebuffer; cur += strspn(linebuffer," \t\n"); if (cur[0] == ';' || strncmp(cur,"//",2) == 0 || col == 0 || tk_section == 0) { col = 0; continue; } col = 0; rr = ldns_rr_new(); ldns_rr_set_class(rr, LDNS_RR_CLASS_IN); ldns_rr_set_type(rr, LDNS_RR_TYPE_DNSKEY); ldns_rr_set_ttl(rr, 3600); char *t = strsep(&cur, " \t"); ldns_str2rdf_dname(&rd, t); ldns_rr_set_owner(rr, rd); t = strsep(&cur, " \t"); ldns_str2rdf_int16(&rd, t); ldns_rr_push_rdf(rr, rd); t = strsep(&cur, " \t"); ldns_str2rdf_int8(&rd, t); ldns_rr_push_rdf(rr, rd); t = strsep(&cur, " \t"); ldns_str2rdf_alg(&rd, t); ldns_rr_push_rdf(rr, rd); if (cur[strlen(cur)-1] == ';') cur[strlen(cur)-1] = '\0'; ldns_str2rdf_b64(&rd, cur); ldns_rr_push_rdf(rr, rd); ldns_rr_list_push_rr(trusted_keys,rr); } else { if (c == '}') { tk_section = 0; } else if (c == '"') { grouped = (grouped+1)%2; } else { linebuffer[col++] = c; } } } while (c != EOF); fclose(key_file); return trusted_keys; }