void * sign (void *arg) { hsm_ctx_t *ctx = NULL; hsm_key_t *key = NULL; size_t i; unsigned int iterations = 0; ldns_rr_list *rrset; ldns_rr *rr, *sig, *dnskey_rr; ldns_status status; hsm_sign_params_t *sign_params; sign_arg_t *sign_arg = arg; ctx = sign_arg->ctx; key = sign_arg->key; iterations = sign_arg->iterations; fprintf(stderr, "Signer thread #%d started...\n", sign_arg->id); /* Prepare dummy RRset for signing */ rrset = ldns_rr_list_new(); status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 123.123.123.123", 0, NULL, NULL); if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 124.124.124.124", 0, NULL, NULL); if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); sign_params = hsm_sign_params_new(); sign_params->algorithm = algorithm; sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "opendnssec.se."); dnskey_rr = hsm_get_dnskey(ctx, key, sign_params); sign_params->keytag = ldns_calc_keytag(dnskey_rr); /* Do some signing */ for (i=0; i<iterations; i++) { sig = hsm_sign_rrset(ctx, rrset, key, sign_params); if (! sig) { fprintf(stderr, "hsm_sign_rrset() returned error: %s in %s\n", ctx->error_message, ctx->error_action ); break; } ldns_rr_free(sig); } /* Clean up */ ldns_rr_list_deep_free(rrset); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); hsm_destroy_context(ctx); fprintf(stderr, "Signer thread #%d done.\n", sign_arg->id); pthread_exit(NULL); }
/** * Lookup SOA RR. * */ ldns_rr* adutil_lookup_soa_rr(FILE* fd) { ldns_rr *cur_rr = NULL; char line[SE_ADFILE_MAXLINE]; ldns_status status = LDNS_STATUS_OK; int line_len = 0; unsigned int l = 0; while (line_len >= 0) { line_len = adutil_readline_frm_file(fd, (char*) line, &l, 0); adutil_rtrim_line(line, &line_len); if (line_len > 0) { if (line[0] != ';') { status = ldns_rr_new_frm_str(&cur_rr, line, 0, NULL, NULL); if (status == LDNS_STATUS_OK) { if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) { return cur_rr; } else { ldns_rr_free(cur_rr); cur_rr = NULL; } } } } } return NULL; }
void read_in(ldns_rr_list* list, ldns_rdf** qname, FILE *in) { char* buf; while((buf=skip_comments_and_query(in, qname))) { /* add rr */ ldns_rr *rr=0; ldns_rdf *origin=0, *prev=0; ldns_status err; uint16_t ttl = 3600; if((err=ldns_rr_new_frm_str(&rr, buf, ttl, origin, &prev)) != LDNS_STATUS_OK) abort_ldns_error("read rr", err); ldns_rr_list_push_rr(list, rr); } printf("nsec3-covers: read %d rrs\n", (int)ldns_rr_list_rr_count(list)); if(!qname) { printf("Could not read question name\n"); exit(1); } printf("nsec3-covers: qname is "); ldns_rdf_print(stdout, *qname); printf("\n"); }
/** * Read the next RR from zone file. * */ ldns_rr* addns_read_rr(FILE* fd, char* line, ldns_rdf** orig, ldns_rdf** prev, uint32_t* ttl, ldns_status* status, unsigned int* l) { ldns_rr* rr = NULL; int len = 0; uint32_t new_ttl = 0; addns_read_line: if (ttl) { new_ttl = *ttl; } len = adutil_readline_frm_file(fd, line, l, 0); adutil_rtrim_line(line, &len); if (len >= 0) { switch (line[0]) { /* no directives */ /* comments, empty lines */ case ';': case '\n': goto addns_read_line; /* perhaps next line is rr */ break; /* let's hope its a RR */ default: if (adutil_whitespace_line(line, len)) { goto addns_read_line; /* perhaps next line is rr */ break; } *status = ldns_rr_new_frm_str(&rr, line, new_ttl, *orig, prev); if (*status == LDNS_STATUS_OK) { return rr; } else if (*status == LDNS_STATUS_SYNTAX_EMPTY) { if (rr) { ldns_rr_free(rr); rr = NULL; } *status = LDNS_STATUS_OK; goto addns_read_line; /* perhaps next line is rr */ break; } else { ods_log_error("[%s] error parsing RR at line %i (%s): %s", adapter_str, l&&*l?*l:0, ldns_get_errorstr_by_id(*status), line); while (len >= 0) { len = adutil_readline_frm_file(fd, line, l, 0); } if (rr) { ldns_rr_free(rr); rr = NULL; } return NULL; } break; } } /* -1, EOF */ *status = LDNS_STATUS_OK; return NULL; }
/** * Read the next RR from the backup file. * */ static ldns_rr* backup_read_rr(FILE* in, zone_type* zone, char* line, ldns_rdf** orig, ldns_rdf** prev, ldns_status* status, unsigned int* l) { ldns_rr* rr = NULL; int len = 0; backup_read_line: len = adutil_readline_frm_file(in, line, l, 1); if (len >= 0) { switch (line[0]) { case ';': /* done */ *status = LDNS_STATUS_OK; return NULL; break; case '\n': case '\0': goto backup_read_line; /* perhaps next line is rr */ break; /* let's hope its a RR */ default: *status = ldns_rr_new_frm_str(&rr, line, zone->default_ttl, *orig, prev); if (*status == LDNS_STATUS_OK) { return rr; } else if (*status == LDNS_STATUS_SYNTAX_EMPTY) { if (rr) { ldns_rr_free(rr); rr = NULL; } *status = LDNS_STATUS_OK; goto backup_read_line; /* perhaps next line is rr */ break; } else { ods_log_error("[%s] error parsing RR #%i (%s): %s", backup_str, l&&*l?*l:0, ldns_get_errorstr_by_id(*status), line); if (rr) { ldns_rr_free(rr); rr = NULL; } return NULL; } break; } } /* -1, EOF */ *status = LDNS_STATUS_OK; return NULL; }
static int hsm_test_sign (hsm_ctx_t *ctx, hsm_key_t *key, ldns_algorithm alg) { int result; ldns_rr_list *rrset; ldns_rr *rr, *sig, *dnskey_rr; ldns_status status; hsm_sign_params_t *sign_params; rrset = ldns_rr_list_new(); status = ldns_rr_new_frm_str(&rr, "example.com. IN A 192.168.0.1", 0, NULL, NULL); if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); status = ldns_rr_new_frm_str(&rr, "example.com. IN A 192.168.0.2", 0, NULL, NULL); if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); sign_params = hsm_sign_params_new(); sign_params->algorithm = alg; sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "example.com."); dnskey_rr = hsm_get_dnskey(ctx, key, sign_params); sign_params->keytag = ldns_calc_keytag(dnskey_rr); sig = hsm_sign_rrset(ctx, rrset, key, sign_params); if (sig) { result = 0; ldns_rr_free(sig); } else { result = 1; } ldns_rr_list_deep_free(rrset); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); return result; }
/* key_list must be initialized with ldns_rr_list_new() */ ldns_status read_key_file(const char *filename, ldns_rr_list *key_list) { int line_len = 0; int line_nr = 0; int key_count = 0; char line[LDNS_MAX_PACKETLEN]; ldns_status status; FILE *input_file; ldns_rr *rr; input_file = fopen(filename, "r"); if (!input_file) { fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno)); return LDNS_STATUS_ERR; } while (line_len >= 0) { line_len = read_line(input_file, line); line_nr++; if (line_len > 0 && line[0] != ';') { status = ldns_rr_new_frm_str(&rr, line, 0, NULL, NULL); if (status != LDNS_STATUS_OK) { fprintf(stderr, "Error parsing DNSKEY RR in line %d: %s\n", line_nr, ldns_get_errorstr_by_id(status)); } else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) { ldns_rr_list_push_rr(key_list, rr); key_count++; } else { ldns_rr_free(rr); } } } // printf(";; Number of trusted keys: %d\n", key_count); if (key_count > 0) { return LDNS_STATUS_OK; } else { /*fprintf(stderr, "No keys read\n");*/ return LDNS_STATUS_ERR; } }
struct trust_anchor* anchor_store_str(struct val_anchors* anchors, ldns_buffer* buffer, const char* str) { struct trust_anchor* ta; ldns_rr* rr = NULL; ldns_status status = ldns_rr_new_frm_str(&rr, str, 0, NULL, NULL); if(status != LDNS_STATUS_OK) { log_err("error parsing trust anchor: %s", ldns_get_errorstr_by_id(status)); ldns_rr_free(rr); return NULL; } if(!(ta=anchor_store_new_rr(anchors, buffer, rr))) { log_err("out of memory"); ldns_rr_free(rr); return NULL; } ldns_rr_free(rr); return ta; }
/* ========== RR ========== */ static int l_rr_new_frm_str(lua_State *L) { /* pop string from stack, make new rr, push rr to * stack and return 1 - to signal the new pointer */ char *str = strdup((char*)luaL_checkstring(L, 1)); uint16_t ttl = (uint16_t)lua_tonumber(L, 2); ldns_rdf *orig = (ldns_rdf*)lua_touserdata(L, 2); if (!str) { return 0; } ldns_rr *new_rr = ldns_rr_new_frm_str(str, ttl, orig); if (new_rr) { lua_pushlightuserdata(L, new_rr); return 1; } else { return 0; } }
/* put a hardcoded list in the root and * init the root rrlist structure */ void init_root(void) { ldns_rr *r; global_dns_root = ldns_rr_list_new(); (void)ldns_rr_new_frm_str(&r, "A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:BA3E::2:30", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "B.ROOT-SERVERS.NET. 3600000 A 192.228.79.201", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "D.ROOT-SERVERS.NET. 3600000 A 128.8.10.90", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2F::F", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "H.ROOT-SERVERS.NET. 3600000 A 128.63.2.53", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::803F:235", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:C27::2:30", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129 ", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7FD::1", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:3::42 ", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); (void)ldns_rr_new_frm_str(&r, "M.ROOT-SERVERS.NET. 3600000 AAAA 2001:DC3::35", 0, NULL, NULL); ldns_rr_list_push_rr(global_dns_root, r); }
int main (int argc, char *argv[]) { int result; hsm_ctx_t *ctx; hsm_key_t **keys; hsm_key_t *key = NULL; char *id; size_t key_count = 0; size_t i; ldns_rr_list *rrset; ldns_rr *rr, *sig, *dnskey_rr; ldns_status status; hsm_sign_params_t *sign_params; int do_generate = 0; int do_sign = 0; int do_delete = 0; int do_random = 0; int res; uint32_t r32; uint64_t r64; char *config = NULL; const char *repository = "default"; int ch; progname = argv[0]; while ((ch = getopt(argc, argv, "hgsdrc:")) != -1) { switch (ch) { case 'c': config = strdup(optarg); break; case 'g': do_generate = 1; break; case 'h': usage(); exit(0); break; case 's': do_sign = 1; break; case 'd': do_delete = 1; break; case 'r': do_random = 1; break; default: usage(); exit(1); } } if (!config) { usage(); exit(1); } /* * Open HSM library */ fprintf(stdout, "Starting HSM lib test\n"); result = hsm_open(config, hsm_prompt_pin); fprintf(stdout, "hsm_open result: %d\n", result); /* * Create HSM context */ ctx = hsm_create_context(); printf("global: "); hsm_print_ctx(NULL); printf("my: "); hsm_print_ctx(ctx); /* * Generate a new key OR find any key with an ID */ if (do_generate) { key = hsm_generate_rsa_key(ctx, repository, 1024); if (key) { printf("\nCreated key!\n"); hsm_print_key(key); printf("\n"); } else { printf("Error creating key, bad token name?\n"); hsm_print_error(ctx); exit(1); } } else if (do_sign || do_delete) { keys = hsm_list_keys(ctx, &key_count); printf("I have found %u keys\n", (unsigned int) key_count); /* let's just use the very first key we find and throw away the rest */ for (i = 0; i < key_count && !key; i++) { printf("\nFound key!\n"); hsm_print_key(keys[i]); id = hsm_get_key_id(ctx, keys[i]); if (id) { printf("Using key ID: %s\n", id); if (key) hsm_key_free(key); key = hsm_find_key_by_id(ctx, id); printf("ptr: 0x%p\n", (void *) key); free(id); } else { printf("Got no key ID (broken key?), skipped...\n"); } hsm_key_free(keys[i]); } free(keys); if (!key) { printf("Failed to find useful key\n"); exit(1); } } /* * Do some signing */ if (do_sign) { printf("\nSigning with:\n"); hsm_print_key(key); printf("\n"); rrset = ldns_rr_list_new(); status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 123.123.123.123", 0, NULL, NULL); if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 124.124.124.124", 0, NULL, NULL); if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); sign_params = hsm_sign_params_new(); sign_params->algorithm = LDNS_RSASHA1; sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "opendnssec.se."); dnskey_rr = hsm_get_dnskey(ctx, key, sign_params); sign_params->keytag = ldns_calc_keytag(dnskey_rr); sig = hsm_sign_rrset(ctx, rrset, key, sign_params); if (sig) { ldns_rr_list_print(stdout, rrset); ldns_rr_print(stdout, sig); ldns_rr_print(stdout, dnskey_rr); ldns_rr_free(sig); } else { hsm_print_error(ctx); exit(-1); } /* cleanup */ ldns_rr_list_deep_free(rrset); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); } /* * Delete key */ if (do_delete) { printf("\nDelete key:\n"); hsm_print_key(key); /* res = hsm_remove_key(ctx, key); */ res = hsm_remove_key(ctx, key); printf("Deleted key. Result: %d\n", res); printf("\n"); } if (key) hsm_key_free(key); /* * Test random{32,64} functions */ if (do_random) { r32 = hsm_random32(ctx); printf("random 32: %u\n", r32); r64 = hsm_random64(ctx); printf("random 64: %llu\n", (long long unsigned int)r64); } /* * Destroy HSM context */ if (ctx) { hsm_destroy_context(ctx); } /* * Close HSM library */ result = hsm_close(); fprintf(stdout, "all done! hsm_close result: %d\n", result); if (config) free(config); return 0; }
/** * Read the next RR from zone file. * */ static ldns_rr* adfile_read_rr(FILE* fd, zone_type* zone, char* line, ldns_rdf** orig, ldns_rdf** prev, uint32_t* ttl, ldns_status* status, unsigned int* l) { ldns_rr* rr = NULL; ldns_rdf* tmp = NULL; FILE* fd_include = NULL; int len = 0; ods_status s = ODS_STATUS_OK; uint32_t new_ttl = 0; const char *endptr; /* unused */ int offset = 0; adfile_read_line: if (ttl) { new_ttl = *ttl; } len = adutil_readline_frm_file(fd, line, l, 0); adutil_rtrim_line(line, &len); if (len >= 0) { switch (line[0]) { /* directive */ case '$': if (strncmp(line, "$ORIGIN", 7) == 0 && isspace((int)line[7])) { /* copy from ldns */ if (*orig) { ldns_rdf_deep_free(*orig); *orig = NULL; } offset = 8; while (isspace((int)line[offset])) { offset++; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, line + offset); if (!tmp) { /* could not parse what next to $ORIGIN */ *status = LDNS_STATUS_SYNTAX_DNAME_ERR; return NULL; } *orig = tmp; /* end copy from ldns */ goto adfile_read_line; /* perhaps next line is rr */ break; } else if (strncmp(line, "$TTL", 4) == 0 && isspace((int)line[4])) { /* override default ttl */ offset = 5; while (isspace((int)line[offset])) { offset++; } if (ttl) { *ttl = ldns_str2period(line + offset, &endptr); new_ttl = *ttl; } goto adfile_read_line; /* perhaps next line is rr */ break; } else if (strncmp(line, "$INCLUDE", 8) == 0 && isspace((int)line[8])) { /* dive into this file */ offset = 9; while (isspace((int)line[offset])) { offset++; } fd_include = ods_fopen(line + offset, NULL, "r"); if (fd_include) { s = adfile_read_file(fd_include, zone); ods_fclose(fd_include); } else { ods_log_error("[%s] unable to open include file %s", adapter_str, (line+offset)); *status = LDNS_STATUS_SYNTAX_ERR; return NULL; } if (s != ODS_STATUS_OK) { *status = LDNS_STATUS_SYNTAX_ERR; ods_log_error("[%s] error in include file %s", adapter_str, (line+offset)); return NULL; } /* restore current ttl */ if (ttl) { *ttl = new_ttl; } goto adfile_read_line; /* perhaps next line is rr */ break; } goto adfile_read_rr; /* this can be an owner name */ break; /* comments, empty lines */ case ';': case '\n': goto adfile_read_line; /* perhaps next line is rr */ break; /* let's hope its a RR */ default: adfile_read_rr: if (adutil_whitespace_line(line, len)) { goto adfile_read_line; /* perhaps next line is rr */ break; } *status = ldns_rr_new_frm_str(&rr, line, new_ttl, *orig, prev); if (*status == LDNS_STATUS_OK) { return rr; } else if (*status == LDNS_STATUS_SYNTAX_EMPTY) { if (rr) { ldns_rr_free(rr); rr = NULL; } *status = LDNS_STATUS_OK; goto adfile_read_line; /* perhaps next line is rr */ break; } else { ods_log_error("[%s] error parsing RR at line %i (%s): %s", adapter_str, l&&*l?*l:0, ldns_get_errorstr_by_id(*status), line); while (len >= 0) { len = adutil_readline_frm_file(fd, line, l, 0); } if (rr) { ldns_rr_free(rr); rr = NULL; } return NULL; } break; } } /* -1, EOF */ *status = LDNS_STATUS_OK; return NULL; }
/** load an RR into rrset */ static int load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region, struct ub_packed_rrset_key* rk, struct packed_rrset_data* d, unsigned int i, int is_rrsig, int* go_on, uint32_t now) { ldns_rr* rr; ldns_status status; /* read the line */ if(!ssl_read_buf(ssl, buf)) return 0; if(strncmp((char*)ldns_buffer_begin(buf), "BADRR\n", 6) == 0) { *go_on = 0; return 1; } status = ldns_rr_new_frm_str(&rr, (char*)ldns_buffer_begin(buf), LDNS_DEFAULT_TTL, NULL, NULL); if(status != LDNS_STATUS_OK) { log_warn("error cannot parse rr: %s: %s", ldns_get_errorstr_by_id(status), (char*)ldns_buffer_begin(buf)); return 0; } if(is_rrsig && ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) { log_warn("error expected rrsig but got %s", (char*)ldns_buffer_begin(buf)); return 0; } /* convert ldns rr into packed_rr */ d->rr_ttl[i] = ldns_rr_ttl(rr) + now; ldns_buffer_clear(buf); ldns_buffer_skip(buf, 2); status = ldns_rr_rdata2buffer_wire(buf, rr); if(status != LDNS_STATUS_OK) { log_warn("error cannot rr2wire: %s", ldns_get_errorstr_by_id(status)); ldns_rr_free(rr); return 0; } ldns_buffer_flip(buf); ldns_buffer_write_u16_at(buf, 0, ldns_buffer_limit(buf) - 2); d->rr_len[i] = ldns_buffer_limit(buf); d->rr_data[i] = (uint8_t*)regional_alloc_init(region, ldns_buffer_begin(buf), ldns_buffer_limit(buf)); if(!d->rr_data[i]) { ldns_rr_free(rr); log_warn("error out of memory"); return 0; } /* if first entry, fill the key structure */ if(i==0) { rk->rk.type = htons(ldns_rr_get_type(rr)); rk->rk.rrset_class = htons(ldns_rr_get_class(rr)); ldns_buffer_clear(buf); status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr)); if(status != LDNS_STATUS_OK) { log_warn("error cannot dname2buffer: %s", ldns_get_errorstr_by_id(status)); ldns_rr_free(rr); return 0; } ldns_buffer_flip(buf); rk->rk.dname_len = ldns_buffer_limit(buf); rk->rk.dname = regional_alloc_init(region, ldns_buffer_begin(buf), ldns_buffer_limit(buf)); if(!rk->rk.dname) { log_warn("error out of memory"); ldns_rr_free(rr); return 0; } } ldns_rr_free(rr); return 1; }
int main(int argc, char **argv) { int c; int i; /* LDNS types */ ldns_pkt *notify; ldns_rr *question; ldns_resolver *res; ldns_rdf *ldns_zone_name = NULL; ldns_status status; const char *zone_name = NULL; int include_soa = 0; uint32_t soa_version = 0; ldns_tsig_credentials tsig_cred = {0,0,0}; int do_hexdump = 1; uint8_t *wire = NULL; size_t wiresize = 0; char *port = "53"; srandom(time(NULL) ^ getpid()); while ((c = getopt(argc, argv, "vhdp:r:s:y:z:")) != -1) { switch (c) { case 'd': verbose++; break; case 'p': port = optarg; break; case 'r': max_num_retry = atoi(optarg); break; case 's': include_soa = 1; soa_version = (uint32_t)atoi(optarg); break; case 'y': tsig_cred.algorithm = "hmac-md5.sig-alg.reg.int."; tsig_cred.keyname = optarg; tsig_cred.keydata = strchr(optarg, ':'); *tsig_cred.keydata = '\0'; tsig_cred.keydata++; printf("Sign with %s : %s\n", tsig_cred.keyname, tsig_cred.keydata); break; case 'z': zone_name = optarg; ldns_zone_name = ldns_dname_new_frm_str(zone_name); if(!ldns_zone_name) { printf("cannot parse zone name: %s\n", zone_name); exit(1); } break; case 'v': version(); case 'h': case '?': default: usage(); } } argc -= optind; argv += optind; if (argc == 0 || zone_name == NULL) { usage(); } notify = ldns_pkt_new(); question = ldns_rr_new(); res = ldns_resolver_new(); if (!notify || !question || !res) { /* bail out */ printf("error: cannot create ldns types\n"); exit(1); } /* create the rr for inside the pkt */ ldns_rr_set_class(question, LDNS_RR_CLASS_IN); ldns_rr_set_owner(question, ldns_zone_name); ldns_rr_set_type(question, LDNS_RR_TYPE_SOA); ldns_pkt_set_opcode(notify, LDNS_PACKET_NOTIFY); ldns_pkt_push_rr(notify, LDNS_SECTION_QUESTION, question); ldns_pkt_set_aa(notify, true); ldns_pkt_set_id(notify, random()&0xffff); if(include_soa) { char buf[10240]; ldns_rr *soa_rr=NULL; ldns_rdf *prev=NULL; snprintf(buf, sizeof(buf), "%s 3600 IN SOA . . %u 0 0 0 0", zone_name, (unsigned)soa_version); /*printf("Adding soa %s\n", buf);*/ status = ldns_rr_new_frm_str(&soa_rr, buf, 3600, NULL, &prev); if(status != LDNS_STATUS_OK) { printf("Error adding SOA version: %s\n", ldns_get_errorstr_by_id(status)); } ldns_pkt_push_rr(notify, LDNS_SECTION_ANSWER, soa_rr); } if(tsig_cred.keyname) { #ifdef HAVE_SSL status = ldns_pkt_tsig_sign(notify, tsig_cred.keyname, tsig_cred.keydata, 300, tsig_cred.algorithm, NULL); if(status != LDNS_STATUS_OK) { printf("Error TSIG sign query: %s\n", ldns_get_errorstr_by_id(status)); } #else fprintf(stderr, "Warning: TSIG needs OpenSSL support, which has not been compiled in, TSIG skipped\n"); #endif } if(verbose) { printf("# Sending packet:\n"); ldns_pkt_print(stdout, notify); } status = ldns_pkt2wire(&wire, notify, &wiresize); if(wiresize == 0) { printf("Error converting notify packet to hex.\n"); exit(1); } if(do_hexdump && verbose > 1) { printf("Hexdump of notify packet:\n"); for(i=0; i<(int)wiresize; i++) printf("%02x", (unsigned)wire[i]); printf("\n"); } for(i=0; i<argc; i++) { struct addrinfo hints, *res0, *res; int error; int default_family = AF_INET; if(verbose) printf("# sending to %s\n", argv[i]); memset(&hints, 0, sizeof(hints)); hints.ai_family = default_family; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; error = getaddrinfo(argv[i], port, &hints, &res0); if (error) { printf("skipping bad address: %s: %s\n", argv[i], gai_strerror(error)); continue; } for (res = res0; res; res = res->ai_next) { int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if(s == -1) continue; /* send the notify */ notify_host(s, res, wire, wiresize, argv[i]); } freeaddrinfo(res0); } ldns_pkt_free(notify); free(wire); return 0; }
/* Reads one entry from file. Returns entry or NULL on error. */ struct entry* read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl, ldns_rdf** origin, ldns_rdf** prev_rr) { struct entry* current = NULL; char line[MAX_LINE]; char* parse; ldns_pkt_section add_section = LDNS_SECTION_QUESTION; struct reply_packet *cur_reply = NULL; bool reading_hex = false; ldns_buffer* hex_data_buffer = NULL; while(fgets(line, (int)sizeof(line), in) != NULL) { line[MAX_LINE-1] = 0; parse = line; (*lineno) ++; while(isspace((int)*parse)) parse++; /* test for keywords */ if(isendline(*parse)) continue; /* skip comment and empty lines */ if(str_keyword(&parse, "ENTRY_BEGIN")) { if(current) { error("%s line %d: previous entry does not ENTRY_END", name, *lineno); } current = new_entry(); current->lineno = *lineno; cur_reply = entry_add_reply(current); continue; } else if(str_keyword(&parse, "$ORIGIN")) { get_origin(name, *lineno, origin, parse); continue; } else if(str_keyword(&parse, "$TTL")) { *default_ttl = (uint32_t)atoi(parse); continue; } /* working inside an entry */ if(!current) { error("%s line %d: expected ENTRY_BEGIN but got %s", name, *lineno, line); } if(str_keyword(&parse, "MATCH")) { matchline(parse, current); } else if(str_keyword(&parse, "REPLY")) { replyline(parse, cur_reply->reply); } else if(str_keyword(&parse, "ADJUST")) { adjustline(parse, current, cur_reply); } else if(str_keyword(&parse, "EXTRA_PACKET")) { cur_reply = entry_add_reply(current); } else if(str_keyword(&parse, "SECTION")) { if(str_keyword(&parse, "QUESTION")) add_section = LDNS_SECTION_QUESTION; else if(str_keyword(&parse, "ANSWER")) add_section = LDNS_SECTION_ANSWER; else if(str_keyword(&parse, "AUTHORITY")) add_section = LDNS_SECTION_AUTHORITY; else if(str_keyword(&parse, "ADDITIONAL")) add_section = LDNS_SECTION_ADDITIONAL; else error("%s line %d: bad section %s", name, *lineno, parse); } else if(str_keyword(&parse, "HEX_ANSWER_BEGIN")) { hex_data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); reading_hex = true; } else if(str_keyword(&parse, "HEX_ANSWER_END")) { if (!reading_hex) { error("%s line %d: HEX_ANSWER_END read but no HEX_ANSWER_BEGIN keyword seen", name, *lineno); } reading_hex = false; cur_reply->reply_from_hex = data_buffer2wire(hex_data_buffer); ldns_buffer_free(hex_data_buffer); } else if(str_keyword(&parse, "ENTRY_END")) { return current; } else if(reading_hex) { ldns_buffer_printf(hex_data_buffer, line); } else { /* it must be a RR, parse and add to packet. */ ldns_rr* n = NULL; ldns_status status; if(add_section == LDNS_SECTION_QUESTION) status = ldns_rr_new_question_frm_str( &n, parse, *origin, prev_rr); else status = ldns_rr_new_frm_str(&n, parse, *default_ttl, *origin, prev_rr); if(status != LDNS_STATUS_OK) error("%s line %d:\n\t%s: %s", name, *lineno, ldns_get_errorstr_by_id(status), parse); ldns_pkt_push_rr(cur_reply->reply, add_section, n); } } if (reading_hex) { error("%s: End of file reached while still reading hex, " "missing HEX_ANSWER_END\n", name); } if(current) { error("%s: End of file reached while reading entry. " "missing ENTRY_END\n", name); } return 0; }
int main(int argc, char **argv) { /* arguments */ int port; int soa; ldns_rdf *zone_name; size_t count; size_t maxcount; /* network */ int sock; ssize_t nb; struct sockaddr addr_me; struct sockaddr addr_him; socklen_t hislen = sizeof(addr_him); const char *my_address; 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 *rr; char rr_string[MAX_LEN + 1]; ldns_rr *soa_rr; char soa_string[MAX_LEN + 1]; /* use this to listen on specified interfaces later? */ my_address = NULL; if(argc == 5) { /* -# num given */ if (argv[1][0] == '-') { maxcount = atoi(argv[1] + 1); if (maxcount == 0) { usage(stdout); exit(EXIT_FAILURE); } else { fprintf(stderr, "quiting after %d qs\n", (int)maxcount); } } else { fprintf(stderr, "Use -Number for max count\n"); exit(EXIT_FAILURE); } argc--; argv++; } else { maxcount = 0; } if (argc != 4) { usage(stdout); exit(EXIT_FAILURE); } else { port = atoi(argv[1]); if (port < 1) { fprintf(stderr, "Use a number for the port\n"); usage(stdout); exit(EXIT_FAILURE); } zone_name = ldns_dname_new_frm_str(argv[2]); if (!zone_name) { fprintf(stderr, "Illegal domain name: %s\n", argv[2]); usage(stdout); exit(EXIT_FAILURE); } soa = atoi(argv[3]); if (soa < 1) { fprintf(stderr, "Illegal soa number\n"); usage(stdout); exit(EXIT_FAILURE); } } 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(EXIT_FAILURE); } 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)); } /* create our ixfr answer */ answer_pkt = ldns_pkt_new(); snprintf(rr_string, MAX_LEN, "%s IN IXFR", argv[2]); (void)ldns_rr_new_frm_str(&rr, rr_string , 0, NULL, NULL); (void)ldns_pkt_push_rr(answer_pkt, LDNS_SECTION_QUESTION, rr); /* next add some rrs, with SOA stuff so that we mimic or ixfr reply */ snprintf(soa_string, MAX_LEN, "%s IN SOA miek.miek.nl elektron.atoom.net %d 1 2 3000 4", argv[2], soa); (void)ldns_rr_new_frm_str(&soa_rr, soa_string, 0, NULL, NULL); snprintf(rr_string, MAX_LEN, "%s IN A 127.0.0.1", argv[2]); (void)ldns_rr_new_frm_str(&rr, rr_string , 0, NULL, NULL); /* compose the ixfr pkt */ (void)ldns_pkt_push_rr(answer_pkt, LDNS_SECTION_ANSWER, soa_rr); (void)ldns_pkt_push_rr(answer_pkt, LDNS_SECTION_ANSWER, rr); (void)ldns_pkt_push_rr(answer_pkt, LDNS_SECTION_ANSWER, soa_rr); /* Done. Now receive */ count = 0; while (1) { nb = recvfrom(sock, inbuf, INBUF_SIZE, 0, &addr_him, &hislen); if (nb < 1) { fprintf(stderr, "%s: recvfrom(): %s\n", argv[0], strerror(errno)); exit(EXIT_FAILURE); } printf("Got query of %d bytes\n", (int)nb); status = ldns_wire2pkt(&query_pkt, inbuf, nb); if (status != LDNS_STATUS_OK) { printf("Got bad packet: %s\n", ldns_get_errorstr_by_id(status)); continue; } query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0); printf("%d QUERY RR +%d: \n", (int)++count, ldns_pkt_id(query_pkt)); ldns_rr_print(stdout, query_rr); ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt)); 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 = (size_t) sendto(sock, outbuf, answer_size, 0, &addr_him, hislen); } if (maxcount > 0 && count >= maxcount) { fprintf(stderr, "%d queries seen... goodbye\n", (int)count); exit(EXIT_SUCCESS); } } return 0; }