summaryrefslogtreecommitdiffstats
path: root/common/pka.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2009-12-07 16:52:27 +0100
committerWerner Koch <wk@gnupg.org>2009-12-07 16:52:27 +0100
commit85d778b9f6fc37f1fae9c2d0dca6c3d51517dd21 (patch)
tree46ac431df3a7970a33bee257b79ea00d35bee2a0 /common/pka.c
parentallow for default algorithms in a gpg parameter file (diff)
downloadgnupg2-85d778b9f6fc37f1fae9c2d0dca6c3d51517dd21.tar.xz
gnupg2-85d778b9f6fc37f1fae9c2d0dca6c3d51517dd21.zip
Use ADNS for PKA and SRV records if no other resolver is available.
Diffstat (limited to 'common/pka.c')
-rw-r--r--common/pka.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/common/pka.c b/common/pka.c
index 79a0bc3f5..e78f54367 100644
--- a/common/pka.c
+++ b/common/pka.c
@@ -33,6 +33,12 @@
#include <resolv.h>
#endif
#endif /* USE_DNS_PKA */
+#ifdef USE_ADNS
+# include <adns.h>
+# ifndef HAVE_ADNS_FREE
+# define adns_free free
+# endif
+#endif
#include "util.h"
#include "pka.h"
@@ -106,6 +112,67 @@ parse_txt_record (char *buffer, unsigned char *fpr)
char *
get_pka_info (const char *address, unsigned char *fpr)
{
+#ifdef USE_ADNS
+ int rc;
+ adns_state state;
+ const char *domain;
+ char *name;
+ adns_answer *answer = NULL;
+ char *buffer = NULL;
+
+ domain = strrchr (address, '@');
+ if (!domain || domain == address || !domain[1])
+ return NULL; /* Invalid mail address given. */
+ name = xtrymalloc (strlen (address) + 5 + 1);
+ if (!name)
+ return NULL;
+ memcpy (name, address, domain - address);
+ strcpy (stpcpy (name + (domain-address), "._pka."), domain+1);
+
+ rc = adns_init (&state, adns_if_noerrprint, NULL);
+ if (rc)
+ {
+ log_error ("error initializing adns: %s\n", strerror (errno));
+ xfree (name);
+ return NULL;
+ }
+
+ rc = adns_synchronous (state, name, adns_r_txt, adns_qf_quoteok_query,
+ &answer);
+ xfree (name);
+ if (rc)
+ {
+ log_error ("DNS query failed: %s\n", strerror (errno));
+ adns_finish (state);
+ return NULL;
+ }
+ if (answer->status != adns_s_ok
+ || answer->type != adns_r_txt || !answer->nrrs)
+ {
+ log_error ("DNS query returned an error: %s (%s)\n",
+ adns_strerror (answer->status),
+ adns_errabbrev (answer->status));
+ adns_free (answer);
+ adns_finish (state);
+ return NULL;
+ }
+
+ /* We use a PKA records iff there is exactly one record. */
+ if (answer->nrrs == 1 && answer->rrs.manyistr[0]->i != -1)
+ {
+ buffer = xtrystrdup (answer->rrs.manyistr[0]->str);
+ if (parse_txt_record (buffer, fpr))
+ {
+ xfree (buffer);
+ buffer = NULL; /* Not a valid gpg trustdns RR. */
+ }
+ }
+
+ adns_free (answer);
+ adns_finish (state);
+ return buffer;
+
+#else /*!USE_ADNS*/
unsigned char answer[PACKETSZ];
int anslen;
int qdcount, ancount, nscount, arcount;
@@ -197,7 +264,9 @@ get_pka_info (const char *address, unsigned char *fpr)
}
return NULL;
+#endif /*!USE_ADNS*/
}
+
#else /* !USE_DNS_PKA */
/* Dummy version of the function if we can't use the resolver
@@ -247,6 +316,6 @@ main(int argc,char *argv[])
/*
Local Variables:
-compile-command: "cc -DUSE_DNS_PKA -DTEST -I.. -I../include -Wall -g -o pka pka.c -lresolv libutil.a"
+compile-command: "cc -DUSE_DNS_PKA -DTEST -I.. -I../include -Wall -g -o pka pka.c -lresolv ../tools/no-libgcrypt.o ../jnlib/libjnlib.a"
End:
*/