[svn] GnuPG - r5213 - in trunk: . common doc tools
svn author wk
cvs at cvs.gnupg.org
Mon Dec 7 16:52:28 CET 2009
Author: wk
Date: 2009-12-07 16:52:27 +0100 (Mon, 07 Dec 2009)
New Revision: 5213
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/common/ChangeLog
trunk/common/pka.c
trunk/common/srv.c
trunk/configure.ac
trunk/doc/DETAILS
trunk/tools/ChangeLog
trunk/tools/no-libgcrypt.c
Log:
Use ADNS for PKA and SRV records if no other resolver is available.
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/ChangeLog 2009-12-07 15:52:27 UTC (rev 5213)
@@ -1,3 +1,8 @@
+2009-12-07 Werner Koch <wk at g10code.com>
+
+ * configure.ac: Check for ADNS before checking for the BIND
+ resolver.
+
2009-10-20 Marcus Brinkmann <marcus at g10code.com>
* configure.ac: Check for fusermount and encfs.
Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/common/ChangeLog 2009-12-07 15:52:27 UTC (rev 5213)
@@ -1,3 +1,10 @@
+2009-12-07 Werner Koch <wk at g10code.com>
+
+ * pka.c (get_pka_info): Add support for ADNS.
+ * src.v (getsrv): Add support for ADNS.
+
+ * srv.c (getsrv): s/xrealloc/xtryrealloc/.
+
2009-12-04 Werner Koch <wk at g10code.com>
* Makefile.am (audit-events.h, status-codes.h): Create files in
Modified: trunk/tools/ChangeLog
===================================================================
--- trunk/tools/ChangeLog 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/tools/ChangeLog 2009-12-07 15:52:27 UTC (rev 5213)
@@ -1,3 +1,7 @@
+2009-12-07 Werner Koch <wk at g10code.com>
+
+ * no-libgcrypt.c (gcry_strdup): Actually copy the string.
+
2009-11-23 Werner Koch <wk at g10code.com>
* gpgconf-comp.c (gc_options_gpg): Add default_pubkey_algo.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/NEWS 2009-12-07 15:52:27 UTC (rev 5213)
@@ -14,7 +14,9 @@
* Numerical values may now be used as an alternative to the
debug-level keywords.
+ * Support SRV and PKA records on W32.
+
Noteworthy changes in version 2.0.13 (2009-09-04)
-------------------------------------------------
Modified: trunk/common/pka.c
===================================================================
--- trunk/common/pka.c 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/common/pka.c 2009-12-07 15:52:27 UTC (rev 5213)
@@ -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 @@
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 @@
}
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 @@
/*
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:
*/
Modified: trunk/common/srv.c
===================================================================
--- trunk/common/srv.c 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/common/srv.c 2009-12-07 15:52:27 UTC (rev 5213)
@@ -30,6 +30,12 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#ifdef USE_ADNS
+# include <adns.h>
+# ifndef HAVE_ADNS_FREE
+# define adns_free free
+# endif
+#endif
#include "util.h"
#include "srv.h"
@@ -52,172 +58,232 @@
return 0;
}
+
int
-getsrv(const char *name,struct srventry **list)
+getsrv (const char *name,struct srventry **list)
{
- unsigned char answer[2048];
- int r,srvcount=0;
- unsigned char *pt,*emsg;
- u16 count,dlen;
- HEADER *header=(HEADER *)answer;
+ int srvcount=0;
+ u16 count;
+ int i, rc;
- *list=NULL;
+ *list = NULL;
- r=res_query(name,C_IN,T_SRV,answer,2048);
- if(r<sizeof(HEADER) || r>2048)
- return -1;
+#ifdef USE_ADNS
+ {
+ adns_state state;
+ adns_answer *answer = NULL;
+
+ rc = adns_init (&state, adns_if_noerrprint, NULL);
+ if (rc)
+ {
+ log_error ("error initializing adns: %s\n", strerror (errno));
+ return -1;
+ }
- if(header->rcode==NOERROR && (count=ntohs(header->ancount)))
- {
- int i,rc;
+ rc = adns_synchronous (state, name, adns_r_srv, adns_qf_quoteok_query,
+ &answer);
+ if (rc)
+ {
+ log_error ("DNS query failed: %s\n", strerror (errno));
+ adns_finish (state);
+ return -1;
+ }
+ if (answer->status != adns_s_ok
+ || answer->type != adns_r_srv || !answer->nrrs)
+ {
+ log_error ("DNS query returned an error or no records: %s (%s)\n",
+ adns_strerror (answer->status),
+ adns_errabbrev (answer->status));
+ adns_free (answer);
+ adns_finish (state);
+ return 0;
+ }
- emsg=&answer[r];
- pt=&answer[sizeof(HEADER)];
+ for (count = 0; count < answer->nrrs; count++)
+ {
+ struct srventry *srv = NULL;
+ struct srventry *newlist;
- /* Skip over the query */
+ if (strlen (answer->rrs.srvha[count].ha.host) >= MAXDNAME)
+ {
+ log_info ("hostname in SRV record too long - skipped\n");
+ continue;
+ }
+
+ newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
+ if (!newlist)
+ goto fail;
+ *list = newlist;
+ memset (&(*list)[srvcount], 0, sizeof(struct srventry));
+ srv = &(*list)[srvcount];
+ srvcount++;
+
+ srv->priority = answer->rrs.srvha[count].priority;
+ srv->weight = answer->rrs.srvha[count].weight;
+ srv->port = answer->rrs.srvha[count].port;
+ strcpy (srv->target, answer->rrs.srvha[count].ha.host);
+ }
- rc=dn_skipname(pt,emsg);
- if(rc==-1)
- goto fail;
+ adns_free (answer);
+ adns_finish (state);
+ }
+#else /*!USE_ADNS*/
+ {
+ unsigned char answer[2048];
+ HEADER *header = (HEADER *)answer;
+ unsigned char *pt, *emsg;
+ int r;
+ u16 dlen;
+
+ r = res_query (name, C_IN, T_SRV, answer, sizeof answer);
+ if (r < sizeof (HEADER) || r > sizeof answer)
+ return -1;
+ if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
+ return 0; /* Error or no record found. */
+
+ emsg = &answer[r];
+ pt = &answer[sizeof(HEADER)];
+
+ /* Skip over the query */
+ rc = dn_skipname (pt, emsg);
+ if (rc == -1)
+ goto fail;
+
+ pt += rc + QFIXEDSZ;
+
+ while (count-- > 0 && pt < emsg)
+ {
+ struct srventry *srv=NULL;
+ u16 type,class;
+ struct srventry *newlist;
+
+ newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
+ if (!newlist)
+ goto fail;
+ *list = newlist;
+ memset(&(*list)[srvcount],0,sizeof(struct srventry));
+ srv=&(*list)[srvcount];
+ srvcount++;
+
+ rc = dn_skipname(pt,emsg); /* the name we just queried for */
+ if (rc == -1)
+ goto fail;
+ pt+=rc;
+
+ /* Truncated message? */
+ if((emsg-pt)<16)
+ goto fail;
+
+ type=*pt++ << 8;
+ type|=*pt++;
+ /* We asked for SRV and got something else !? */
+ if(type!=T_SRV)
+ goto fail;
+
+ class=*pt++ << 8;
+ class|=*pt++;
+ /* We asked for IN and got something else !? */
+ if(class!=C_IN)
+ goto fail;
+
+ pt+=4; /* ttl */
+ dlen=*pt++ << 8;
+ dlen|=*pt++;
+ srv->priority=*pt++ << 8;
+ srv->priority|=*pt++;
+ srv->weight=*pt++ << 8;
+ srv->weight|=*pt++;
+ srv->port=*pt++ << 8;
+ srv->port|=*pt++;
+
+ /* Get the name. 2782 doesn't allow name compression, but
+ dn_expand still works to pull the name out of the
+ packet. */
+ rc = dn_expand(answer,emsg,pt,srv->target,MAXDNAME);
+ if (rc == 1 && srv->target[0] == 0) /* "." */
+ {
+ xfree(*list);
+ *list = NULL;
+ return 0;
+ }
+ if (rc == -1)
+ goto fail;
+ pt += rc;
+ /* Corrupt packet? */
+ if (dlen != rc+6)
+ goto fail;
+ }
+ }
+#endif /*!USE_ADNS*/
+
+ /* Now we have an array of all the srv records. */
+
+ /* Order by priority */
+ qsort(*list,srvcount,sizeof(struct srventry),priosort);
+
+ /* For each priority, move the zero-weighted items first. */
+ for (i=0; i < srvcount; i++)
+ {
+ int j;
+
+ for (j=i;j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
+ {
+ if((*list)[j].weight==0)
+ {
+ /* Swap j with i */
+ if(j!=i)
+ {
+ struct srventry temp;
+
+ memcpy (&temp,&(*list)[j],sizeof(struct srventry));
+ memcpy (&(*list)[j],&(*list)[i],sizeof(struct srventry));
+ memcpy (&(*list)[i],&temp,sizeof(struct srventry));
+ }
+
+ break;
+ }
+ }
+ }
- pt+=rc+QFIXEDSZ;
+ /* Run the RFC-2782 weighting algorithm. We don't need very high
+ quality randomness for this, so regular libc srand/rand is
+ sufficient. Fixme: It is a bit questionaly to reinitalize srand
+ - better use a gnupg fucntion for this. */
+ srand(time(NULL)*getpid());
- while(count-->0 && pt<emsg)
- {
- struct srventry *srv=NULL;
- u16 type,class;
-
- *list=xrealloc(*list,(srvcount+1)*sizeof(struct srventry));
- memset(&(*list)[srvcount],0,sizeof(struct srventry));
- srv=&(*list)[srvcount];
- srvcount++;
-
- rc=dn_skipname(pt,emsg); /* the name we just queried for */
- if(rc==-1)
- goto fail;
- pt+=rc;
-
- /* Truncated message? */
- if((emsg-pt)<16)
- goto fail;
-
- type=*pt++ << 8;
- type|=*pt++;
- /* We asked for SRV and got something else !? */
- if(type!=T_SRV)
- goto fail;
-
- class=*pt++ << 8;
- class|=*pt++;
- /* We asked for IN and got something else !? */
- if(class!=C_IN)
- goto fail;
-
- pt+=4; /* ttl */
- dlen=*pt++ << 8;
- dlen|=*pt++;
- srv->priority=*pt++ << 8;
- srv->priority|=*pt++;
- srv->weight=*pt++ << 8;
- srv->weight|=*pt++;
- srv->port=*pt++ << 8;
- srv->port|=*pt++;
-
- /* Get the name. 2782 doesn't allow name compression, but
- dn_expand still works to pull the name out of the
- packet. */
- rc=dn_expand(answer,emsg,pt,srv->target,MAXDNAME);
- if(rc==1 && srv->target[0]==0) /* "." */
- goto noanswer;
- if(rc==-1)
- goto fail;
- pt+=rc;
- /* Corrupt packet? */
- if(dlen!=rc+6)
- goto fail;
-
-#if 0
- printf("count=%d\n",srvcount);
- printf("priority=%d\n",srv->priority);
- printf("weight=%d\n",srv->weight);
- printf("port=%d\n",srv->port);
- printf("target=%s\n",srv->target);
-#endif
- }
-
- /* Now we have an array of all the srv records. */
-
- /* Order by priority */
- qsort(*list,srvcount,sizeof(struct srventry),priosort);
-
- /* For each priority, move the zero-weighted items first. */
- for(i=0;i<srvcount;i++)
- {
- int j;
-
- for(j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
- {
- if((*list)[j].weight==0)
- {
- /* Swap j with i */
- if(j!=i)
- {
- struct srventry temp;
-
- memcpy(&temp,&(*list)[j],sizeof(struct srventry));
- memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
- memcpy(&(*list)[i],&temp,sizeof(struct srventry));
- }
-
- break;
- }
- }
- }
-
- /* Run the RFC-2782 weighting algorithm. We don't need very
- high quality randomness for this, so regular libc srand/rand
- is sufficient. */
- srand(time(NULL)*getpid());
-
- for(i=0;i<srvcount;i++)
- {
- int j;
- float prio_count=0,chose;
-
- for(j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
- {
- prio_count+=(*list)[j].weight;
- (*list)[j].run_count=prio_count;
- }
-
- chose=prio_count*rand()/RAND_MAX;
-
- for(j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
- {
- if(chose<=(*list)[j].run_count)
- {
- /* Swap j with i */
- if(j!=i)
- {
- struct srventry temp;
-
- memcpy(&temp,&(*list)[j],sizeof(struct srventry));
- memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
- memcpy(&(*list)[i],&temp,sizeof(struct srventry));
- }
- break;
- }
- }
- }
+ for (i=0; i < srvcount; i++)
+ {
+ int j;
+ float prio_count=0,chose;
+
+ for (j=i; j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
+ {
+ prio_count+=(*list)[j].weight;
+ (*list)[j].run_count=prio_count;
+ }
+
+ chose=prio_count*rand()/RAND_MAX;
+
+ for (j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
+ {
+ if (chose<=(*list)[j].run_count)
+ {
+ /* Swap j with i */
+ if(j!=i)
+ {
+ struct srventry temp;
+
+ memcpy(&temp,&(*list)[j],sizeof(struct srventry));
+ memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
+ memcpy(&(*list)[i],&temp,sizeof(struct srventry));
+ }
+ break;
+ }
+ }
}
return srvcount;
- noanswer:
- xfree(*list);
- *list=NULL;
- return 0;
-
fail:
xfree(*list);
*list=NULL;
@@ -250,6 +316,6 @@
/*
Local Variables:
-compile-command: "cc -DTEST -I.. -I../include -Wall -g -o srv srv.c -lresolv libutil.a"
+compile-command: "cc -DTEST -I.. -I../include -Wall -g -o srv srv.c -lresolv ../tools/no-libgcrypt.o ../jnlib/libjnlib.a"
End:
*/
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/configure.ac 2009-12-07 15:52:27 UTC (rev 5213)
@@ -710,7 +710,36 @@
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt,
[NETLIBS="-lsocket $NETLIBS"]))
+
#
+# Check for ADNS.
+#
+_cppflags="${CPPFLAGS}"
+_ldflags="${LDFLAGS}"
+AC_ARG_WITH(adns,
+ AC_HELP_STRING([--with-adns=DIR],
+ [look for the adns library in DIR]),
+ [if test -d "$withval"; then
+ CPPFLAGS="${CPPFLAGS} -I$withval/include"
+ LDFLAGS="${LDFLAGS} -L$withval/lib"
+ fi])
+if test "$with_adns" != "no"; then
+ AC_CHECK_HEADERS(adns.h,
+ AC_CHECK_LIB(adns, adns_init,
+ [have_adns=yes],
+ [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}]),
+ [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}])
+fi
+if test "$have_adns" = "yes"; then
+ ADNSLIBS="-ladns"
+fi
+AC_SUBST(ADNSLIBS)
+# Newer adns versions feature a free function to be used under W32.
+AC_CHECK_FUNCS(adns_free)
+
+
+
+#
# Now try for the resolver functions so we can use DNS for SRV, PA and CERT.
#
if test x"$try_hkp" = xyes || test x"$try_http" = xyes ; then
@@ -747,7 +776,8 @@
# Make sure that the BIND 4 resolver interface is workable before
# enabling any code that calls it. At some point I'll rewrite the
# code to use the BIND 8 resolver API.
- # We might also want to use adns instead.
+ # We might also want to use adns instead. Problem with ADNS is that
+ # it does not support v6.
AC_MSG_CHECKING([whether the resolver is usable])
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <sys/types.h>
@@ -802,6 +832,20 @@
use_dns_srv=no
use_dns_pka=no
use_dns_cert=no
+ # If we have no resolver library but ADNS (e.g. under W32) enable the
+ # code parts which can be used with ADNS.
+ if test x"$have_adns" = xyes ; then
+ DNSLIB="$ADNSLIBS"
+ AC_DEFINE(USE_ADNS,1,[Use ADNS as resolver library.])
+
+ if test x"$use_dns_srv" = xyes ; then
+ AC_DEFINE(USE_DNS_SRV,1)
+ fi
+
+ if test x"$use_dns_pka" = xyes ; then
+ AC_DEFINE(USE_DNS_PKA,1)
+ fi
+ fi
fi
LIBS=$_dns_save_libs
@@ -813,33 +857,6 @@
#
-# Check for ADNS.
-#
-_cppflags="${CPPFLAGS}"
-_ldflags="${LDFLAGS}"
-AC_ARG_WITH(adns,
- AC_HELP_STRING([--with-adns=DIR],
- [look for the adns library in DIR]),
- [if test -d "$withval"; then
- CPPFLAGS="${CPPFLAGS} -I$withval/include"
- LDFLAGS="${LDFLAGS} -L$withval/lib"
- fi])
-if test "$with_adns" != "no"; then
- AC_CHECK_HEADERS(adns.h,
- AC_CHECK_LIB(adns, adns_init,
- [have_adns=yes],
- [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}]),
- [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}])
-fi
-if test "$have_adns" = "yes"; then
- ADNSLIBS="-ladns"
-fi
-AC_SUBST(ADNSLIBS)
-# Newer adns versions feature a free function to be used under W32.
-AC_CHECK_FUNCS(adns_free)
-
-
-#
# Check for LDAP
#
if test "$try_ldap" = yes ; then
Modified: trunk/doc/DETAILS
===================================================================
--- trunk/doc/DETAILS 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/doc/DETAILS 2009-12-07 15:52:27 UTC (rev 5213)
@@ -843,7 +843,7 @@
given but "default" is used the usage will be "sign".
Subkey-Type: <algo-number>|<algo-string>
This generates a secondary key. Currently only one subkey
- can be handled.
+ can be handled. "default" is also supported.
Subkey-Length: <length-in-bits>
Length of the subkey in bits. The default is returned by running
the command "gpg --gpgconf-list".
Modified: trunk/tools/no-libgcrypt.c
===================================================================
--- trunk/tools/no-libgcrypt.c 2009-12-04 19:58:28 UTC (rev 5212)
+++ trunk/tools/no-libgcrypt.c 2009-12-07 15:52:27 UTC (rev 5213)
@@ -55,7 +55,10 @@
char *
gcry_strdup (const char *string)
{
- return malloc (strlen (string)+1);
+ char *p = malloc (strlen (string)+1);
+ if (p)
+ strcpy (p, string);
+ return p;
}
More information about the Gnupg-commits
mailing list