aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2015-10-06 17:57:00 +0000
committerWerner Koch <[email protected]>2015-10-06 17:57:00 +0000
commit211b8084ee4391baec35e8c5bd75a9ecbcb889a7 (patch)
tree294985eaf97d31437514c136c628693e5616743d
parentdirmngr: Change DNS code to make additions easier. (diff)
downloadgnupg-211b8084ee4391baec35e8c5bd75a9ecbcb889a7.tar.gz
gnupg-211b8084ee4391baec35e8c5bd75a9ecbcb889a7.zip
dirmngr: Improve DNS code to retrieve arbitrary records.
* dirmngr/dns-cert.c (get_dns_cert): Add hack to retrieve arbitrary resource records. * dirmngr/dns-cert.h (DNS_CERTTYPE_RRBASE): New. (DNS_CERTTYPE_RR61): New. -- This has been tested with ADNS on Unix and with the standard resolver. Because ADNS works it should also work on Windows. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--dirmngr/dns-cert.c55
-rw-r--r--dirmngr/dns-cert.h4
2 files changed, 55 insertions, 4 deletions
diff --git a/dirmngr/dns-cert.c b/dirmngr/dns-cert.c
index 03c1de1e6..3845a4b25 100644
--- a/dirmngr/dns-cert.c
+++ b/dirmngr/dns-cert.c
@@ -99,7 +99,11 @@ get_dns_cert (const char *name, int want_certtype,
return err;
}
- if (adns_synchronous (state, name, (adns_r_unknown | my_adns_r_cert),
+ if (adns_synchronous (state, name,
+ (adns_r_unknown
+ | (want_certtype < DNS_CERTTYPE_RRBASE
+ ? my_adns_r_cert
+ : (want_certtype - DNS_CERTTYPE_RRBASE))),
adns_qf_quoteok_query, &answer))
{
err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
@@ -122,6 +126,26 @@ get_dns_cert (const char *name, int want_certtype,
int datalen = answer->rrs.byteblock[count].len;
const unsigned char *data = answer->rrs.byteblock[count].data;
+ /* First check for our generic RR hack. */
+ if (datalen
+ && want_certtype >= DNS_CERTTYPE_RRBASE
+ && ((want_certtype - DNS_CERTTYPE_RRBASE)
+ == (answer->type & ~adns_r_unknown)))
+ {
+ /* Found the requested record - return it. */
+ *r_key = xtrymalloc (datalen);
+ if (!*r_key)
+ err = gpg_err_make (default_errsource,
+ gpg_err_code_from_syserror ());
+ else
+ {
+ memcpy (*r_key, data, datalen);
+ *r_keylen = datalen;
+ err = 0;
+ }
+ goto leave;
+ }
+
if (datalen < 5)
continue; /* Truncated CERT record - skip. */
@@ -219,7 +243,11 @@ get_dns_cert (const char *name, int want_certtype,
err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
- r = res_query (name, C_IN, T_CERT, answer, 65536);
+ r = res_query (name, C_IN,
+ (want_certtype < DNS_CERTTYPE_RRBASE
+ ? T_CERT
+ : (want_certtype - DNS_CERTTYPE_RRBASE)),
+ answer, 65536);
/* Not too big, not too small, no errors and at least 1 answer. */
if (r >= sizeof (HEADER) && r <= 65536
&& (((HEADER *) answer)->rcode) == NOERROR
@@ -283,7 +311,28 @@ get_dns_cert (const char *name, int want_certtype,
pt += 2;
/* Check the type and parse. */
- if (type == T_CERT)
+ if (want_certtype >= DNS_CERTTYPE_RRBASE
+ && type == (want_certtype - DNS_CERTTYPE_RRBASE)
+ && r_key)
+ {
+ *r_key = xtrymalloc (dlen);
+ if (!*r_key)
+ err = gpg_err_make (default_errsource,
+ gpg_err_code_from_syserror ());
+ else
+ {
+ memcpy (*r_key, pt, dlen);
+ *r_keylen = dlen;
+ err = 0;
+ }
+ goto leave;
+ }
+ else if (want_certtype >= DNS_CERTTYPE_RRBASE)
+ {
+ /* We did not found the requested RR. */
+ pt += dlen;
+ }
+ else if (type == T_CERT)
{
/* We got a CERT type. */
ctype = buf16_to_u16 (pt);
diff --git a/dirmngr/dns-cert.h b/dirmngr/dns-cert.h
index 5a579ec1f..9dbc58c23 100644
--- a/dirmngr/dns-cert.h
+++ b/dirmngr/dns-cert.h
@@ -43,7 +43,9 @@
#define DNS_CERTTYPE_IACPKIX 8 /* The URL of an Attribute Certificate. */
#define DNS_CERTTYPE_URI 253 /* URI private. */
#define DNS_CERTTYPE_OID 254 /* OID private. */
-
+/* Hacks for our implementation. */
+#define DNS_CERTTYPE_RRBASE 1024 /* Base of special constants. */
+#define DNS_CERTTYPE_RR61 (DNS_CERTTYPE_RRBASE + 61)
gpg_error_t get_dns_cert (const char *name, int want_certtype,
void **r_key, size_t *r_keylen,