Commit Diff
Diff:
815eebfe982c3a17d1abdfcc7dfd02940a8703a9
4531984f03c91e418179ade198f0bacbdf0f8cad
Commit:
4531984f03c91e418179ade198f0bacbdf0f8cad
Tree:
14e643b4c8c615a4a38de280f3fd6b3cbe2f0c94
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Thu Oct 10 16:47:18 2019 UTC
Message:
TSIG is now checked on answers from the AXFR server. This paves the way for AXFR in slave mode.
blob - 4035e056c5762c1c4fe5d41e39bf7fb7a7c97b86
blob + e66ebe08802120d0d15841ef4e5d694d0ca9e48c
--- dddctl.c
+++ dddctl.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: dddctl.c,v 1.71 2019/10/10 04:08:23 pjp Exp $
+ * $Id: dddctl.c,v 1.72 2019/10/10 16:47:18 pjp Exp $
*/
#include <sys/param.h>
@@ -310,6 +310,7 @@ int icount = 0;
int vslen = 0;
char *versionstring = NULL;
u_int64_t expiredon, signedon;
+int additionalcount = 0;
/* externs */
@@ -339,25 +340,26 @@ extern struct rbtree * find_rrset(ddDB *db, char *name
extern struct rrset * find_rr(struct rbtree *rbt, u_int16_t rrtype);
extern int add_rr(struct rbtree *rbt, char *name, int len, u_int16_t rrtype, void *rdata);
-extern int raxfr_a(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_tlsa(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_srv(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_naptr(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_aaaa(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_cname(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_ns(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_ptr(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_mx(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_txt(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_dnskey(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_rrsig(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_nsec3param(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_nsec3(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_ds(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-extern int raxfr_sshfp(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
+extern int raxfr_a(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_tlsa(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_srv(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_naptr(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_aaaa(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_cname(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_ns(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_ptr(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_mx(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_txt(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_dnskey(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_rrsig(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_nsec3param(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_nsec3(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_ds(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+extern int raxfr_sshfp(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
extern u_int16_t raxfr_skip(FILE *, u_char *, u_char *);
-extern int raxfr_soa(FILE *, u_char *, u_char *, u_char *, struct soa *, int, u_int32_t, u_int16_t);
-extern int raxfr_peek(FILE *, u_char *, u_char *, u_char *, int *, int, u_int16_t *, u_int32_t);
+extern int raxfr_soa(FILE *, u_char *, u_char *, u_char *, struct soa *, int, u_int32_t, u_int16_t, HMAC_CTX *);
+extern int raxfr_peek(FILE *, u_char *, u_char *, u_char *, int *, int, u_int16_t *, u_int32_t, HMAC_CTX *);
+extern int raxfr_tsig(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *, char *);
extern int memcasecmp(u_char *, u_char *, int);
@@ -367,7 +369,7 @@ extern int dnssec;
static struct raxfr_logic {
int rrtype;
int dnssec;
- int (*raxfr)(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
+ int (*raxfr)(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
} supported[] = {
{ DNS_TYPE_A, 0, raxfr_a },
{ DNS_TYPE_NS, 0, raxfr_ns },
@@ -1329,9 +1331,6 @@ create_key_ec(char *zonename, int ttl, int flags, int
fprintf(f, "Activate: %s\n", buf);
fclose(f);
- //BN_free((BIGNUM *)ecprivatekey);
-
-
/* now for the EC public .key */
snprintf(buf, sizeof(buf), "%s.key", retval);
@@ -6435,16 +6434,17 @@ usage(int argc, char *argv[])
fprintf(stderr, "\t-z ZSK\t\tuse provided ZSK zone-signing keyname\n");
return 0;
} else if (argc == 2 && strcmp(argv[1], "query") == 0) {
- fprintf(stderr, "usage: dddctl query [-BDITZ] [-@ server] [-P port] [-p file] [-Q server] name command\n");
+ fprintf(stderr, "usage: dddctl query [-BDITZ] [-@ server] [-P port] [-p file] [-Q server]\n\t\t[-y keyname:password] name command\n");
fprintf(stderr, "\t-@ server\t\tUse server ip.\n");
- fprintf(stderr, "\t-B\t\tOutput as a BIND file.\n");
- fprintf(stderr, "\t-D\t\tUse DNSSEC (DO bit) lookup.\n");
- fprintf(stderr, "\t-I\t\tIndent output.\n");
- fprintf(stderr, "\t-T\t\tUse TCP.\n");
- fprintf(stderr, "\t-Z\t\tOutput as a zonefile.\n");
- fprintf(stderr, "\t-P port\t\tUse specified port.\n");
- fprintf(stderr, "\t-p file\t\tOutput to file.\n");
+ fprintf(stderr, "\t-B\t\t\tOutput as a BIND file.\n");
+ fprintf(stderr, "\t-D\t\t\tUse DNSSEC (DO bit) lookup.\n");
+ fprintf(stderr, "\t-I\t\t\tIndent output.\n");
+ fprintf(stderr, "\t-T\t\t\tUse TCP.\n");
+ fprintf(stderr, "\t-Z\t\t\tOutput as a zonefile.\n");
+ fprintf(stderr, "\t-P port\t\t\tUse specified port.\n");
+ fprintf(stderr, "\t-p file\t\t\tOutput to file.\n");
fprintf(stderr, "\t-Q server\t\tSynonymous with -@\n");
+ fprintf(stderr, "\t-y keyname:password\tTSIG keyname and password\n");
return 0;
} else if (argc == 2) {
@@ -6453,7 +6453,7 @@ usage(int argc, char *argv[])
fprintf(stderr, "usage: command [arg ...]\n");
fprintf(stderr, "\tbindfile zonename zonefile\n");
fprintf(stderr, "\tconfigtest [-c] [configfile]\n");
- fprintf(stderr, "\tquery [-BDITZ] [-@ server] [-P port] [-p file] [-Q server] name command\n");
+ fprintf(stderr, "\tquery [-BDITZ] [-@ server] [-P port] [-p file] [-Q server]\n\t\t[-y keyname:password] name command\n");
fprintf(stderr, "\thelp [command]\n");
fprintf(stderr, "\tsign [-KXZ] [-a algorithm] [-B bits] [-e seconds]\n\t\t[-I iterations] [-i inputfile] [-k KSK] [-m mask] [-n zonename]\n\t\t[-o output] [-S pid] [-s salt] [-t ttl] [-x serial] [-z ZSK]\n");
fprintf(stderr, "\tsshfp hostname [-k keyfile] [-t ttl]\n");
@@ -6631,6 +6631,9 @@ dig(int argc, char *argv[])
if (format & ZONE_FORMAT)
answers--;
+ if (additionalcount)
+ answers -= additionalcount;
+
fprintf(f, ";; XFR size %d records (messages %d, bytes %d)\n",
answers, segment, bytes_received);
} else {
@@ -6927,7 +6930,28 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
return -1;
}
+ if (tsigkey) {
+ uint16_t maclen;
+
+ if ((len = mybase64_decode(tsigpass, (u_char *)&pseudo_packet, sizeof(pseudo_packet))) < 0) {
+ fprintf(stderr, "bad base64 password\n");
+ return -1;
+ }
+
+ ctx = HMAC_CTX_new();
+ HMAC_Init_ex(ctx, pseudo_packet, len, EVP_sha256(), NULL);
+ maclen = htons(32);
+ HMAC_Update(ctx, (char *)&maclen, 2);
+ HMAC_Update(ctx, shabuf, sizeof(shabuf));
+ } else
+ ctx = NULL;
+ q = build_question((char *)&wh->dh, wh->len, wh->dh.additional, (tsigkey == NULL) ? NULL : shabuf);
+ if (q == NULL) {
+ fprintf(stderr, "failed to build_question\n");
+ return -1;
+ }
+
for (;;) {
len = recv(so, reply, 0xffff, MSG_PEEK | MSG_WAITALL);
if (len <= 0)
@@ -6963,13 +6987,13 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
}
segmentcount = ntohs(rwh->dh.answer);
+ if (tsigkey) {
+ segmentcount += ntohs(rwh->dh.additional);
+ additionalcount += ntohs(rwh->dh.additional);
+ rwh->dh.additional = 0;
+ }
answers += segmentcount;
- q = build_question((char *)&wh->dh, len, wh->dh.additional, (tsigkey == NULL) ? NULL : shabuf);
- if (q == NULL) {
- fprintf(stderr, "failed to build_question\n");
- return -1;
- }
if (memcmp(q->hdr->name, name, q->hdr->namelen) != 0) {
fprintf(stderr, "question name not for what we asked\n");
@@ -6985,29 +7009,55 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
p += q->hdr->namelen;
p += sizeof(u_int16_t); /* type */
p += sizeof(u_int16_t); /* class */
-
/* end of question */
-
+
estart = (u_char *)&rwh->dh;
+ if (tsigkey) {
+ HMAC_Update(ctx, estart, (p - estart));
+ }
+
if (segment == 0 && (format & ZONE_FORMAT) && f != NULL)
fprintf(f, "zone \"%s\" {\n", zonename);
segment++;
for (count = 0; count < segmentcount; count++) {
+ char mac[32];
elen = 0;
- if ((rrlen = raxfr_peek(f, p, estart, end, &rrtype, soacount, &rdlen, format)) < 0) {
+ if ((rrlen = raxfr_peek(f, p, estart, end, &rrtype, soacount, &rdlen, format, ctx)) < 0) {
fprintf(stderr, "not a SOA reply, or ERROR\n");
return -1;
}
- p = (estart + rrlen);
+ if (tsigkey && (rrtype == DNS_TYPE_TSIG)) {
+ uint16_t maclen;
+ /* do tsig checks here */
+ if ((len = raxfr_tsig(f,p,estart,end,mysoa,rdlen,ctx, (char *)&mac)) < 0) {
+ fprintf(stderr, "error with TSIG record\n");
+ return -1;
+ }
+
+ p = (estart + len);
+
+ if ((len = mybase64_decode(tsigpass, (u_char *)&pseudo_packet, sizeof(pseudo_packet))) < 0) {
+ fprintf(stderr, "bad base64 password\n");
+ return -1;
+ }
+
+ HMAC_CTX_reset(ctx);
+ HMAC_Init_ex(ctx, pseudo_packet, len, EVP_sha256(), NULL);
+ maclen = htons(32);
+ HMAC_Update(ctx, (char *)&maclen, 2);
+ HMAC_Update(ctx, mac, 32);
+ } else
+ p = (estart + rrlen);
+
if (rrtype == DNS_TYPE_SOA) {
- if ((len = raxfr_soa(f, p, estart, end, mysoa, soacount, format, rdlen)) < 0) {
- fprintf(stderr, "raxxfr_soa failed\n");
+ if ((len = raxfr_soa(f, p, estart, end, mysoa, soacount, format, rdlen, ctx)) < 0) {
+ fprintf(stderr, "raxfr_soa failed\n");
return -1;
}
p = (estart + len);
@@ -7015,7 +7065,7 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
} else {
for (sr = supported; sr->rrtype != 0; sr++) {
if (rrtype == sr->rrtype) {
- if ((len = (*sr->raxfr)(f, p, estart, end, mysoa, rdlen)) < 0) {
+ if ((len = (*sr->raxfr)(f, p, estart, end, mysoa, rdlen, ctx)) < 0) {
fprintf(stderr, "error with rrtype %d\n", sr->rrtype);
return -1;
}
@@ -7025,8 +7075,10 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
}
if (sr->rrtype == 0) {
- fprintf(stderr, "unsupported RRTYPE\n");
- return -1;
+ if (rrtype != DNS_TYPE_TSIG) {
+ fprintf(stderr, "unsupported RRTYPE %d\n", rrtype);
+ return -1;
+ }
}
}
@@ -7042,11 +7094,17 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
fprintf(stderr, ";; WARN: recieved %d more bytes.\n", len);
}
+ if (tsigkey) {
+ HMAC_CTX_free(ctx);
+ }
+
if (f != NULL) {
if ((format & ZONE_FORMAT))
fprintf(f, "}\n");
}
+ free_question(q);
+
return 0;
}
@@ -7281,7 +7339,7 @@ lookup_name(FILE *f, int so, char *zonename, u_int16_t
skip:
- if ((rrlen = raxfr_peek(f, p, estart, end, &rrtype, 0, &rdlen, format)) < 0) {
+ if ((rrlen = raxfr_peek(f, p, estart, end, &rrtype, 0, &rdlen, format, NULL)) < 0) {
fprintf(stderr, "not a SOA reply, or ERROR\n");
return -1;
}
@@ -7289,7 +7347,7 @@ skip:
p = (estart + rrlen);
if (rrtype == DNS_TYPE_SOA) {
- if ((len = raxfr_soa(f, p, estart, end, mysoa, soacount, format, rdlen)) < 0) {
+ if ((len = raxfr_soa(f, p, estart, end, mysoa, soacount, format, rdlen, NULL)) < 0) {
fprintf(stderr, "raxxfr_soa failed\n");
return -1;
}
@@ -7298,7 +7356,7 @@ skip:
} else {
for (sr = supported; sr->rrtype != 0; sr++) {
if (rrtype == sr->rrtype) {
- if ((len = (*sr->raxfr)(f, p, estart, end, mysoa, rdlen)) < 0) {
+ if ((len = (*sr->raxfr)(f, p, estart, end, mysoa, rdlen, NULL)) < 0) {
fprintf(stderr, "error with rrtype %d\n", sr->rrtype);
return -1;
}
blob - bb854dcc3ba1039797ced97b9668d9148b22822e
blob + e60084e09a14e7878c4477f2f6d3645fbf0e7f41
--- raxfr.c
+++ raxfr.c
@@ -26,7 +26,7 @@
*
*/
/*
- * $Id: raxfr.c,v 1.13 2019/06/06 14:56:08 pjp Exp $
+ * $Id: raxfr.c,v 1.14 2019/10/10 16:47:19 pjp Exp $
*/
#include <sys/types.h>
@@ -57,30 +57,33 @@
#include <sys/tree.h>
#endif /* __linux__ */
+#include <openssl/bn.h>
+#include <openssl/hmac.h>
#include "ddd-dns.h"
#include "ddd-db.h"
-int raxfr_a(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_aaaa(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_cname(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_ns(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_ptr(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_mx(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_txt(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_dnskey(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_rrsig(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_nsec3param(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_nsec3(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_ds(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_sshfp(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_tlsa(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_srv(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
-int raxfr_naptr(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t);
+int raxfr_a(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_aaaa(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_cname(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_ns(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_ptr(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_mx(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_txt(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_dnskey(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_rrsig(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_nsec3param(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_nsec3(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_ds(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_sshfp(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_tlsa(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_srv(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+int raxfr_naptr(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
u_int16_t raxfr_skip(FILE *, u_char *, u_char *);
-int raxfr_soa(FILE *, u_char *, u_char *, u_char *, struct soa *, int, u_int32_t, u_int16_t);
-int raxfr_peek(FILE *, u_char *, u_char *, u_char *, int *, int, u_int16_t *, u_int32_t);
+int raxfr_soa(FILE *, u_char *, u_char *, u_char *, struct soa *, int, u_int32_t, u_int16_t, HMAC_CTX *);
+int raxfr_peek(FILE *, u_char *, u_char *, u_char *, int *, int, u_int16_t *, u_int32_t, HMAC_CTX *);
+int raxfr_tsig(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx, char *);
extern int memcasecmp(u_char *, u_char *, int);
@@ -107,7 +110,7 @@ extern char * expand_compression(u_char *, u_char *, u
int
-raxfr_peek(FILE *f, u_char *p, u_char *estart, u_char *end, int *rrtype, int soacount, u_int16_t *rdlen, u_int32_t format)
+raxfr_peek(FILE *f, u_char *p, u_char *estart, u_char *end, int *rrtype, int soacount, u_int16_t *rdlen, u_int32_t format, HMAC_CTX *ctx)
{
int rrlen;
char *save;
@@ -157,7 +160,13 @@ raxfr_peek(FILE *f, u_char *p, u_char *estart, u_char
*rrtype = ntohs(*rtype);
- if (*rrtype == 41)
+ if (ctx != NULL) {
+ if (*rrtype != DNS_TYPE_TSIG) {
+ HMAC_Update(ctx, p, q - p);
+ }
+ }
+
+ if (*rrtype == 41 || *rrtype == DNS_TYPE_TSIG)
goto out;
humanname = convert_name(expand, elen);
@@ -216,7 +225,7 @@ raxfr_skip(FILE *f, u_char *p, u_char *estart)
}
int
-raxfr_soa(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, int soacount, u_int32_t format, u_int16_t rdlen)
+raxfr_soa(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, int soacount, u_int32_t format, u_int16_t rdlen, HMAC_CTX *ctx)
{
u_int32_t *rvalue;
char *save, *humanname;
@@ -316,13 +325,15 @@ raxfr_soa(FILE *f, u_char *p, u_char *estart, u_char *
ntohl(mysoa->expire), ntohl(mysoa->minttl));
}
}
+
+ if (ctx != NULL)
+ HMAC_Update(ctx, p, q - p);
-
return (q - estart);
}
int
-raxfr_rrsig(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_rrsig(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
struct rrsig rs;
char *save, *humanname;
@@ -409,11 +420,14 @@ raxfr_rrsig(FILE *f, u_char *p, u_char *estart, u_char
free(humanname);
free(b);
+ if (ctx != NULL)
+ HMAC_Update(ctx, p, q - p);
+
return (q - estart);
}
int
-raxfr_ds(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_ds(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
struct ds d;
u_int16_t *tmpshort;
@@ -442,11 +456,14 @@ raxfr_ds(FILE *f, u_char *p, u_char *estart, u_char *e
d.digest_type, bin2hex(d.digest, d.digestlen));
}
+ if (ctx != NULL)
+ HMAC_Update(ctx, q, p - q);
+
return (p - estart);
}
int
-raxfr_sshfp(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_sshfp(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
struct sshfp s;
char *hex;
@@ -473,11 +490,14 @@ raxfr_sshfp(FILE *f, u_char *p, u_char *estart, u_char
fprintf(f, "%u,%u,\"%s\"\n", s.algorithm, s.fptype, hex);
}
+ if (ctx != NULL)
+ HMAC_Update(ctx, q, p - q);
+
return (p - estart);
}
int
-raxfr_dnskey(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_dnskey(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
struct dnskey dk;
u_int16_t *tmpshort;
@@ -522,12 +542,16 @@ raxfr_dnskey(FILE *f, u_char *p, u_char *estart, u_cha
}
free(b);
+
+ if (ctx != NULL)
+ HMAC_Update(ctx, q, p - q);
+
return (p - estart);
}
int
-raxfr_mx(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_mx(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
u_int16_t *mxpriority;
char *save, *humanname;
@@ -567,17 +591,20 @@ raxfr_mx(FILE *f, u_char *p, u_char *estart, u_char *e
free(humanname);
+ if (ctx != NULL)
+ HMAC_Update(ctx, p, q - p);
+
return (q - estart);
}
int
-raxfr_ptr(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_ptr(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
- return (raxfr_ns(f, p, estart, end, mysoa, rdlen));
+ return (raxfr_ns(f, p, estart, end, mysoa, rdlen, ctx));
}
int
-raxfr_nsec3(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_nsec3(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
struct nsec3 n;
u_int16_t *iter;
@@ -626,11 +653,14 @@ raxfr_nsec3(FILE *f, u_char *p, u_char *estart, u_char
bitmap2human(n.bitmap, n.bitmap_len));
}
+ if (ctx != NULL)
+ HMAC_Update(ctx, brr, p - brr);
+
return (p - estart);
}
int
-raxfr_nsec3param(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_nsec3param(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
struct nsec3param np;
u_int16_t *iter;
@@ -659,12 +689,15 @@ raxfr_nsec3param(FILE *f, u_char *p, u_char *estart, u
(np.saltlen == 0 ? "-" : bin2hex(np.salt, np.saltlen)));
}
+ if (ctx != NULL)
+ HMAC_Update(ctx, q, p - q);
+
return (p - estart);
}
int
-raxfr_txt(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_txt(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
u_int8_t len;
int i;
@@ -688,12 +721,14 @@ raxfr_txt(FILE *f, u_char *p, u_char *estart, u_char *
p += i;
+ if (ctx != NULL)
+ HMAC_Update(ctx, q, p - q);
return (p - estart);
}
int
-raxfr_ns(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_ns(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
char *save, *humanname;
u_char *q = p;
@@ -724,18 +759,22 @@ raxfr_ns(FILE *f, u_char *p, u_char *estart, u_char *e
free(humanname);
+ if (ctx != NULL) {
+ HMAC_Update(ctx, p, q - p);
+ }
+
return (q - estart);
}
int
-raxfr_cname(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_cname(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
- return (raxfr_ns(f, p, estart, end, mysoa, rdlen));
+ return (raxfr_ns(f, p, estart, end, mysoa, rdlen, ctx));
}
int
-raxfr_aaaa(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_aaaa(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
char buf[INET6_ADDRSTRLEN];
struct in6_addr *ia;
@@ -750,11 +789,14 @@ raxfr_aaaa(FILE *f, u_char *p, u_char *estart, u_char
p += sizeof(*ia);
+ if (ctx != NULL)
+ HMAC_Update(ctx, q, p - q);
+
return (p - estart);
}
int
-raxfr_a(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_a(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
char buf[INET_ADDRSTRLEN];
struct in_addr *ia;
@@ -770,11 +812,14 @@ raxfr_a(FILE *f, u_char *p, u_char *estart, u_char *en
p += sizeof(*ia);
+ if (ctx != NULL)
+ HMAC_Update(ctx, q, p - q);
+
return (p - estart);
}
int
-raxfr_tlsa(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_tlsa(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
struct tlsa t;
u_char *q = p;
@@ -802,11 +847,14 @@ raxfr_tlsa(FILE *f, u_char *p, u_char *estart, u_char
t.matchtype, bin2hex(t.data, t.datalen));
}
+ if (ctx != NULL)
+ HMAC_Update(ctx, q, p - q);
+
return (p - estart);
}
int
-raxfr_srv(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_srv(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
u_int16_t *tmp16;
struct srv s;
@@ -853,11 +901,14 @@ raxfr_srv(FILE *f, u_char *p, u_char *estart, u_char *
free(humanname);
+ if (ctx != NULL)
+ HMAC_Update(ctx, p, q - p);
+
return (q - estart);
}
int
-raxfr_naptr(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen)
+raxfr_naptr(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx)
{
u_int16_t *tmp16;
struct naptr n;
@@ -945,5 +996,185 @@ raxfr_naptr(FILE *f, u_char *p, u_char *estart, u_char
free(humanname);
+ if (ctx != NULL)
+ HMAC_Update(ctx, p, q - p);
+
return (q - estart);
+}
+
+int
+raxfr_tsig(FILE *f, u_char *p, u_char *estart, u_char *end, struct soa *mysoa, u_int16_t rdlen, HMAC_CTX *ctx, char *mac)
+{
+ struct dns_tsigrr *sdt;
+ char *save;
+ char *keyname = NULL, *algname = NULL;
+ char *rawkeyname = NULL, *rawalgname = NULL;
+ char *otherdata;
+ u_char expand[256];
+ u_char *q = p;
+ u_int16_t *rtype, *rclass, *origid, *tsigerror, *otherlen;
+ u_int32_t *rttl;
+ int rlen, rrlen = -1;
+ int elen = 0;
+ int max = sizeof(expand);
+ int rawkeynamelen, rawalgnamelen;
+ int macsize = 32;
+
+ static int standardanswer = 1;
+
+
+ memset(&expand, 0, sizeof(expand));
+ save = expand_compression(q, estart, end, (u_char *)&expand, &elen, max);
+ if (save == NULL) {
+ fprintf(stderr, "expanding compression failure 0\n");
+ goto out;
+ } else
+ q = save;
+
+ keyname = convert_name(expand, elen);
+ if (keyname == NULL) {
+ goto out;
+ }
+
+ rawkeyname = malloc(elen);
+ if (rawkeyname == NULL)
+ goto out;
+
+ memcpy(rawkeyname, expand, elen);
+ rawkeynamelen = elen;
+
+ if ((q + 2) > end)
+ goto out;
+
+ rtype = (u_int16_t *)q;
+ q += 2;
+
+ if (ntohs(*rtype) != DNS_TYPE_TSIG)
+ goto out;
+
+ if ((q + 2) > end)
+ goto out;
+
+ rclass = (u_int16_t *)q;
+ q += 2;
+
+ if (ntohs(*rclass) != DNS_CLASS_ANY)
+ goto out;
+
+ if ((q + 4) > end)
+ goto out;
+
+ rttl = (u_int32_t *)q;
+ q += 4;
+
+ if (*rttl != 0)
+ goto out;
+
+ /* skip rdlen because raxfr_peek already got it */
+ if ((q + 2) > end)
+ goto out;
+ q += 2;
+
+ rlen = (q - estart);
+
+ memset(&expand, 0, sizeof(expand));
+ elen = 0;
+ save = expand_compression(q, estart, end, (u_char *)&expand, &elen, max);
+ if (save == NULL) {
+ fprintf(stderr, "expanding compression failure 0\n");
+ goto out;
+ } else
+ q = save;
+
+
+ algname = convert_name(expand, elen);
+ if (algname == NULL) {
+ goto out;
+ }
+
+ rawalgname = malloc(elen);
+ if (rawalgname == NULL)
+ goto out;
+ memcpy(rawalgname, expand, elen);
+ rawalgnamelen = elen;
+
+ if (strcasecmp(algname, "hmac-sha256.") != 0) {
+ goto out;
+ }
+
+ if ((q + sizeof(struct dns_tsigrr)) > end) {
+ goto out;
+ }
+
+ sdt = (struct dns_tsigrr *)q;
+ q += sizeof(struct dns_tsigrr);
+
+ if ((q + 2) > end)
+ goto out;
+
+ origid = (uint16_t *)q;
+ q += 2;
+
+ if ((q + 2) > end)
+ goto out;
+
+ tsigerror = (uint16_t *)q;
+ q += 2;
+
+ if ((q + 2) > end)
+ goto out;
+
+ otherlen = (uint16_t *)q;
+ q += 2;
+
+ otherdata = q;
+ q += ntohs(*otherlen);
+
+ if ((q - estart) != (rdlen + rlen)) {
+ goto out;
+ }
+
+ /* do something with the gathered data */
+
+ if (standardanswer) {
+ /* dns message */
+ HMAC_Update(ctx, rawkeyname, rawkeynamelen);
+ HMAC_Update(ctx, (char *)rclass, 2);
+ HMAC_Update(ctx, (char *)rttl, 4);
+ HMAC_Update(ctx, rawalgname, rawalgnamelen);
+ HMAC_Update(ctx, (char *)&sdt->timefudge, 8);
+ HMAC_Update(ctx, (char *)tsigerror, 2);
+ HMAC_Update(ctx, (char *)otherlen, 2);
+ if (ntohs(*otherlen))
+ HMAC_Update(ctx, otherdata, ntohs(*otherlen));
+
+ standardanswer = 0;
+ } else
+ HMAC_Update(ctx, (char *)&sdt->timefudge, 8);
+
+ HMAC_Final(ctx, mac, &macsize);
+
+ if (memcmp(sdt->mac, mac, macsize) != 0) {
+ int i;
+
+ printf("the given mac: ");
+ for (i = 0; i < macsize; i++) {
+ printf("%02x", sdt->mac[i] & 0xff);
+ }
+ printf(" does not equal the calculated mac: ");
+ for (i = 0; i < macsize; i++) {
+ printf("%02x", mac[i] & 0xff);
+ }
+ printf("\n");
+ goto out;
+ }
+
+ rrlen = (q - estart);
+
+out:
+ free(keyname);
+ free(algname);
+ free(rawkeyname);
+ free(rawalgname);
+ return (rrlen);
}
repomaster@centroid.eu