summaryrefslogtreecommitdiffstats
path: root/dnstlsa.c
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2023-08-07 16:33:27 +0200
committermanuel <manuel@mausz.at>2023-08-07 16:33:27 +0200
commit696792f08106e5bea4a8847e394401c1a68ecf9c (patch)
treef8e5481c9a86c95ff2cdc4cd803e3c0ab180e48c /dnstlsa.c
parentae63d731e9c1d9a0403aac3ee0e680a6508dff07 (diff)
downloadqmail-696792f08106e5bea4a8847e394401c1a68ecf9c.tar.gz
qmail-696792f08106e5bea4a8847e394401c1a68ecf9c.tar.bz2
qmail-696792f08106e5bea4a8847e394401c1a68ecf9c.zip
add dns_tlsa(...) and dnstlsa utility
Diffstat (limited to 'dnstlsa.c')
-rw-r--r--dnstlsa.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/dnstlsa.c b/dnstlsa.c
new file mode 100644
index 0000000..6623cfd
--- /dev/null
+++ b/dnstlsa.c
@@ -0,0 +1,99 @@
1#include <stdint.h>
2#include "byte.h"
3#include "substdio.h"
4#include "subfd.h"
5#include "subgetopt.h"
6#include "stralloc.h"
7#include "dns.h"
8#include "dnsdoe.h"
9#include "exit.h"
10
11stralloc sa = {0};
12stralloc out = {0};
13
14static void die_nomem()
15{
16 substdio_putsflush(subfderr, "out of memory\n");
17 _exit(111);
18}
19
20 #include <stdio.h>
21void main(int argc, char **argv)
22{
23 char *port = "25";
24 char proto[7] = "._tcp.";
25 char *host = NULL;
26 int opt;
27 int verbose = 0;
28
29 while ((opt = sgopt(argc, argv, "vutp:")) != sgoptdone)
30 {
31 switch(opt)
32 {
33 case 'p': port = sgoptarg; break;
34 case 't': break;
35 case 'u': byte_copy(proto, 6, "._udp."); break;
36 case 'v': verbose = 1;
37 }
38 }
39
40 argv += sgoptind;
41 argc -= sgoptind;
42
43 if (!argv[0])
44 {
45 substdio_putsflush(subfderr, "dnstlsa [-v] [-p port] [-u(dp)|-t(cp)] host (tcp on port 25 is default)\n");
46 _exit(100);
47 }
48 host = argv[0];
49
50 if (!stralloc_copyb(&sa, "_", 1)) die_nomem;
51 if (!stralloc_cats(&sa, port)) die_nomem;
52 if (!stralloc_cats(&sa, proto)) die_nomem;
53 if (!stralloc_cats(&sa, host)) die_nomem;
54
55 if (verbose)
56 {
57 substdio_puts(subfdout, "checking for TLSA records: ");
58 substdio_put(subfdout, sa.s, sa.len);
59 substdio_putsflush(subfdout, "\n");
60 }
61
62 dns_init(0);
63 dnsdoe(dns_tlsa(&out, &sa));
64
65 int pos = 0;
66 unsigned char *response = (unsigned char *)out.s;
67 while(pos < out.len && out.len - pos > 2 + 4) // sizeof(rrlen) + min(rrdata)
68 {
69 unsigned short rrlen = (response[pos] << 8) + response[pos + 1];
70 pos += 2;
71 uint8_t usage = response[pos];
72 uint8_t sel = response[pos + 1];
73 uint8_t type = response[pos + 2];
74
75 if (usage == 0) substdio_puts(subfdout, "usage=0 ");
76 if (usage == 1) substdio_puts(subfdout, "usage=1 ");
77 if (usage == 2) substdio_puts(subfdout, "usage=2 ");
78 if (usage == 3) substdio_puts(subfdout, "usage=3 ");
79
80 if (sel == 0) substdio_puts(subfdout, "selector=0 ");
81 if (sel == 1) substdio_puts(subfdout, "selector=1 ");
82
83 if (type == 0) substdio_puts(subfdout, "type=0 "); // full cert
84 if (type == 1) substdio_puts(subfdout, "type=1 "); // sha256
85 if (type == 2) substdio_puts(subfdout, "type=2 "); // sha512
86
87 substdio_puts(subfdout, "data="); // sha512
88 for (int j = 3; j < rrlen; j++)
89 {
90 unsigned char ch = response[pos + j];
91 substdio_put(subfdout, "0123456789abcdef" + (ch >> 4), 1);
92 substdio_put(subfdout, "0123456789abcdef" + (ch & 0x0F), 1);
93 }
94 substdio_putsflush(subfdout, "\n");
95 pos += rrlen;
96 }
97
98 _exit(0);
99}