Local<Value> GNUtil::convertToJSObj(struct getdns_dict* dict) { if (!dict) { return Nan::Null(); } // try it as an IP char* ipStr = getdns_dict_to_ip_string(dict); if (ipStr) { Local<Value> result = Nan::New<String>(ipStr).ToLocalChecked(); free(ipStr); return result; } getdns_list* names; getdns_dict_get_names(dict, &names); size_t len = 0; Local<Object> result = Nan::New<Object>(); getdns_list_get_length(names, &len); for (size_t i = 0; i < len; ++i) { getdns_bindata* nameBin; getdns_list_get_bindata(names, i, &nameBin); Local<Value> name = Nan::New<String>((char*) nameBin->data).ToLocalChecked(); getdns_data_type type; getdns_dict_get_data_type(dict, (char*)nameBin->data, &type); switch (type) { case t_bindata: { getdns_bindata* data = NULL; getdns_dict_get_bindata(dict, (char*)nameBin->data, &data); result->Set(name, convertBinData(data, (char*) nameBin->data)); break; } case t_int: { uint32_t res = 0; getdns_dict_get_int(dict, (char*)nameBin->data, &res); result->Set(name, Nan::New<Integer>(res)); break; } case t_dict: { getdns_dict* subdict = NULL; getdns_dict_get_dict(dict, (char*)nameBin->data, &subdict); result->Set(name, GNUtil::convertToJSObj(subdict)); break; } case t_list: { getdns_list* list = NULL; getdns_dict_get_list(dict, (char*)nameBin->data, &list); result->Set(name, GNUtil::convertToJSArray(list)); break; } default: break; } } getdns_list_destroy(names); return result; }
/* * extract_response extracts all of the various information * a test may want to look at from the response. */ void extract_response(struct getdns_dict *response, struct extracted_response *ex_response) { ck_assert_msg(response != NULL, "Response should not be NULL"); ASSERT_RC(getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type), GETDNS_RETURN_GOOD, "Failed to extract \"top answer_type\""); ASSERT_RC(getdns_dict_get_bindata(response, "canonical_name", &ex_response->top_canonical_name), GETDNS_RETURN_GOOD, "Failed to extract \"top canonical_name\""); ASSERT_RC(getdns_dict_get_list(response, "just_address_answers", &ex_response->just_address_answers), GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\""); ck_assert_msg(ex_response->just_address_answers != NULL, "just_address_answers should not be NULL"); ASSERT_RC(getdns_dict_get_list(response, "replies_full", &ex_response->replies_full), GETDNS_RETURN_GOOD, "Failed to extract \"replies_full\""); ck_assert_msg(ex_response->replies_full != NULL, "replies_full should not be NULL"); ASSERT_RC(getdns_dict_get_list(response, "replies_tree", &ex_response->replies_tree), GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree\""); ck_assert_msg(ex_response->replies_tree != NULL, "replies_tree should not be NULL"); ASSERT_RC(getdns_list_get_dict(ex_response->replies_tree, 0, &ex_response->replies_tree_sub_dict), GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree[0]\""); ck_assert_msg(ex_response->replies_tree_sub_dict != NULL, "replies_tree[0] dict should not be NULL"); ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "additional", &ex_response->additional), GETDNS_RETURN_GOOD, "Failed to extract \"additional\""); ck_assert_msg(ex_response->additional != NULL, "additional should not be NULL"); ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "answer", &ex_response->answer), GETDNS_RETURN_GOOD, "Failed to extract \"answer\""); ck_assert_msg(ex_response->answer != NULL, "answer should not be NULL"); ASSERT_RC(getdns_dict_get_int(ex_response->replies_tree_sub_dict, "answer_type", &ex_response->answer_type), GETDNS_RETURN_GOOD, "Failed to extract \"answer_type\""); ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "authority", &ex_response->authority), GETDNS_RETURN_GOOD, "Failed to extract \"authority\""); ck_assert_msg(ex_response->authority != NULL, "authority should not be NULL"); ASSERT_RC(getdns_dict_get_bindata(ex_response->replies_tree_sub_dict, "canonical_name", &ex_response->canonical_name), GETDNS_RETURN_GOOD, "Failed to extract \"canonical_name\""); ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "header", &ex_response->header), GETDNS_RETURN_GOOD, "Failed to extract \"header\""); ck_assert_msg(ex_response->header != NULL, "header should not be NULL"); ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "question", &ex_response->question), GETDNS_RETURN_GOOD, "Failed to extract \"question\""); ck_assert_msg(ex_response->question != NULL, "question should not be NULL"); ASSERT_RC(getdns_dict_get_int(response, "status", &ex_response->status), GETDNS_RETURN_GOOD, "Failed to extract \"status\""); }
/* Set up the callback function, which will also do the processing of the results */ void callback(getdns_context *context, getdns_callback_type_t callback_type, getdns_dict *response, void *userarg, getdns_transaction_t transaction_id) { getdns_return_t r; /* Holder for all function returns */ getdns_list *replies_tree; size_t n_replies, i; (void) context; (void) userarg; /* unused parameters */ switch(callback_type) { case GETDNS_CALLBACK_CANCEL: printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); return; case GETDNS_CALLBACK_TIMEOUT: printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); return; case GETDNS_CALLBACK_ERROR: printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); return; default: break; } assert( callback_type == GETDNS_CALLBACK_COMPLETE ); if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree))) fprintf(stderr, "Could not get \"replies_tree\" from response"); else if ((r = getdns_list_get_length(replies_tree, &n_replies))) fprintf(stderr, "Could not get replies_tree\'s length"); else for (i = 0; i < n_replies && r == GETDNS_RETURN_GOOD; i++) { getdns_dict *reply; getdns_list *answer; size_t n_answers, j; if ((r = getdns_list_get_dict(replies_tree, i, &reply))) fprintf(stderr, "Could not get address %zu from just_address_answers", i); else if ((r = getdns_dict_get_list(reply, "answer", &answer))) fprintf(stderr, "Could not get \"address_data\" from address"); else if ((r = getdns_list_get_length(answer, &n_answers))) fprintf(stderr, "Could not get answer section\'s length"); else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) { getdns_dict *rr; getdns_bindata *address = NULL; if ((r = getdns_list_get_dict(answer, j, &rr))) fprintf(stderr, "Could net get rr %zu from answer section", j); else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD) printf("The IPv4 address is "); else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD) printf("The IPv6 address is "); if (address) { char *address_str; if (!(address_str = getdns_display_ip_address(address))) { fprintf(stderr, "Could not convert second address to string"); r = GETDNS_RETURN_MEMORY_ERROR; break; } printf("%s\n", address_str); free(address_str); } } } if (r) { assert( r != GETDNS_RETURN_GOOD ); fprintf(stderr, ": %d\n", r); } getdns_dict_destroy(response); }
static getdns_return_t validate_chain(getdns_dict *response) { getdns_return_t r; getdns_list *validation_chain; getdns_list *replies_tree; getdns_dict *reply; getdns_list *to_validate; getdns_list *trust_anchor; size_t i; int s; if (!(to_validate = getdns_list_create())) return GETDNS_RETURN_MEMORY_ERROR; trust_anchor = getdns_root_trust_anchor(NULL); if ((r = getdns_dict_get_list( response, "validation_chain", &validation_chain))) goto error; if ((r = getdns_dict_get_list( response, "replies_tree", &replies_tree))) goto error; fprintf(stdout, "replies_tree dnssec_status: "); switch ((s = getdns_validate_dnssec( replies_tree, validation_chain, trust_anchor))) { case GETDNS_DNSSEC_SECURE: fprintf(stdout, "GETDNS_DNSSEC_SECURE\n"); break; case GETDNS_DNSSEC_BOGUS: fprintf(stdout, "GETDNS_DNSSEC_BOGUS\n"); break; case GETDNS_DNSSEC_INDETERMINATE: fprintf(stdout, "GETDNS_DNSSEC_INDETERMINATE\n"); break; case GETDNS_DNSSEC_INSECURE: fprintf(stdout, "GETDNS_DNSSEC_INSECURE\n"); break; case GETDNS_DNSSEC_NOT_PERFORMED: fprintf(stdout, "GETDNS_DNSSEC_NOT_PERFORMED\n"); break; default: fprintf(stdout, "%d\n", (int)s); } i = 0; while (!(r = getdns_list_get_dict(replies_tree, i++, &reply))) { if ((r = getdns_list_set_dict(to_validate, 0, reply))) goto error; fprintf( stdout , "reply %zu, dnssec_status: ", i); switch ((s = getdns_validate_dnssec( to_validate, validation_chain, trust_anchor))) { case GETDNS_DNSSEC_SECURE: fprintf(stdout, "GETDNS_DNSSEC_SECURE\n"); break; case GETDNS_DNSSEC_BOGUS: fprintf(stdout, "GETDNS_DNSSEC_BOGUS\n"); break; case GETDNS_DNSSEC_INDETERMINATE: fprintf(stdout, "GETDNS_DNSSEC_INDETERMINATE\n"); break; case GETDNS_DNSSEC_INSECURE: fprintf(stdout, "GETDNS_DNSSEC_INSECURE\n"); break; case GETDNS_DNSSEC_NOT_PERFORMED: fprintf(stdout, "GETDNS_DNSSEC_NOT_PERFORMED\n"); break; default: fprintf(stdout, "%d\n", (int)s); } } if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM) r = GETDNS_RETURN_GOOD; error: getdns_list_destroy(trust_anchor); getdns_list_destroy(to_validate); return GETDNS_RETURN_GOOD; }
/*---------------------------------------- getkeyviadane fetch the smime/a key identified by the encoded keyid and host name populate *certtxt with the key record, caller must free certtxt */ void getkeyviadane(char *dname, int rrtype, char **certtxt) { int i; uint32_t status; size_t nans; size_t numrrs; int rrnum; char getdnserr[MAX_ERROR_STRING+1]; uint32_t recrrtype; getdns_return_t getdnsret; getdns_context *getdnsctx = NULL; getdns_dict *getdnsrsp = NULL; getdns_dict *dnsrec = NULL; getdns_dict *rr = NULL; getdns_dict *rrdata = NULL; getdns_list *dnsreplytree = NULL; getdns_list *dnsans = NULL; getdns_bindata *rawrdata = NULL; *certtxt = NULL; // create the context for DNS resolution using local OS system settings getdnsret = getdns_context_create(&getdnsctx, 1); if(getdnsret != GETDNS_RETURN_GOOD) { getdns_strerror(getdnsret, getdnserr, MAX_ERROR_STRING); fprintf(stderr, "error creating getdns context, %d, %s\n" , getdnsret, getdnserr); return; } // getdns_context_set_resolution_type(getdnsctx, GETDNS_RESOLUTION_STUB); // perform the DNS resolution request getdnsret = getdns_general_sync(getdnsctx, dname, rrtype, NULL, &getdnsrsp); if(getdnsret != GETDNS_RETURN_GOOD) { getdns_strerror(getdnsret, getdnserr, MAX_ERROR_STRING); fprintf(stderr, "DNS request failed, %d, %s\n", getdnsret, getdnserr); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } // sanity check the result of the query getdnsret = getdns_dict_get_int(getdnsrsp, (char *) "status", &status); if(getdnsret != GETDNS_RETURN_GOOD || status != GETDNS_RESPSTATUS_GOOD) { fprintf(stderr, "DNS request did not return results\n"); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } getdnsret = getdns_dict_get_list(getdnsrsp, (char *)"replies_tree", &dnsreplytree); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "DNS reply tree empty\n"); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } nans = 0; getdns_list_get_length(dnsreplytree, &nans); for(i=0; i<nans && *certtxt == NULL; i++) { // extract a record from the reply tree, extract answer from that record getdns_list_get_dict(dnsreplytree, i, &dnsrec); getdnsret = getdns_dict_get_list(dnsrec, (char *)"answer", &dnsans); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "answer missing from DNS reply tree, exiting\n"); exit(1); } // walk the RRs in the DNS answer getdns_list_get_length(dnsans, &numrrs); for(rrnum=0; rrnum < numrrs && *certtxt == NULL; rrnum++) { getdns_list_get_dict(dnsans, rrnum, &rr); recrrtype = 0; getdns_dict_get_int(rr, (char *)"type", &recrrtype); if(recrrtype == rrtype) { getdns_dict_get_dict(rr, (char *)"rdata", &rrdata); getdnsret = getdns_dict_get_bindata(rrdata, (char *)"rdata_raw" , &rawrdata); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "error, rdata missing address\n"); } else { *certtxt = (char *) malloc(rawrdata->size + 1); memcpy(*certtxt, rawrdata->data, rawrdata->size); *certtxt[rawrdata->size] = '\0'; } } } // for rrnum } // for i in nans getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } // getkeyviadane
int main(int argc, char *argv[]) { char *name = "getdnsapi.net"; getdns_context *context; getdns_return_t ret; getdns_dict *extensions; getdns_dict *response; uint32_t status; uint32_t dnssec_status; uint32_t type; getdns_list *replies_tree; size_t nanswers; int i; char element[MAXELEM]; if (argc > 1) name = argv[1]; if ((ret = getdns_context_create(&context, 1)) != GETDNS_RETURN_GOOD) { fprintf(stderr, "getdns_context_create: %s\n", getdns_get_errorstr_by_id(ret)); return 1; } extensions = getdns_dict_create(); if ((ret = getdns_dict_set_int(extensions, "/dnssec_return_status", GETDNS_EXTENSION_TRUE)) != GETDNS_RETURN_GOOD) { fprintf(stderr, "getdns_dict_set_int(dnssec_return_status): %s\n", getdns_get_errorstr_by_id(ret)); return 1; } if ((ret = getdns_address_sync(context, name, extensions, &response)) != GETDNS_RETURN_GOOD) { fprintf(stderr, "getdns_address_sync: %s\n", getdns_get_errorstr_by_id(ret)); return 1; } (void)getdns_dict_get_int(response, "status", &status); if (status != GETDNS_RESPSTATUS_GOOD) { printf("Bad status: "); switch (status) { case GETDNS_RESPSTATUS_NO_NAME: printf("GETDNS_RESPSTATUS_NO_NAME\n"); break; case GETDNS_RESPSTATUS_ALL_TIMEOUT: printf("GETDNS_RESPSTATUS_ALL_TIMEOUT\n"); break; default: break; } } if ((ret = getdns_dict_get_list(response, "/replies_tree", &replies_tree)) != GETDNS_RETURN_GOOD) { fprintf(stderr, "getdns_dict_get_list(replies_tree): %s\n", getdns_get_errorstr_by_id(ret)); return 1; } (void)getdns_list_get_length(replies_tree, &nanswers); printf("%d answers\n", (int)nanswers); for ( i = 0 ; i < (int)nanswers ; i++ ) { snprintf(element, MAXELEM, "/replies_tree/%d/dnssec_status", i); (void)getdns_dict_get_int(response, element, &dnssec_status); snprintf(element, MAXELEM, "/replies_tree/%d/answer/0/type", i); (void)getdns_dict_get_int(response, element, &type); printf("dnssec_status for %s record: %s\n", address_type_to_string(type), dnssec_status_to_string(dnssec_status)); } /* * handy debugging tool - uncomment if wanted */ /* printf("%s\n", getdns_pretty_print_dict(response)); */ return 0; }
/** * test the list get and set routines */ void tst_listsetget(void) { char msg[TSTMSGBUF]; char key[20]; size_t index; uint32_t int1; uint32_t int2; getdns_return_t retval; struct getdns_list *newlist; struct getdns_list *anslist; struct getdns_dict *dict = NULL; tstmsg_case_begin("tst_listsetget"); dict = getdns_dict_create(); /* test get function against empty list and with bogus params */ strcpy(key, "foo"); tstmsg_case_msg("getdns_dict_get_list() empty dict"); retval = getdns_dict_get_list(NULL, key, &anslist); snprintf(msg, sizeof(msg), "test 13: getdns_dict_get_list(NULL, key, &anslist),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_dict_get_list(dict, key, NULL); snprintf(msg, sizeof(msg), "test 14: getdns_dict_get_list(dict, key, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_list(dict, NULL, &anslist)"); retval = getdns_dict_get_list(dict, NULL, &anslist); snprintf(msg, sizeof(msg), "test 15: getdns_dict_get_list,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_list(dict, key, &anslist)"); retval = getdns_dict_get_list(dict, key, &anslist); snprintf(msg, sizeof(msg), "test 16: getdns_list_get_list,retval = %d", retval); tstmsg_case_msg(msg); getdns_dict_destroy(dict); /* TODO: test getdns_dict_set functions with bogus params */ /* test set and get legitimate use case */ dict = getdns_dict_create(); strcpy(key, "foo"); newlist = getdns_list_create(); getdns_list_add_item(newlist, &index); getdns_list_set_int(newlist, index, 42); getdns_list_add_item(newlist, &index); getdns_list_set_int(newlist, index, 52); tstmsg_case_msg("getdns_dict_set_list(dict, key, newlist)"); retval = getdns_dict_set_list(dict, key, newlist); snprintf(msg, sizeof(msg), "test 17: getdns_dict_set_list,retval=%d,key=%s", retval, key); tstmsg_case_msg(msg); getdns_list_destroy(newlist); tstmsg_case_msg("getdns_dict_get_list(dict, key, &anslist)"); retval = getdns_dict_get_list(dict, key, &anslist); getdns_list_get_int(anslist, 0, &int1); getdns_list_get_int(anslist, 1, &int2); snprintf(msg, sizeof(msg), "test 18: getdns_dict_get_list,retval=%d,key=%s,int1=%d,int2=%d", retval, key, int1, int2); tstmsg_case_msg(msg); getdns_dict_destroy(dict); tstmsg_case_end(); return; } /* tst_listsetget */