/* * Copyright (c) 2016, NORDUnet A/S. * See LICENSE for licensing information. */ #include #include #include #include #include #include #include "erlport.h" #include "dnssec_test.h" static char *testmode = NULL; /* getdns/src/convert.c */ getdns_return_t getdns_wire2rr_dict(const uint8_t *wire, size_t wire_len, getdns_dict **rr_dict); #if !defined(TEST) static getdns_return_t validate(const unsigned char *records, size_t records_len, getdns_list *trust_anchors) { getdns_return_t r = GETDNS_DNSSEC_INDETERMINATE; getdns_list *to_validate = getdns_list_create(); getdns_list *support_records = getdns_list_create(); getdns_dict *records_dict = NULL; if (to_validate == NULL || support_records == NULL) { r = GETDNS_RETURN_MEMORY_ERROR; goto out; } /* TODO: figure out if we get _all_ RRs in records here bc i have the feeling that we're not supposed to mix RR types in the same dict; maybe this will help some: https://getdnsapi.net/pipermail/users/2015-May/000032.html */ r = getdns_wire2rr_dict(records, records_len, &records_dict); if (r) goto out; /* to_validate: one dict with the DS and one with a RRSIG for that DS support_records: DS and DNSKEY dicts with accompanying RRSIG's trust_anchors: DNSKEY (or DS) */ r = getdns_list_set_dict(to_validate, i, records_dict); if (r) goto out; r = getdns_validate_dnssec(to_validate, support_records, trust_anchors); out: if (to_validate) getdns_list_destroy(to_validate); if (support_records) getdns_list_destroy(support_records); return r; } #endif /* !TEST */ static void loop(getdns_list *trust_anchors) { getdns_return_t r = GETDNS_RETURN_GENERIC_ERROR; unsigned char buf[65536]; ssize_t len; while ((len = read_command(buf, sizeof(buf), 4)) > 0) { unsigned char *reply = NULL; #if !defined(TEST) r = validate(buf, len, trust_anchors); #else r = test_validate(buf, len, trust_anchors, testmode); #endif switch (r) { case GETDNS_RETURN_GOOD: reply = (unsigned char *) "valid"; break; default: fprintf(stderr, "error %d\n", r); /* DEBUG */ reply = (unsigned char *) "err"; } write_reply(reply, strlen((const char *) reply), 4); } } int main(int argc, char *argv[]) { int c; getdns_list *trust_anchors = NULL; time_t trust_anchor_date; while (1) { static struct option long_options[] = { {"testmode", required_argument, NULL, 't'}, {0, 0, 0, 0}}; c = getopt_long(argc, argv, "", long_options, NULL); if (c == -1) break; switch (c) { #if defined(TEST) case 't': testmode = optarg; break; #endif default: fprintf(stderr, "dnssecport: bad option: %s", argv[optind]); return -1; } } if (optind < argc) /* Using getdns trust anchor. */ { trust_anchors = getdns_root_trust_anchor(&trust_anchor_date); } loop(trust_anchors); return 0; }