#include #include "byte.h" #include "substdio.h" #include "subfd.h" #include "subgetopt.h" #include "stralloc.h" #include "dns.h" #include "dnsdoe.h" #include "exit.h" stralloc sa = {0}; stralloc out = {0}; static void die_nomem() { substdio_putsflush(subfderr, "out of memory\n"); _exit(111); } void main(int argc, char **argv) { char *port = "25"; char proto[7] = "._tcp."; char *host = NULL; int opt; int verbose = 0; while ((opt = sgopt(argc, argv, "vutp:")) != sgoptdone) { switch(opt) { case 'p': port = sgoptarg; break; case 't': break; case 'u': byte_copy(proto, 6, "._udp."); break; case 'v': verbose = 1; } } argv += sgoptind; argc -= sgoptind; if (!argv[0]) { substdio_putsflush(subfderr, "dnstlsa [-v] [-p port] [-u(dp)|-t(cp)] host (tcp on port 25 is default)\n"); _exit(100); } host = argv[0]; if (!stralloc_copyb(&sa, "_", 1)) die_nomem(); if (!stralloc_cats(&sa, port)) die_nomem(); if (!stralloc_cats(&sa, proto)) die_nomem(); if (!stralloc_cats(&sa, host)) die_nomem(); if (verbose) { substdio_puts(subfdout, "checking for TLSA records: "); substdio_put(subfdout, sa.s, sa.len); substdio_putsflush(subfdout, "\n"); } dnsdoe(dns_tlsa(&out, &sa)); int pos = 0; unsigned char *response = (unsigned char *)out.s; while(pos < out.len && out.len - pos > 2 + 4) // sizeof(rrlen) + min(rrdata) { unsigned short rrlen = (response[pos] << 8) + response[pos + 1]; pos += 2; uint8_t usage = response[pos]; uint8_t sel = response[pos + 1]; uint8_t type = response[pos + 2]; if (usage == 0) substdio_puts(subfdout, "usage=0 "); if (usage == 1) substdio_puts(subfdout, "usage=1 "); if (usage == 2) substdio_puts(subfdout, "usage=2 "); if (usage == 3) substdio_puts(subfdout, "usage=3 "); if (sel == 0) substdio_puts(subfdout, "selector=0 "); if (sel == 1) substdio_puts(subfdout, "selector=1 "); if (type == 0) substdio_puts(subfdout, "type=0 "); // full cert if (type == 1) substdio_puts(subfdout, "type=1 "); // sha256 if (type == 2) substdio_puts(subfdout, "type=2 "); // sha512 substdio_puts(subfdout, "data="); for (int j = 3; j < rrlen; j++) { unsigned char ch = response[pos + j]; substdio_put(subfdout, "0123456789abcdef" + (ch >> 4), 1); substdio_put(subfdout, "0123456789abcdef" + (ch & 0x0F), 1); } substdio_puts(subfdout, dns_last_query_validated() ? " [dnssec validated]" : " [no dnssec validated]"); substdio_putsflush(subfdout, "\n"); pos += rrlen; } _exit(0); }