/* * 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\""); }
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; }
/*---------------------------------------- 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
/** * test the dict get and set routines */ void tst_dictsetget(void) { char msg[TSTMSGBUF]; char key[20]; uint32_t int1; uint32_t int2; getdns_return_t retval; struct getdns_dict *newdict; struct getdns_dict *ansdict; struct getdns_dict *dict = NULL; tstmsg_case_begin("tst_dictsetget"); dict = getdns_dict_create(); /* test get function against empty list and with bogus params */ strcpy(key, "foo"); tstmsg_case_msg("getdns_dict_get_dict() empty dict"); retval = getdns_dict_get_dict(NULL, key, &ansdict); snprintf(msg, sizeof(msg), "test 7: getdns_dict_get_dict(NULL, key, &ansdict),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_dict_get_dict(dict, key, NULL); snprintf(msg, sizeof(msg), "test 8: getdns_dict_get_dict(dict, key, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_dict(dict, NULL, &ansdict)"); retval = getdns_dict_get_dict(dict, NULL, &ansdict); snprintf(msg, sizeof(msg), "test 9: getdns_dict_get_dict,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_dict(dict, key, &ansdict)"); retval = getdns_dict_get_dict(dict, key, &ansdict); snprintf(msg, sizeof(msg), "test 10: getdns_list_get_dict,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"); newdict = getdns_dict_create(); getdns_dict_set_int(newdict, "foo", 42); getdns_dict_set_int(newdict, "bar", 52); tstmsg_case_msg("getdns_dict_set_dict(dict, key, newdict)"); retval = getdns_dict_set_dict(dict, key, newdict); snprintf(msg, sizeof(msg), "test 11: getdns_dict_set_dict,retval=%d,key=%s", retval, key); tstmsg_case_msg(msg); getdns_dict_destroy(newdict); tstmsg_case_msg("getdns_dict_get_dict(dict, key, &ansdict)"); retval = getdns_dict_get_dict(dict, key, &ansdict); getdns_dict_get_int(ansdict, "foo", &int1); getdns_dict_get_int(ansdict, "bar", &int2); snprintf(msg, sizeof(msg), "test 12: getdns_dict_get_dict,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_dictsetget */