ldns_status ldns_resolver_new_default(ldns_resolver **res) { ldns_resolver *r; ldns_rdf *tmp; HKEY hKey; DWORD data_sz; char* buf; char* addr; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_QUERY_VALUE, &hKey); RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, NULL, &data_sz); buf = (char*)malloc(data_sz + 1); RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, (LPBYTE)buf, &data_sz); RegCloseKey(hKey); if(buf[data_sz - 1] != 0) { buf[data_sz] = 0; } r = ldns_resolver_new(); if(!r) { free(buf); return LDNS_STATUS_MEM_ERR; } addr = strtok(buf, " "); while(addr != NULL) { tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, addr); if (!tmp) { // try ip4 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, addr); } // could not parse it, exit if (!tmp) { ldns_resolver_deep_free(r); free(buf); return LDNS_STATUS_SYNTAX_ERR; } (void)ldns_resolver_push_nameserver(r, tmp); ldns_rdf_deep_free(tmp); addr = strtok(NULL, " "); } free(buf); if(res) { *res = r; return LDNS_STATUS_OK; } else { return LDNS_STATUS_NULL; } }
DCPluginSyncFilterResult dcplugin_sync_pre_filter(DCPlugin *dcplugin, DCPluginDNSPacket *dcp_packet) { uint8_t *new_packet; ldns_rdf *edns_data; ldns_pkt *packet; size_t new_packet_size; ldns_wire2pkt(&packet, dcplugin_get_wire_data(dcp_packet), dcplugin_get_wire_data_len(dcp_packet)); edns_data = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_HEX, dcplugin_get_user_data(dcplugin)); ldns_pkt_set_edns_data(packet, edns_data); ldns_pkt2wire(&new_packet, packet, &new_packet_size); if (dcplugin_get_wire_data_max_len(dcp_packet) >= new_packet_size) { dcplugin_set_wire_data(dcp_packet, new_packet, new_packet_size); } free(new_packet); ldns_pkt_free(packet); return DCP_SYNC_FILTER_RESULT_OK; }
/* this will probably be moved to a better place in the library itself */ ldns_rr_list * get_rrset(const ldns_zone *zone, const ldns_rdf *owner_name, const ldns_rr_type qtype, const ldns_rr_class qclass) { const char* result; switch(qtype) { case LDNS_RR_TYPE_A: result = rp_get_a_record(rp_handle, owner_name->_data); break; default: result = 0; } if(!result) { return 0; } uint16_t i; ldns_rr_list *rrlist = ldns_rr_list_new(); if (!zone || !owner_name) { fprintf(stderr, "Warning: get_rrset called with NULL zone or owner name\n"); return rrlist; } ldns_rr* rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_A); ldns_rr_set_owner(rr, ldns_rdf_clone(owner_name)); ldns_rdf* rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, result); ldns_rr_push_rdf(rr, rdf); ldns_rr_list_push_rr(rrlist, ldns_rr_clone(rr)); return rrlist; }
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); }
ldns_resolver* createResolver(const char *dnsserver) { ldns_resolver *res = NULL; ldns_status status; ldns_rdf *ns_rdf; if (dnsserver) { // Use the given DNS server res = ldns_resolver_new(); if (!res) return NULL; // Create rdf from dnsserver ns_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, dnsserver); #ifdef USE_IPV6 if (!ns_rdf) ns_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, dnsserver); #endif if (!ns_rdf) { ldns_resolver_deep_free(res); return NULL; } else { status = ldns_resolver_push_nameserver(res, ns_rdf); ldns_rdf_deep_free(ns_rdf); if (status != LDNS_STATUS_OK) { ldns_resolver_free(res); return NULL; } } } else { // Use a DNS server from resolv.conf status = ldns_resolver_new_frm_file(&res, NULL); if (status != LDNS_STATUS_OK) { ldns_resolver_free(res); return NULL; } } // Enable TCP if requested ldns_resolver_set_usevc(res, mp_ldns_usevc); return res; }
/* ========== RDF ========== */ static int l_rdf_new_frm_str(lua_State *L) { uint16_t t = (uint16_t)lua_tonumber(L, 1); char *str = strdup((char*)luaL_checkstring(L, 2)); if (!str) { return 0; } ldns_rdf *new_rdf = ldns_rdf_new_frm_str((ldns_rdf_type)t, str); if (new_rdf) { lua_pushlightuserdata(L, new_rdf); return 1; } else { return 0; } }
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; }
ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) { ldns_resolver *r; const char *keyword[LDNS_RESOLV_KEYWORDS]; char word[LDNS_MAX_LINELEN + 1]; int8_t expect; uint8_t i; ldns_rdf *tmp; #ifdef HAVE_SSL ldns_rr *tmp_rr; #endif ssize_t gtr, bgtr; ldns_buffer *b; int lnr = 0, oldline; if(!line_nr) line_nr = &lnr; /* do this better * expect = * 0: keyword * 1: default domain dname * 2: NS aaaa or a record */ /* recognized keywords */ keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; keyword[LDNS_RESOLV_SEARCH] = "search"; /* these two are read but not used atm TODO */ keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; keyword[LDNS_RESOLV_OPTIONS] = "options"; keyword[LDNS_RESOLV_ANCHOR] = "anchor"; expect = LDNS_RESOLV_KEYWORD; r = ldns_resolver_new(); if (!r) { return LDNS_STATUS_MEM_ERR; } gtr = 1; word[0] = 0; oldline = *line_nr; expect = LDNS_RESOLV_KEYWORD; while (gtr > 0) { /* check comments */ if (word[0] == '#') { word[0]='x'; if(oldline == *line_nr) { /* skip until end of line */ int c; do { c = fgetc(fp); } while(c != EOF && c != '\n'); if(c=='\n' && line_nr) (*line_nr)++; } /* and read next to prepare for further parsing */ oldline = *line_nr; continue; } oldline = *line_nr; switch(expect) { case LDNS_RESOLV_KEYWORD: /* keyword */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr != 0) { if(word[0] == '#') continue; for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) { if (strcasecmp(keyword[i], word) == 0) { /* chosen the keyword and * expect values carefully */ expect = i; break; } } /* no keyword recognized */ if (expect == LDNS_RESOLV_KEYWORD) { /* skip line */ /* ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_KEYWORD_ERR; */ } } break; case LDNS_RESOLV_DEFDOMAIN: /* default domain dname */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } if(word[0] == '#') { expect = LDNS_RESOLV_KEYWORD; continue; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_DNAME_ERR; } /* DOn't free, because we copy the pointer */ ldns_resolver_set_domain(r, tmp); expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_NAMESERVER: /* NS aaaa or a record */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } if(word[0] == '#') { expect = LDNS_RESOLV_KEYWORD; continue; } if(strchr(word, '%')) { /* snip off interface labels, * fe80::222:19ff:fe31:4222%eth0 */ strchr(word, '%')[0]=0; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word); if (!tmp) { /* try ip4 */ tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word); } /* could not parse it, exit */ if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_ERR; } (void)ldns_resolver_push_nameserver(r, tmp); ldns_rdf_deep_free(tmp); expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_SEARCH: /* search list domain dname */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); b = LDNS_MALLOC(ldns_buffer); if(!b) { ldns_resolver_deep_free(r); return LDNS_STATUS_MEM_ERR; } ldns_buffer_new_frm_data(b, word, (size_t) gtr); if(ldns_buffer_status(b) != LDNS_STATUS_OK) { LDNS_FREE(b); ldns_resolver_deep_free(r); return LDNS_STATUS_MEM_ERR; } bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1); while (bgtr > 0) { gtr -= bgtr; if(word[0] == '#') { expect = LDNS_RESOLV_KEYWORD; ldns_buffer_free(b); continue; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); if (!tmp) { ldns_resolver_deep_free(r); ldns_buffer_free(b); return LDNS_STATUS_SYNTAX_DNAME_ERR; } ldns_resolver_push_searchlist(r, tmp); ldns_rdf_deep_free(tmp); bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1); } ldns_buffer_free(b); gtr = 1; expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_SORTLIST: gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); /* sortlist not implemented atm */ expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_OPTIONS: gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); /* options not implemented atm */ expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_ANCHOR: /* a file containing a DNSSEC trust anchor */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } if(word[0] == '#') { expect = LDNS_RESOLV_KEYWORD; continue; } #ifdef HAVE_SSL tmp_rr = ldns_read_anchor_file(word); (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr); ldns_rr_free(tmp_rr); #endif expect = LDNS_RESOLV_KEYWORD; break; } } /* finally, add the root domain to the search list */ ldns_resolver_push_searchlist(r, ldns_dname_new_frm_str(".")); if (res) { *res = r; return LDNS_STATUS_OK; } else { ldns_resolver_deep_free(r); return LDNS_STATUS_NULL; } }
ldns_status ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only) { ldns_rr *tsig_rr; ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name); ldns_rdf *fudge_rdf = NULL; ldns_rdf *orig_id_rdf = NULL; ldns_rdf *algorithm_rdf; ldns_rdf *error_rdf = NULL; ldns_rdf *mac_rdf = NULL; ldns_rdf *other_data_rdf = NULL; ldns_status status = LDNS_STATUS_OK; uint8_t *pkt_wire = NULL; size_t pkt_wire_len; struct timeval tv_time_signed; uint8_t *time_signed = NULL; ldns_rdf *time_signed_rdf = NULL; algorithm_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, algorithm_name); if(!key_name_rdf || !algorithm_rdf) { status = LDNS_STATUS_MEM_ERR; goto clean; } /* eww don't have create tsigtime rdf yet :( */ /* bleh :p */ if (gettimeofday(&tv_time_signed, NULL) == 0) { time_signed = LDNS_XMALLOC(uint8_t, 6); if(!time_signed) { status = LDNS_STATUS_MEM_ERR; goto clean; } ldns_write_uint64_as_uint48(time_signed, (uint64_t)tv_time_signed.tv_sec); } else { status = LDNS_STATUS_INTERNAL_ERR; goto clean; } time_signed_rdf = ldns_rdf_new(LDNS_RDF_TYPE_TSIGTIME, 6, time_signed); if(!time_signed_rdf) { LDNS_FREE(time_signed); status = LDNS_STATUS_MEM_ERR; goto clean; } fudge_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, fudge); orig_id_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, ldns_pkt_id(pkt)); error_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 0); other_data_rdf = ldns_native2rdf_int16_data(0, NULL); if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) { status = LDNS_STATUS_MEM_ERR; goto clean; } if (ldns_pkt2wire(&pkt_wire, pkt, &pkt_wire_len) != LDNS_STATUS_OK) { status = LDNS_STATUS_ERR; goto clean; } status = ldns_tsig_mac_new(&mac_rdf, pkt_wire, pkt_wire_len, key_data, key_name_rdf, fudge_rdf, algorithm_rdf, time_signed_rdf, error_rdf, other_data_rdf, query_mac, tsig_timers_only); if (!mac_rdf) { goto clean; } LDNS_FREE(pkt_wire); /* Create the TSIG RR */ tsig_rr = ldns_rr_new(); if(!tsig_rr) { status = LDNS_STATUS_MEM_ERR; goto clean; } ldns_rr_set_owner(tsig_rr, key_name_rdf); ldns_rr_set_class(tsig_rr, LDNS_RR_CLASS_ANY); ldns_rr_set_type(tsig_rr, LDNS_RR_TYPE_TSIG); ldns_rr_set_ttl(tsig_rr, 0); ldns_rr_push_rdf(tsig_rr, algorithm_rdf); ldns_rr_push_rdf(tsig_rr, time_signed_rdf); ldns_rr_push_rdf(tsig_rr, fudge_rdf); ldns_rr_push_rdf(tsig_rr, mac_rdf); ldns_rr_push_rdf(tsig_rr, orig_id_rdf); ldns_rr_push_rdf(tsig_rr, error_rdf); ldns_rr_push_rdf(tsig_rr, other_data_rdf); ldns_pkt_set_tsig(pkt, tsig_rr); return status; clean: LDNS_FREE(pkt_wire); ldns_rdf_free(key_name_rdf); ldns_rdf_free(algorithm_rdf); ldns_rdf_free(time_signed_rdf); ldns_rdf_free(fudge_rdf); ldns_rdf_free(orig_id_rdf); ldns_rdf_free(error_rdf); ldns_rdf_free(other_data_rdf); return status; }
bool ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char* key_name, const char *key_data, ldns_rdf *orig_mac_rdf, int tsig_timers_only) { ldns_rdf *fudge_rdf; ldns_rdf *algorithm_rdf; ldns_rdf *time_signed_rdf; ldns_rdf *orig_id_rdf; ldns_rdf *error_rdf; ldns_rdf *other_data_rdf; ldns_rdf *pkt_mac_rdf; ldns_rdf *my_mac_rdf; ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name); uint16_t pkt_id, orig_pkt_id; ldns_status status; uint8_t *prepared_wire = NULL; size_t prepared_wire_size = 0; ldns_rr *orig_tsig = ldns_pkt_tsig(pkt); if (!orig_tsig || ldns_rr_rd_count(orig_tsig) <= 6) { ldns_rdf_deep_free(key_name_rdf); return false; } algorithm_rdf = ldns_rr_rdf(orig_tsig, 0); time_signed_rdf = ldns_rr_rdf(orig_tsig, 1); fudge_rdf = ldns_rr_rdf(orig_tsig, 2); pkt_mac_rdf = ldns_rr_rdf(orig_tsig, 3); orig_id_rdf = ldns_rr_rdf(orig_tsig, 4); error_rdf = ldns_rr_rdf(orig_tsig, 5); other_data_rdf = ldns_rr_rdf(orig_tsig, 6); /* remove temporarily */ ldns_pkt_set_tsig(pkt, NULL); /* temporarily change the id to the original id */ pkt_id = ldns_pkt_id(pkt); orig_pkt_id = ldns_rdf2native_int16(orig_id_rdf); ldns_pkt_set_id(pkt, orig_pkt_id); prepared_wire = ldns_tsig_prepare_pkt_wire(wire, wirelen, &prepared_wire_size); status = ldns_tsig_mac_new(&my_mac_rdf, prepared_wire, prepared_wire_size, key_data, key_name_rdf, fudge_rdf, algorithm_rdf, time_signed_rdf, error_rdf, other_data_rdf, orig_mac_rdf, tsig_timers_only); LDNS_FREE(prepared_wire); if (status != LDNS_STATUS_OK) { ldns_rdf_deep_free(key_name_rdf); return false; } /* Put back the values */ ldns_pkt_set_tsig(pkt, orig_tsig); ldns_pkt_set_id(pkt, pkt_id); ldns_rdf_deep_free(key_name_rdf); if (ldns_rdf_compare(pkt_mac_rdf, my_mac_rdf) == 0) { ldns_rdf_deep_free(my_mac_rdf); return true; } else { ldns_rdf_deep_free(my_mac_rdf); return false; } }
static uint16_t dnskey_from_id(std::string &dnskey, const char *id, ::ods::keystate::keyrole role, const char *zone, int algorithm, int bDS, uint32_t ttl) { hsm_key_t *key; hsm_sign_params_t *sign_params; ldns_rr *dnskey_rr; ldns_algorithm algo = (ldns_algorithm)algorithm; /* Code to output the DNSKEY record (stolen from hsmutil) */ hsm_ctx_t *hsm_ctx = hsm_create_context(); if (!hsm_ctx) { ods_log_error("[%s] Could not connect to HSM", module_str); return false; } key = hsm_find_key_by_id(hsm_ctx, id); if (!key) { // printf("Key %s in DB but not repository\n", id); hsm_destroy_context(hsm_ctx); return 0; } /* * Sign params only need to be kept around * for the hsm_get_dnskey() call. */ sign_params = hsm_sign_params_new(); sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone); sign_params->algorithm = algo; sign_params->flags = LDNS_KEY_ZONE_KEY; if (role == ::ods::keystate::KSK) sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/ /* Get the DNSKEY record */ dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params); hsm_sign_params_free(sign_params); /* Calculate the keytag for this key, we return it. */ uint16_t keytag = ldns_calc_keytag(dnskey_rr); /* Override the TTL in the dnskey rr */ if (ttl) ldns_rr_set_ttl(dnskey_rr, ttl); char *rrstr; if (!bDS) { #if 0 ldns_rr_print(stdout, dnskey_rr); #endif rrstr = ldns_rr2str(dnskey_rr); dnskey = rrstr; LDNS_FREE(rrstr); } else { switch (algo) { case LDNS_RSASHA1: // 5 { /* DS record (SHA1) */ ldns_rr *ds_sha1_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA1); #if 0 ldns_rr_print(stdout, ds_sha1_rr); #endif rrstr = ldns_rr2str(ds_sha1_rr); dnskey = rrstr; LDNS_FREE(rrstr); ldns_rr_free(ds_sha1_rr); break; } case LDNS_RSASHA256: // 8 - RFC 5702 { /* DS record (SHA256) */ ldns_rr *ds_sha256_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA256); #if 0 ldns_rr_print(stdout, ds_sha256_rr); #endif rrstr = ldns_rr2str(ds_sha256_rr); dnskey = rrstr; LDNS_FREE(rrstr); ldns_rr_free(ds_sha256_rr); break; } default: keytag = 0; } } ldns_rr_free(dnskey_rr); hsm_key_free(key); hsm_destroy_context(hsm_ctx); return keytag; }
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; }
ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) { ldns_resolver *r; const char *keyword[LDNS_RESOLV_KEYWORDS]; char word[LDNS_MAX_LINELEN + 1]; int8_t expect; uint8_t i; ldns_rdf *tmp; #ifdef HAVE_SSL ldns_rr *tmp_rr; #endif ssize_t gtr; ldns_buffer *b; /* do this better * expect = * 0: keyword * 1: default domain dname * 2: NS aaaa or a record */ /* recognized keywords */ keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; keyword[LDNS_RESOLV_SEARCH] = "search"; /* these two are read but not used atm TODO */ keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; keyword[LDNS_RESOLV_OPTIONS] = "options"; keyword[LDNS_RESOLV_ANCHOR] = "anchor"; expect = LDNS_RESOLV_KEYWORD; r = ldns_resolver_new(); if (!r) { return LDNS_STATUS_MEM_ERR; } gtr = 1; word[0] = 0; while (gtr > 0) { /* check comments */ if (word[0] == '#') { /* read the rest of the line, should be 1 word */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); /* prepare the next string for further parsing */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); continue; } switch(expect) { case LDNS_RESOLV_KEYWORD: /* keyword */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr != 0) { for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) { if (strcasecmp(keyword[i], word) == 0) { /* chosen the keyword and * expect values carefully */ expect = i; break; } } /* no keyword recognized */ if (expect == LDNS_RESOLV_KEYWORD) { /* skip line */ /* ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_KEYWORD_ERR; */ } } break; case LDNS_RESOLV_DEFDOMAIN: /* default domain dname */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_DNAME_ERR; } /* DOn't free, because we copy the pointer */ ldns_resolver_set_domain(r, tmp); expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_NAMESERVER: /* NS aaaa or a record */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word); if (!tmp) { /* try ip4 */ tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word); } /* could not parse it, exit */ if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_ERR; } (void)ldns_resolver_push_nameserver(r, tmp); ldns_rdf_deep_free(tmp); expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_SEARCH: /* search list domain dname */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); b = LDNS_MALLOC(ldns_buffer); ldns_buffer_new_frm_data(b, word, (size_t) gtr); gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr); while (gtr > 0) { tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_DNAME_ERR; } ldns_resolver_push_searchlist(r, tmp); ldns_rdf_deep_free(tmp); gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr); } ldns_buffer_free(b); gtr = 1; expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_SORTLIST: gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); /* sortlist not implemented atm */ expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_OPTIONS: gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); /* options not implemented atm */ expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_ANCHOR: /* a file containing a DNSSEC trust anchor */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } #ifdef HAVE_SSL tmp_rr = ldns_read_anchor_file(word); (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr); ldns_rr_free(tmp_rr); #endif expect = LDNS_RESOLV_KEYWORD; break; } } if (res) { *res = r; return LDNS_STATUS_OK; } else { return LDNS_STATUS_NULL; } }
ldns_rr_list* getaddr_rdf(ldns_resolver *res, ldns_rdf *hostrdf) { ldns_rdf *rdf; ldns_resolver *r = NULL; ldns_rr_list *rrl; ldns_rr_list *ret = NULL; ldns_pkt *pkt; ldns_status status; if (ldns_rdf_get_type(hostrdf) == LDNS_RDF_TYPE_A #ifdef USE_IPV6 || ldns_rdf_get_type(hostrdf) == LDNS_RDF_TYPE_AAAA #endif ) { rdf = ldns_rdf_address_reverse(hostrdf); r = res; if (res == NULL) { status = ldns_resolver_new_frm_file(&r, NULL); if (status != LDNS_STATUS_OK) return NULL; } // Fetch PTR pkt = ldns_resolver_query(r, rdf, LDNS_RR_TYPE_PTR, LDNS_RR_CLASS_IN, LDNS_RD); if (pkt == NULL || ldns_pkt_get_rcode(pkt) != LDNS_RCODE_NOERROR) return NULL; rrl = ldns_pkt_rr_list_by_name_and_type(pkt, rdf, LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER); if (ldns_rr_list_rr_count(rrl) != 1) return NULL; ldns_rdf_deep_free(rdf); rdf = ldns_rdf_clone(ldns_rr_rdf(ldns_rr_list_rr(rrl,0),0)); ldns_pkt_free(pkt); ldns_rr_list_deep_free(rrl); } else if (ldns_rdf_get_type(hostrdf) == LDNS_RDF_TYPE_DNAME) { rdf = hostrdf; } else { return NULL; } if (r == NULL) { r = res; if (res == NULL) { status = ldns_resolver_new_frm_file(&r, NULL); if (status != LDNS_STATUS_OK) return NULL; } } #ifdef USE_IPV6 if (ldns_rdf_get_type(hostrdf) != LDNS_RDF_TYPE_A) { // Fetch AAAA pkt = ldns_resolver_query(r, rdf, LDNS_RR_TYPE_AAAA, LDNS_RR_CLASS_IN, LDNS_RD); if (pkt != NULL && ldns_pkt_get_rcode(pkt) == LDNS_RCODE_NOERROR) { rrl = ldns_pkt_rr_list_by_name_and_type(pkt, rdf, LDNS_RR_TYPE_AAAA, LDNS_SECTION_ANSWER); ldns_pkt_free(pkt); if (ldns_rr_list_rr_count(rrl) > 0) { ret = rrl; rrl = NULL; } else { ldns_rr_list_free(rrl); } } } if (ldns_rdf_get_type(hostrdf) != LDNS_RDF_TYPE_AAAA) { #else if (1) { #endif /* USE_IPV6 */ // Fetch AA pkt = ldns_resolver_query(r, rdf, LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, LDNS_RD); if (pkt != NULL && ldns_pkt_get_rcode(pkt) == LDNS_RCODE_NOERROR) { rrl = ldns_pkt_rr_list_by_name_and_type(pkt, rdf, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER); ldns_pkt_free(pkt); if (ldns_rr_list_rr_count(rrl) > 0) { if (ret == NULL) { ret = rrl; } else { ldns_rr_list_cat(ret, rrl); ldns_rr_list_free(rrl); } } else { ldns_rr_list_free(rrl); } } // if (pkt != NULL && ldns_pkt_ge... } if (res == NULL) ldns_resolver_deep_free(r); return ret; } ldns_rr_list* getaddr(ldns_resolver *res, const char *hostname) { ldns_rdf *rdf; /* Check if hostname is a ip */ rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, hostname); #ifdef USE_IPV6 if (!rdf) { rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, hostname); } #endif if (!rdf) { rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, hostname); } if (!rdf) return NULL; return getaddr_rdf(res, rdf); }
static bool retract_dnskey_by_id(int sockfd, const char *ds_retract_command, const char *id, ::ods::keystate::keyrole role, const char *zone, int algorithm) { /* Code to output the DNSKEY record (stolen from hsmutil) */ hsm_ctx_t *hsm_ctx = hsm_create_context(); if (!hsm_ctx) { ods_log_error_and_printf(sockfd, module_str, "could not connect to HSM"); return false; } hsm_key_t *key = hsm_find_key_by_id(hsm_ctx, id); if (!key) { ods_log_error_and_printf(sockfd, module_str, "key %s not found in any HSM", id); hsm_destroy_context(hsm_ctx); return false; } bool bOK = false; char *dnskey_rr_str; hsm_sign_params_t *sign_params = hsm_sign_params_new(); sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone); sign_params->algorithm = (ldns_algorithm)algorithm; sign_params->flags = LDNS_KEY_ZONE_KEY; sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/ ldns_rr *dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params); #if 0 ldns_rr_print(stdout, dnskey_rr); #endif dnskey_rr_str = ldns_rr2str(dnskey_rr); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); hsm_key_free(key); /* Replace tab with white-space */ for (int i = 0; dnskey_rr_str[i]; ++i) { if (dnskey_rr_str[i] == '\t') { dnskey_rr_str[i] = ' '; } } /* We need to strip off trailing comments before we send to any clients that might be listening */ for (int i = 0; dnskey_rr_str[i]; ++i) { if (dnskey_rr_str[i] == ';') { dnskey_rr_str[i] = '\n'; dnskey_rr_str[i+1] = '\0'; break; } } // pass the dnskey rr string to a configured // delegation signer retract program. if (ds_retract_command && ds_retract_command[0] != '\0') { /* send records to the configured command */ FILE *fp = popen(ds_retract_command, "w"); if (fp == NULL) { ods_log_error_and_printf(sockfd, module_str, "failed to run command: %s: %s", ds_retract_command, strerror(errno)); } else { int bytes_written = fprintf(fp, "%s", dnskey_rr_str); if (bytes_written < 0) { ods_log_error_and_printf(sockfd, module_str, "[%s] Failed to write to %s: %s", ds_retract_command, strerror(errno)); } else { if (pclose(fp) == -1) { ods_log_error_and_printf(sockfd, module_str, "failed to close %s: %s", ds_retract_command, strerror(errno)); } else { bOK = true; ods_printf(sockfd, "key %s retracted by %s\n", id, ds_retract_command); } } } } else { ods_log_error_and_printf(sockfd, module_str, "no \"DelegationSignerRetractCommand\" binary " "configured in conf.xml."); } LDNS_FREE(dnskey_rr_str); hsm_destroy_context(hsm_ctx); return bOK; }
static bool retract_dnskey_by_id(int sockfd, const char *ds_retract_command, const char *id, ::ods::keystate::keyrole role, const char *zone, int algorithm, bool force) { struct stat stat_ret; /* Code to output the DNSKEY record (stolen from hsmutil) */ hsm_ctx_t *hsm_ctx = hsm_create_context(); if (!hsm_ctx) { ods_log_error_and_printf(sockfd, module_str, "could not connect to HSM"); return false; } hsm_key_t *key = hsm_find_key_by_id(hsm_ctx, id); if (!key) { ods_log_error_and_printf(sockfd, module_str, "key %s not found in any HSM", id); hsm_destroy_context(hsm_ctx); return false; } bool bOK = false; char *dnskey_rr_str; hsm_sign_params_t *sign_params = hsm_sign_params_new(); sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone); sign_params->algorithm = (ldns_algorithm)algorithm; sign_params->flags = LDNS_KEY_ZONE_KEY; sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/ ldns_rr *dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params); #if 0 ldns_rr_print(stdout, dnskey_rr); #endif dnskey_rr_str = ldns_rr2str(dnskey_rr); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); hsm_key_free(key); /* Replace tab with white-space */ for (int i = 0; dnskey_rr_str[i]; ++i) { if (dnskey_rr_str[i] == '\t') { dnskey_rr_str[i] = ' '; } } /* We need to strip off trailing comments before we send to any clients that might be listening */ for (int i = 0; dnskey_rr_str[i]; ++i) { if (dnskey_rr_str[i] == ';') { dnskey_rr_str[i] = '\n'; dnskey_rr_str[i+1] = '\0'; break; } } // pass the dnskey rr string to a configured // delegation signer retract program. if (!ds_retract_command || ds_retract_command[0] == '\0') { if (!force) { ods_log_error_and_printf(sockfd, module_str, "No \"DelegationSignerRetractCommand\" " "configured. No state changes made. " "Use --force to override."); bOK = false; } /* else: Do nothing, return keytag. */ } else if (stat(ds_retract_command, &stat_ret) != 0) { /* First check that the command exists */ ods_log_error_and_printf(sockfd, module_str, "Cannot stat file %s: %s", ds_retract_command, strerror(errno)); } else if (S_ISREG(stat_ret.st_mode) && !(stat_ret.st_mode & S_IXUSR || stat_ret.st_mode & S_IXGRP || stat_ret.st_mode & S_IXOTH)) { /* Then see if it is a regular file, then if usr, grp or * all have execute set */ ods_log_error_and_printf(sockfd, module_str, "File %s is not executable", ds_retract_command); } else { /* send records to the configured command */ FILE *fp = popen(ds_retract_command, "w"); if (fp == NULL) { ods_log_error_and_printf(sockfd, module_str, "failed to run command: %s: %s", ds_retract_command, strerror(errno)); } else { int bytes_written = fprintf(fp, "%s", dnskey_rr_str); if (bytes_written < 0) { ods_log_error_and_printf(sockfd, module_str, "[%s] Failed to write to %s: %s", ds_retract_command, strerror(errno)); } else if (pclose(fp) == -1) { ods_log_error_and_printf(sockfd, module_str, "failed to close %s: %s", ds_retract_command, strerror(errno)); } else { bOK = true; ods_printf(sockfd, "key %s retracted by %s\n", id, ds_retract_command); } } } LDNS_FREE(dnskey_rr_str); hsm_destroy_context(hsm_ctx); return bOK; }
ldns_status ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet) { ldns_rr_list *rr_list; uint16_t i; /* edns tmp vars */ ldns_rr *edns_rr; uint8_t edata[4]; (void) ldns_hdr2buffer_wire(buffer, packet); rr_list = ldns_pkt_question(packet); if (rr_list) { for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { (void) ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION); } } rr_list = ldns_pkt_answer(packet); if (rr_list) { for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { (void) ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER); } } rr_list = ldns_pkt_authority(packet); if (rr_list) { for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { (void) ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY); } } rr_list = ldns_pkt_additional(packet); if (rr_list) { for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { (void) ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL); } } /* add EDNS to additional if it is needed */ if (ldns_pkt_edns(packet)) { edns_rr = ldns_rr_new(); ldns_rr_set_owner(edns_rr, ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, ".")); ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT); ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet)); edata[0] = ldns_pkt_edns_extended_rcode(packet); edata[1] = ldns_pkt_edns_version(packet); ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet)); ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata)); (void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL); ldns_rr_free(edns_rr); } /* add TSIG to additional if it is there */ if (ldns_pkt_tsig(packet)) { (void) ldns_rr2buffer_wire(buffer, ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL); } return LDNS_STATUS_OK; }
int main(int argc, char *argv[]) { ldns_resolver *res; ldns_rdf *ns; ldns_rdf *domain; ldns_rr_list *l = NULL; ldns_rr_list *dns_root = NULL; const char *root_file = "/etc/named.root"; ldns_status status; int i; char *domain_str; char *outputfile_str; ldns_buffer *outputfile_buffer; FILE *outputfile; ldns_rr *k; bool insecure = false; ldns_pkt *pkt; domain = NULL; res = NULL; if (argc < 2) { usage(stdout, argv[0]); exit(EXIT_FAILURE); } else { for (i = 1; i < argc; i++) { if (strncmp("-4", argv[i], 3) == 0) { if (address_family != 0) { fprintf(stderr, "Options -4 and -6 cannot be specified at the same time\n"); exit(EXIT_FAILURE); } address_family = 1; } else if (strncmp("-6", argv[i], 3) == 0) { if (address_family != 0) { fprintf(stderr, "Options -4 and -6 cannot be specified at the same time\n"); exit(EXIT_FAILURE); } address_family = 2; } else if (strncmp("-h", argv[i], 3) == 0) { usage(stdout, argv[0]); exit(EXIT_SUCCESS); } else if (strncmp("-i", argv[i], 2) == 0) { insecure = true; } else if (strncmp("-r", argv[i], 2) == 0) { if (strlen(argv[i]) > 2) { root_file = argv[i]+2; } else if (i+1 >= argc) { usage(stdout, argv[0]); exit(EXIT_FAILURE); } else { root_file = argv[i+1]; i++; } } else if (strncmp("-s", argv[i], 3) == 0) { store_in_file = true; } else if (strncmp("-v", argv[i], 2) == 0) { if (strlen(argv[i]) > 2) { verbosity = atoi(argv[i]+2); } else if (i+1 > argc) { usage(stdout, argv[0]); exit(EXIT_FAILURE); } else { verbosity = atoi(argv[i+1]); i++; } } else { /* create a rdf from the command line arg */ if (domain) { fprintf(stdout, "You can only specify one domain at a time\n"); exit(EXIT_FAILURE); } domain = ldns_dname_new_frm_str(argv[i]); } } if (!domain) { usage(stdout, argv[0]); exit(EXIT_FAILURE); } } dns_root = read_root_hints(root_file); if (!dns_root) { fprintf(stderr, "cannot read the root hints file\n"); exit(EXIT_FAILURE); } /* create a new resolver from /etc/resolv.conf */ status = ldns_resolver_new_frm_file(&res, NULL); if (status != LDNS_STATUS_OK) { fprintf(stderr, "Warning: Unable to create stub resolver from /etc/resolv.conf:\n"); fprintf(stderr, "%s\n", ldns_get_errorstr_by_id(status)); fprintf(stderr, "defaulting to nameserver at 127.0.0.1 for separate nameserver name lookups\n"); res = ldns_resolver_new(); ns = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, "127.0.0.1"); status = ldns_resolver_push_nameserver(res, ns); if (status != LDNS_STATUS_OK) { fprintf(stderr, "Unable to create stub resolver: %s\n", ldns_get_errorstr_by_id(status)); exit(EXIT_FAILURE); } ldns_rdf_deep_free(ns); } ldns_resolver_set_ip6(res, address_family); if (insecure) { pkt = ldns_resolver_query(res, domain, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD); if (pkt) { l = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_DNSKEY, LDNS_SECTION_ANY_NOQUESTION); } } else { l = retrieve_dnskeys(res, domain, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, dns_root); } /* separator for result data and verbosity data */ if (verbosity > 0) { fprintf(stdout, "; ---------------------------\n"); fprintf(stdout, "; Got the following keys:\n"); } if (l) { if (store_in_file) { /* create filename: * K<domain>.+<alg>.+<id>.key */ for (i = 0; (size_t) i < ldns_rr_list_rr_count(l); i++) { k = ldns_rr_list_rr(l, (size_t) i); outputfile_buffer = ldns_buffer_new(300); domain_str = ldns_rdf2str(ldns_rr_owner(k)); ldns_buffer_printf(outputfile_buffer, "K%s+%03u+%05u.key", domain_str, ldns_rdf2native_int8(ldns_rr_rdf(k, 2)), (unsigned int) ldns_calc_keytag(k)); outputfile_str = ldns_buffer_export(outputfile_buffer); if (verbosity >= 1) { fprintf(stdout, "Writing key to file %s\n", outputfile_str); } outputfile = fopen(outputfile_str, "w"); if (!outputfile) { fprintf(stderr, "Error writing key to file %s: %s\n", outputfile_str, strerror(errno)); } else { ldns_rr_print(outputfile, k); fclose(outputfile); } LDNS_FREE(domain_str); LDNS_FREE(outputfile_str); LDNS_FREE(outputfile_buffer); } } else { ldns_rr_list_print(stdout, l); } } else { fprintf(stderr, "no answer packet received, stub resolver config:\n"); ldns_resolver_print(stderr, res); } printf("\n"); ldns_rdf_deep_free(domain); ldns_resolver_deep_free(res); ldns_rr_list_deep_free(l); ldns_rr_list_deep_free(dns_root); return EXIT_SUCCESS; }
/** * 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; }
int cmd_dnskey (int argc, char *argv[]) { char *id; char *name; int type; int algo; hsm_key_t *key = NULL; ldns_rr *dnskey_rr; hsm_sign_params_t *sign_params; if (argc != 4) { usage(); return -1; } id = strdup(argv[0]); name = strdup(argv[1]); type = atoi(argv[2]); algo = atoi(argv[3]); key = hsm_find_key_by_id(NULL, id); if (!key) { printf("Key not found: %s\n", id); free(name); free(id); return -1; } if (type != LDNS_KEY_ZONE_KEY && type != LDNS_KEY_ZONE_KEY + LDNS_KEY_SEP_KEY) { printf("Invalid key type: %i\n", type); printf("Please use: %i or %i\n", LDNS_KEY_ZONE_KEY, LDNS_KEY_ZONE_KEY + LDNS_KEY_SEP_KEY); free(name); free(id); return -1; } hsm_key_info_t *key_info = hsm_get_key_info(NULL, key); switch (algo) { case LDNS_SIGN_RSAMD5: case LDNS_SIGN_RSASHA1: case LDNS_SIGN_RSASHA1_NSEC3: case LDNS_SIGN_RSASHA256: case LDNS_SIGN_RSASHA512: if (strcmp(key_info->algorithm_name, "RSA") != 0) { printf("Not an RSA key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; case LDNS_SIGN_DSA: case LDNS_SIGN_DSA_NSEC3: if (strcmp(key_info->algorithm_name, "DSA") != 0) { printf("Not a DSA key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; case LDNS_SIGN_ECC_GOST: if (strcmp(key_info->algorithm_name, "GOST") != 0) { printf("Not a GOST key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; /* TODO: We can remove the directive if we require LDNS >= 1.6.13 */ #if !defined LDNS_BUILD_CONFIG_USE_ECDSA || LDNS_BUILD_CONFIG_USE_ECDSA case LDNS_SIGN_ECDSAP256SHA256: if (strcmp(key_info->algorithm_name, "ECDSA") != 0) { printf("Not an ECDSA key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } if (key_info->keysize != 256) { printf("The key is a ECDSA/%lu, expecting ECDSA/256 for this algorithm.\n", key_info->keysize); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; case LDNS_SIGN_ECDSAP384SHA384: if (strcmp(key_info->algorithm_name, "ECDSA") != 0) { printf("Not an ECDSA key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } if (key_info->keysize != 384) { printf("The key is a ECDSA/%lu, expecting ECDSA/384 for this algorithm.\n", key_info->keysize); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; #endif default: printf("Invalid algorithm: %i\n", algo); hsm_key_info_free(key_info); free(name); free(id); return -1; } hsm_key_info_free(key_info); sign_params = hsm_sign_params_new(); sign_params->algorithm = algo; sign_params->flags = type; sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name); dnskey_rr = hsm_get_dnskey(NULL, key, sign_params); sign_params->keytag = ldns_calc_keytag(dnskey_rr); ldns_rr_print(stdout, dnskey_rr); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); hsm_key_free(key); free(name); free(id); return 0; }
int main (int argc, char **argv) { /* Local Vars */ char *out = NULL; ldns_resolver *res; ldns_rdf *domain; ldns_rdf *host; ldns_rdf *example; ldns_pkt *pkt; ldns_rr *rr; ldns_status status; /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) critical("Setup SIGALRM trap failed!"); /* Process check arguments */ if (process_arguments(argc, argv) != OK) unknown("Parsing arguments failed!"); /* Start plugin timeout */ alarm(mp_timeout); // Create DNAME from domainname domain = ldns_dname_new_frm_str(domainname); if (!domain) usage("Invalid domainname '%s'", domainname); // Create rdf from hostaddr host = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, hostname); #ifdef USE_IPV6 if (!host) host = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, hostname); #endif if (!host) { ldns_rdf_deep_free(domain); usage("Invalid hostname '%s'", hostname); } // Create DNAME from example.com example = ldns_dname_new_frm_str("exmple.com"); if (!example) usage("Invalid domainname 'example.com'"); // Create resolver res = ldns_resolver_new(); if (!res) { ldns_rdf_deep_free(domain); ldns_rdf_deep_free(host); unknown("Create resolver failed."); } // Add ns to resolver status = ldns_resolver_push_nameserver(res, host); if (status != LDNS_STATUS_OK) { ldns_rdf_deep_free(domain); ldns_rdf_deep_free(host); ldns_resolver_deep_free(res); unknown("Adding %s as NS fails.", domainname); } if (udp) { // Disable TCP ldns_resolver_set_usevc(res, 0); // Fetch SOA pkt = mp_ldns_resolver_query(res, domain, LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, 0); if (pkt == NULL || ldns_pkt_get_rcode(pkt) != LDNS_RCODE_NOERROR) { mp_strcat_comma(&out, "No UDP Answer"); } else if (ldns_pkt_aa(pkt) == 0) { mp_strcat_comma(&out, "Non Authoritative UDP Answer"); } if (mp_verbose > 2) { printf("[ SOA Answer ]----------\n"); ldns_pkt_print(stdout,pkt); } ldns_pkt_free(pkt); if (recursion) { // Fetch example.com SOA ldns_resolver_set_recursive(res, TRUE); pkt = mp_ldns_resolver_query(res, example, LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, LDNS_RD); ldns_resolver_set_recursive(res, FALSE); if (pkt && (ldns_pkt_get_rcode(pkt) != LDNS_RCODE_REFUSED && ldns_pkt_get_rcode(pkt) != LDNS_RCODE_SERVFAIL)) { mp_strcat_comma(&out, "Recursive UDP Answer"); } if (mp_verbose > 2) { printf("[ SOA Answer ]----------\n"); ldns_pkt_print(stdout,pkt); } ldns_pkt_free(pkt); } } if (tcp) { // Enable TCP ldns_resolver_set_usevc(res, 1); // Fetch SOA pkt = mp_ldns_resolver_query(res, domain, LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, 0); if (pkt == NULL || ldns_pkt_get_rcode(pkt) != LDNS_RCODE_NOERROR) { mp_strcat_comma(&out, "No TCP Answer"); } else if (ldns_pkt_aa(pkt) == 0) { mp_strcat_comma(&out, "Non Authoritative TCP Answer"); } if (mp_verbose > 2) { printf("[ SOA Answer ]----------\n"); ldns_pkt_print(stdout,pkt); } ldns_pkt_free(pkt); if (recursion) { // Fetch example.com SOA ldns_resolver_set_recursive(res, TRUE); pkt = mp_ldns_resolver_query(res, example, LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, LDNS_RD); ldns_resolver_set_recursive(res, FALSE); if (pkt && (ldns_pkt_get_rcode(pkt) != LDNS_RCODE_REFUSED && ldns_pkt_get_rcode(pkt) != LDNS_RCODE_SERVFAIL)) { mp_strcat_comma(&out, "Recursive TCP Answer"); } if (mp_verbose > 2) { printf("[ SOA Answer ]----------\n"); ldns_pkt_print(stdout,pkt); } ldns_pkt_free(pkt); } } if (axfr) { status = ldns_axfr_start(res, domain, LDNS_RR_CLASS_IN); if (status == LDNS_STATUS_OK) { rr = NULL; rr = ldns_axfr_next(res); if (rr) { mp_strcat_comma(&out, "AXFR allowed."); } } } if (out) critical("Authoritative DNS for %s: %s", domainname, out); ok("Authoritative DNS for %s", domainname); }