getdns_list* GNUtil::convertToList(Local<Array> array) { uint32_t len = array->Length(); getdns_list* result = getdns_list_create(); for (uint32_t i = 0; i < len; ++i) { size_t idx = getdns_list_get_length(result, &idx); Local<Value> val = array->Get(i); GetdnsType type = getGetdnsType(val); switch (type) { case IntType: getdns_list_set_int(result, idx, val->ToUint32()->Value()); break; case BoolType: if (val->IsTrue()) { getdns_list_set_int(result, idx, GETDNS_EXTENSION_TRUE); } else { getdns_list_set_int(result, idx, GETDNS_EXTENSION_FALSE); } break; case StringType: { struct getdns_bindata strdata; String::Utf8Value utf8Str(val->ToString()); int len = utf8Str.length(); strdata.data = (uint8_t*) *utf8Str; strdata.size = len; getdns_list_set_bindata(result, idx, &strdata); } break; case BinDataType: { struct getdns_bindata bdata; bdata.data = (uint8_t*) node::Buffer::Data(val); bdata.size = node::Buffer::Length(val); getdns_list_set_bindata(result, idx, &bdata); } break; case ListType: { Local<Array> subArray = Local<Array>::Cast(val); struct getdns_list* sublist = GNUtil::convertToList(subArray); getdns_list_set_list(result, idx, sublist); getdns_list_destroy(sublist); } break; case DictType: { Local<Object> subObj = val->ToObject(); struct getdns_dict* subdict = GNUtil::convertToDict(subObj); if (subdict) { getdns_list_set_dict(result, idx, subdict); getdns_dict_destroy(subdict); } } break; default: break; } } return result; }
static getdns_return_t set_cookie(getdns_dict *exts, char *cookie) { uint8_t data[40]; size_t i; getdns_return_t r = GETDNS_RETURN_GENERIC_ERROR; getdns_bindata bindata; getdns_dict *opt_parameters = getdns_dict_create(); getdns_list *options = getdns_list_create(); getdns_dict *option = getdns_dict_create(); if (*cookie == '=') cookie++; for (i = 0; i < 40 && *cookie; i++) { if (*cookie >= '0' && *cookie <= '9') data[i] = (uint8_t)(*cookie - '0') << 4; else if (*cookie >= 'a' && *cookie <= 'f') data[i] = (uint8_t)(*cookie - 'a' + 10) << 4; else if (*cookie >= 'A' && *cookie <= 'F') data[i] = (uint8_t)(*cookie - 'A' + 10) << 4; else goto done; cookie++; if (*cookie >= '0' && *cookie <= '9') data[i] |= (uint8_t)(*cookie - '0'); else if (*cookie >= 'a' && *cookie <= 'f') data[i] |= (uint8_t)(*cookie - 'a' + 10); else if (*cookie >= 'A' && *cookie <= 'F') data[i] |= (uint8_t)(*cookie - 'A' + 10); else goto done; cookie++;; } bindata.data = data; bindata.size = i; if ((r = getdns_dict_set_int(option, "option_code", 65001))) goto done; if ((r = getdns_dict_set_bindata(option, "option_data", &bindata))) goto done; if ((r = getdns_list_set_dict(options, 0, option))) goto done; if ((r = getdns_dict_set_list(opt_parameters, "options", options))) goto done; r = getdns_dict_set_dict(exts, "add_opt_parameters", opt_parameters); done: getdns_dict_destroy(option); getdns_list_destroy(options); getdns_dict_destroy(opt_parameters); return r; }
getdns_return_t _getdns_get_pubkey_pinset_list(getdns_context *ctx, const sha256_pin_t *pinset_in, getdns_list **pinset_list) { getdns_list *out = getdns_list_create_with_context(ctx); getdns_return_t r; uint8_t buf[SHA256_DIGEST_LENGTH]; getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf }; getdns_dict *pin = NULL; size_t idx = 0; if (out == NULL) return GETDNS_RETURN_MEMORY_ERROR; while (pinset_in) { pin = getdns_dict_create_with_context(ctx); if (pin == NULL) { r = GETDNS_RETURN_MEMORY_ERROR; goto fail; } if (r = getdns_dict_set_bindata(pin, "digest", &sha256), r) goto fail; memcpy(buf, pinset_in->pin, sizeof(buf)); if (r = getdns_dict_set_bindata(pin, "value", &value), r) goto fail; if (r = getdns_list_set_dict(out, idx++, pin), r) goto fail; getdns_dict_destroy(pin); pin = NULL; pinset_in = pinset_in->next; } *pinset_list = out; return GETDNS_RETURN_GOOD; fail: getdns_dict_destroy(pin); getdns_list_destroy(out); return r; }
getdns_return_t parse_args(int argc, char **argv) { getdns_return_t r = GETDNS_RETURN_GOOD; size_t i; char *arg, *c, *endptr; int t, print_api_info = 0; getdns_list *upstream_list = NULL; size_t upstream_count = 0; for (i = 1; i < argc; i++) { arg = argv[i]; if ((t = get_rrtype(arg)) >= 0) { request_type = t; continue; } else if (arg[0] == '+') { if (arg[1] == 's' && arg[2] == 'i' && arg[3] == 't' && (arg[4] == '=' || arg[4] == '\0')) { if ((r = set_cookie(extensions, arg+4))) { fprintf(stderr, "Could not set cookie:" " %d", r); break; } } else if ((r = getdns_dict_set_int(extensions, arg+1, GETDNS_EXTENSION_TRUE))) { fprintf(stderr, "Could not set extension " "\"%s\": %d\n", argv[i], r); break; } continue; } else if (arg[0] == '@') { getdns_dict *upstream = ipaddr_dict(context, arg + 1); if (upstream) { if (!upstream_list && !(upstream_list = getdns_list_create_with_context(context))){ fprintf(stderr, "Could not create upstream list\n"); return GETDNS_RETURN_MEMORY_ERROR; } getdns_list_set_dict(upstream_list, upstream_count++, upstream); } continue; } else if (arg[0] != '-') { name = arg; continue; } for (c = arg+1; *c; c++) { switch (*c) { case 'a': async = 1; break; case 'A': calltype = ADDRESS; break; case 'b': if (c[1] != 0 || ++i >= argc || !*argv[i]) { fprintf(stderr, "max_udp_payload_size " "expected after -b\n"); return GETDNS_RETURN_GENERIC_ERROR; } edns0_size = strtol(argv[i], &endptr, 10); if (*endptr || edns0_size < 0) { fprintf(stderr, "positive " "numeric max_udp_payload_size " "expected after -b\n"); return GETDNS_RETURN_GENERIC_ERROR; } getdns_context_set_edns_maximum_udp_payload_size( context, (uint16_t) edns0_size); goto next; case 'D': (void) getdns_context_set_edns_do_bit(context, 1); break; case 'd': (void) getdns_context_set_edns_do_bit(context, 0); break; case 'F': if (c[1] != 0 || ++i >= argc || !*argv[i]) { fprintf(stderr, "file name expected " "after -F\n"); return GETDNS_RETURN_GENERIC_ERROR; } query_file = argv[i]; interactive = 1; break; case 'G': calltype = GENERAL; break; case 'H': calltype = HOSTNAME; break; case 'h': print_usage(stdout, argv[0]); return CONTINUE; case 'i': print_api_info = 1; break; case 'I': interactive = 1; break; case 'j': json = 2; break; case 'J': json = 1; break; case 'p': json = 0; case 'q': quiet = 1; break; case 'r': getdns_context_set_resolution_type( context, GETDNS_RESOLUTION_RECURSING); break; case 's': getdns_context_set_resolution_type( context, GETDNS_RESOLUTION_STUB); break; case 'S': calltype = SERVICE; break; case 't': if (c[1] != 0 || ++i >= argc || !*argv[i]) { fprintf(stderr, "ttl expected " "after -t\n"); return GETDNS_RETURN_GENERIC_ERROR; } timeout = strtol(argv[i], &endptr, 10); if (*endptr || timeout < 0) { fprintf(stderr, "positive " "numeric ttl expected " "after -t\n"); return GETDNS_RETURN_GENERIC_ERROR; } getdns_context_set_timeout( context, timeout); goto next; case 'T': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TCP_ONLY); break; case 'O': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN); break; case 'L': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN); break; case 'E': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN); break; case 'u': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP); break; case 'U': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_UDP_ONLY); break; case 'B': batch_mode = 1; break; default: fprintf(stderr, "Unknown option " "\"%c\"\n", *c); for (i = 0; i < argc; i++) fprintf(stderr, "%d: \"%s\"\n", (int)i, argv[i]); return GETDNS_RETURN_GENERIC_ERROR; } } next: ; } if (r) return r; if (upstream_count && (r = getdns_context_set_upstream_recursive_servers( context, upstream_list))) { fprintf(stderr, "Error setting upstream recursive servers\n"); } if (print_api_info) { fprintf(stdout, "%s\n", getdns_pretty_print_dict( getdns_context_get_api_information(context))); return CONTINUE; } return r; }
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; }
/** * test the dict get and set routines */ void tst_dictsetget(void) { char msg[TSTMSGBUF]; size_t index = 0; uint32_t ans_int; getdns_return_t retval; struct getdns_list *list = NULL; struct getdns_dict *dict = NULL; struct getdns_dict *ansdict = NULL; tstmsg_case_begin("tst_dictsetget"); list = getdns_list_create(); dict = getdns_dict_create(); /* test dict get function against empty list and with bogus params */ tstmsg_case_msg("getdns_list_get_dict() empty list"); retval = getdns_list_get_dict(NULL, index, &dict); snprintf(msg, sizeof(msg), "getdns_list_get_dict(NULL, index, &dict),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_list_get_dict(list, index, NULL); snprintf(msg, sizeof(msg), "getdns_list_get_dict(list, index, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_dict(list, 0, &dict)"); retval = getdns_list_get_dict(list, 0, &dict); snprintf(msg, sizeof(msg), "getdns_list_get_dict,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_dict(list, 1, &dict)"); retval = getdns_list_get_dict(list, 1, &dict); snprintf(msg, sizeof(msg), "getdns_list_get_dict,retval = %d", retval); tstmsg_case_msg(msg); /* test int set function against empty list with bogus params */ tstmsg_case_msg("getdns_list_set_dict(list, 0, dict)"); retval = getdns_list_set_dict(list, -1, dict); snprintf(msg, sizeof(msg), "getdns_list_set_dict,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_set_dict(list, 1, dict)"); retval = getdns_list_set_dict(list, 1, dict); snprintf(msg, sizeof(msg), "getdns_list_set_dict,retval = %d", retval); tstmsg_case_msg(msg); /* test set and get legitimate use case */ getdns_dict_set_int(dict, "foo", 42); getdns_list_set_dict(list, index, dict); retval = getdns_list_get_dict(list, index, &ansdict); getdns_dict_get_int(ansdict, "foo", &ans_int); snprintf(msg, sizeof(msg), "getdns_list_set/get_dict,retval=%d, ans=%d", retval, ans_int); tstmsg_case_msg(msg); getdns_dict_destroy(dict); getdns_list_destroy(list); tstmsg_case_end(); return; } /* tst_dictsetget */
getdns_return_t _getdns_list_append_dict(getdns_list *list, const getdns_dict *child_dict) { if (!list) return GETDNS_RETURN_INVALID_PARAMETER; return getdns_list_set_dict(list, list->numinuse, child_dict); }