[git] GnuPG - branch, master, updated. gnupg-2.1.9-57-g8b06d7f

by Werner Koch cvs at cvs.gnupg.org
Thu Oct 22 17:08:18 CEST 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  8b06d7f41aec6cb993445935dba7c60e033d026a (commit)
       via  e03a4a94bb67d4a6c958b37671f83456e203f325 (commit)
       via  41bb01ae792af78edd28bf1b735cacc0b3ac428a (commit)
      from  1e34007c972c1d7730cfcacd88f6bbebba7dec1d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 8b06d7f41aec6cb993445935dba7c60e033d026a
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Oct 22 10:14:10 2015 +0200

    dirmngr: Implement Tor mode for SRV RRs.
    
    * dirmngr/dns-stuff.c (get_dns_cert): Factor adns init out to...
    (my_adns_init): new.
    (getsrv)[USE_ADNS]: Use my_adns_init.
    (getsrv)[!USE_ADNS]: Return an error if Tor mode is active.
    
    * dirmngr/t-dns-stuff.c: Add option --use-tor.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
index 639388f..300d086 100644
--- a/dirmngr/dns-stuff.c
+++ b/dirmngr/dns-stuff.c
@@ -219,6 +219,29 @@ resolve_dns_name (const char *name, unsigned short port,
 }
 
 
+#ifdef USE_ADNS
+/* Init ADNS and store the new state at R_STATE.  Returns 0 on
+   success; prints an error message and returns an error code on
+   failure.  */
+static gpg_error_t
+my_adns_init (adns_state *r_state)
+{
+  gpg_error_t err;
+
+  if (tor_mode? adns_init_strcfg (r_state,
+                                  adns_if_noerrprint|adns_if_tormode,
+                                  NULL, "nameserver 8.8.8.8")
+      /*    */: adns_init (r_state, adns_if_noerrprint, NULL))
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      log_error ("error initializing adns: %s\n", gpg_strerror (err));
+      return err;
+    }
+  return 0;
+}
+#endif /*USE_ADNS*/
+
+
 /* Returns 0 on success or an error code.  If a PGP CERT record was
    found, the malloced data is returned at (R_KEY, R_KEYLEN) and
    the other return parameters are set to NULL/0.  If an IPGP CERT
@@ -250,14 +273,9 @@ get_dns_cert (const char *name, int want_certtype,
   *r_fprlen = 0;
   *r_url = NULL;
 
-  if (tor_mode? adns_init_strcfg (&state, adns_if_noerrprint|adns_if_tormode,
-                                  NULL, "nameserver 8.8.8.8")
-      /*    */: adns_init (&state, adns_if_noerrprint, NULL))
-    {
-      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
-      log_error ("error initializing adns: %s\n", strerror (errno));
-      return err;
-    }
+  err = my_adns_init (&state);
+  if (err)
+    return err;
 
   if (adns_synchronous (state, name,
                         (adns_r_unknown
@@ -620,12 +638,8 @@ getsrv (const char *name,struct srventry **list)
     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 (my_adns_init (&state))
+      return -1;
 
     rc = adns_synchronous (state, name, adns_r_srv, adns_qf_quoteok_query,
                            &answer);
@@ -682,6 +696,10 @@ getsrv (const char *name,struct srventry **list)
     int r;
     u16 dlen;
 
+    /* Do not allow a query using the standard resolver in Tor mode.  */
+    if (tor_mode)
+      return -1;
+
     r = res_query (name, C_IN, T_SRV, answer, sizeof answer);
     if (r < sizeof (HEADER) || r > sizeof answer)
       return -1;
diff --git a/dirmngr/t-dns-stuff.c b/dirmngr/t-dns-stuff.c
index d2ead8f..63d4cdd 100644
--- a/dirmngr/t-dns-stuff.c
+++ b/dirmngr/t-dns-stuff.c
@@ -42,6 +42,7 @@ main (int argc, char **argv)
   int last_argc = -1;
   gpg_error_t err;
   int any_options = 0;
+  int opt_tor = 0;
   int opt_cert = 0;
   int opt_srv = 0;
   char const *name = NULL;
@@ -64,6 +65,7 @@ main (int argc, char **argv)
                  "Options:\n"
                  "  --verbose         print timings etc.\n"
                  "  --debug           flyswatter\n"
+                 "  --use-tor         use Tor\n"
                  "  --cert            lookup a CERT RR\n"
                  "  --srv             lookup a SRV RR\n"
                  , stdout);
@@ -80,6 +82,11 @@ main (int argc, char **argv)
           debug++;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--use-tor"))
+        {
+          opt_tor = 1;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--cert"))
         {
           any_options = opt_cert = 1;
@@ -110,6 +117,17 @@ main (int argc, char **argv)
       exit (1);
     }
 
+  if (opt_tor)
+    {
+      err = enable_dns_tormode ();
+      if (err)
+        {
+          fprintf (stderr, "error switching into Tor mode: %s\n",
+                   gpg_strerror (err));
+          exit (1);
+        }
+    }
+
   if (opt_cert)
     {
       unsigned char *fpr;

commit e03a4a94bb67d4a6c958b37671f83456e203f325
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Oct 22 09:52:51 2015 +0200

    dirmngr: Do not use MAXDNAME.
    
    * dirmngr/dns-stuff.c (getsrv): Replace MAXDNAME.
    * dirmngr/dns-stuff.h (MAXDNAME): Remove.
    (struct srventry): Use a fixed value instead of MAXDNAME.
    * dirmngr/http.c (connect_server): Use DIMof instead of MAXDNAME.
    Malloc a helper array.
    
    --
    
    Depending on the order of included headers it might be that we allocate
    the array with a different size than what we test against in another
    module.  To make it more robust we use the actual known size of
    checking.
    
    A better would be to use a linked list and avoid these large arrays.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
index c500c34..639388f 100644
--- a/dirmngr/dns-stuff.c
+++ b/dirmngr/dns-stuff.c
@@ -651,7 +651,7 @@ getsrv (const char *name,struct srventry **list)
         struct srventry *srv = NULL;
         struct srventry *newlist;
 
-        if (strlen (answer->rrs.srvha[count].ha.host) >= MAXDNAME)
+        if (strlen (answer->rrs.srvha[count].ha.host) >= sizeof srv->target)
           {
             log_info ("hostname in SRV record too long - skipped\n");
             continue;
@@ -747,7 +747,7 @@ getsrv (const char *name,struct srventry **list)
         /* 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);
+        rc = dn_expand(answer,emsg,pt,srv->target, sizeof srv->target);
         if (rc == 1 && srv->target[0] == 0) /* "." */
           {
             xfree(*list);
diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
index 5ffa017..13c47df 100644
--- a/dirmngr/dns-stuff.h
+++ b/dirmngr/dns-stuff.h
@@ -71,18 +71,13 @@ struct dns_addrinfo_s
 };
 
 
-
-#ifndef MAXDNAME
-#define MAXDNAME 1025
-#endif
-
 struct srventry
 {
   unsigned short priority;
   unsigned short weight;
   unsigned short port;
   int run_count;
-  char target[MAXDNAME];
+  char target[1025];
 };
 
 
diff --git a/dirmngr/http.c b/dirmngr/http.c
index 4387b96..de5edc3 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -2251,13 +2251,23 @@ connect_server (const char *server, unsigned short port,
   if (srvtag)
     {
       /* We're using SRV, so append the tags. */
-      if (1+strlen (srvtag) + 6 + strlen (server) + 1 <= MAXDNAME)
+      if (1 + strlen (srvtag) + 6 + strlen (server) + 1
+          <= DIMof (struct srventry, target))
 	{
-	  char srvname[MAXDNAME];
+	  char *srvname = xtrymalloc (DIMof (struct srventry, target));
 
-	  stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag),
-                           "._tcp."), server);
-	  srvcount = getsrv (srvname, &serverlist);
+          if (!srvname) /* Out of core */
+            {
+              serverlist = NULL;
+              srvcount = 0;
+            }
+          else
+            {
+              stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag),
+                              "._tcp."), server);
+              srvcount = getsrv (srvname, &serverlist);
+              xfree (srvname);
+            }
 	}
     }
 #else
@@ -2273,8 +2283,8 @@ connect_server (const char *server, unsigned short port,
       if (!serverlist)
         return -1; /* Out of core.  */
       serverlist->port = port;
-      strncpy (serverlist->target, server, MAXDNAME);
-      serverlist->target[MAXDNAME-1] = '\0';
+      strncpy (serverlist->target, server, DIMof (struct srventry, target));
+      serverlist->target[DIMof (struct srventry, target)-1] = '\0';
       srvcount = 1;
     }
 

commit 41bb01ae792af78edd28bf1b735cacc0b3ac428a
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Oct 22 09:22:41 2015 +0200

    Move SRV RR code from common/ to dirmngr/.
    
    * common/srv.c: Merge into dirmngr/dns-stuff.c.  Delete file.
    * common/srv.h: Merge into dirmngr/dns-stuff.h.  Delete file.
    * common/Makefile.am (common_sources): Remove srv.c and srv.h.
    * g10/keyserver.c: Do not include srv.h.  The code using it is anyway
    disabled.
    * dirmngr/http.c: Remove header srv.h and stubs.
    * dirmngr/t-dns-stuff.c: Add option --srv.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/common/Makefile.am b/common/Makefile.am
index 2be51f1..6cbde0b 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -78,7 +78,6 @@ common_sources = \
 	exechelp.h \
 	signal.c \
 	audit.c audit.h \
-	srv.h \
 	localename.c \
 	session-env.c session-env.h \
 	userids.c userids.h \
@@ -110,15 +109,9 @@ without_npth_sources = \
 
 
 libcommon_a_SOURCES = $(common_sources) $(without_npth_sources)
-if USE_DNS_SRV
-libcommon_a_SOURCES += srv.c
-endif
 libcommon_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) -DWITHOUT_NPTH=1
 
 libcommonpth_a_SOURCES = $(common_sources)
-if USE_DNS_SRV
-libcommonpth_a_SOURCES += srv.c
-endif
 libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
 
 if !HAVE_W32CE_SYSTEM
diff --git a/common/srv.c b/common/srv.c
deleted file mode 100644
index 2107aa5..0000000
--- a/common/srv.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* srv.c - DNS SRV code
- * Copyright (C) 2003, 2009 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of either
- *
- *   - the GNU Lesser General Public License as published by the Free
- *     Software Foundation; either version 3 of the License, or (at
- *     your option) any later version.
- *
- * or
- *
- *   - the GNU General Public License as published by the Free
- *     Software Foundation; either version 2 of the License, or (at
- *     your option) any later version.
- *
- * or both in parallel, as here.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <sys/types.h>
-#ifdef _WIN32
-# ifdef HAVE_WINSOCK2_H
-#  include <winsock2.h>
-# endif
-# include <windows.h>
-#else
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-#endif
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#ifdef USE_ADNS
-# include <adns.h>
-#endif
-
-#include "util.h"
-#include "host2net.h"
-#include "srv.h"
-
-/* Not every installation has gotten around to supporting SRVs
-   yet... */
-#ifndef T_SRV
-#define T_SRV 33
-#endif
-
-static int
-priosort(const void *a,const void *b)
-{
-  const struct srventry *sa=a,*sb=b;
-  if(sa->priority>sb->priority)
-    return 1;
-  else if(sa->priority<sb->priority)
-    return -1;
-  else
-    return 0;
-}
-
-
-int
-getsrv (const char *name,struct srventry **list)
-{
-  int srvcount=0;
-  u16 count;
-  int i, rc;
-
-  *list = NULL;
-
-#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;
-      }
-
-    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;
-      }
-
-    for (count = 0; count < answer->nrrs; count++)
-      {
-        struct srventry *srv = NULL;
-        struct srventry *newlist;
-
-        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);
-      }
-
-    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 = buf16_to_u16 (pt);
-        pt += 2;
-        /* We asked for SRV and got something else !? */
-        if(type!=T_SRV)
-          goto fail;
-
-        class = buf16_to_u16 (pt);
-        pt += 2;
-        /* We asked for IN and got something else !? */
-        if(class!=C_IN)
-          goto fail;
-
-        pt += 4; /* ttl */
-        dlen = buf16_to_u16 (pt);
-        pt += 2;
-
-        srv->priority = buf16_to_ushort (pt);
-        pt += 2;
-        srv->weight = buf16_to_ushort (pt);
-        pt += 2;
-        srv->port = buf16_to_ushort (pt);
-        pt += 2;
-
-        /* 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;
-            }
-        }
-    }
-
-  /* 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());
-
-  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;
-
- fail:
-  xfree(*list);
-  *list=NULL;
-  return -1;
-}
-
-#ifdef TEST
-int
-main(int argc,char *argv[])
-{
-  struct srventry *srv;
-  int rc,i;
-
-  rc=getsrv("_hkp._tcp.wwwkeys.pgp.net",&srv);
-  printf("Count=%d\n\n",rc);
-  for(i=0;i<rc;i++)
-    {
-      printf("priority=%hu\n",srv[i].priority);
-      printf("weight=%hu\n",srv[i].weight);
-      printf("port=%hu\n",srv[i].port);
-      printf("target=%s\n",srv[i].target);
-      printf("\n");
-    }
-
-  xfree(srv);
-
-  return 0;
-}
-#endif /* TEST */
-
-/*
-Local Variables:
-compile-command: "cc -DTEST -I.. -I../include -Wall -g -o srv srv.c -lresolv  ../tools/no-libgcrypt.o  ../common/libcommon.a"
-End:
-*/
diff --git a/common/srv.h b/common/srv.h
deleted file mode 100644
index 016d2b1..0000000
--- a/common/srv.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* srv.h
- * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNUPG.
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of either
- *
- *   - the GNU Lesser General Public License as published by the Free
- *     Software Foundation; either version 3 of the License, or (at
- *     your option) any later version.
- *
- * or
- *
- *   - the GNU General Public License as published by the Free
- *     Software Foundation; either version 2 of the License, or (at
- *     your option) any later version.
- *
- * or both in parallel, as here.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GNUPG_COMMON_SRV_H
-#define GNUPG_COMMON_SRV_H
-
-#ifdef USE_DNS_SRV
-# ifdef _WIN32
-#  ifdef HAVE_WINSOCK2_H
-#   include <winsock2.h>
-#  endif
-#  include <windows.h>
-# else
-#  include <netinet/in.h>
-#  include <arpa/nameser.h>
-#  include <resolv.h>
-# endif /* !_WIN32 */
-#endif /* USE_DNS_SRV */
-
-
-#ifndef MAXDNAME
-#define MAXDNAME 1025
-#endif
-
-struct srventry
-{
-  unsigned short priority;
-  unsigned short weight;
-  unsigned short port;
-  int run_count;
-  char target[MAXDNAME];
-};
-
-int getsrv(const char *name,struct srventry **list);
-
-#endif /*GNUPG_COMMON_SRV_H*/
diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
index 3fa6054..c500c34 100644
--- a/dirmngr/dns-stuff.c
+++ b/dirmngr/dns-stuff.c
@@ -1,5 +1,5 @@
 /* dns-stuff.c - DNS related code including CERT RR (rfc-4398)
- * Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2005, 2006, 2009 Free Software Foundation, Inc.
  * Copyright (C) 2005, 2006, 2009, 2015 Werner Koch
  *
  * This file is part of GnuPG.
@@ -54,8 +54,11 @@
 #include "host2net.h"
 #include "dns-stuff.h"
 
-/* Not every installation has gotten around to supporting CERTs
-   yet... */
+/* Not every installation has gotten around to supporting SRVs or
+   CERTs yet... */
+#ifndef T_SRV
+#define T_SRV 33
+#endif
 #ifndef T_CERT
 # define T_CERT 37
 #endif
@@ -588,3 +591,250 @@ get_dns_cert (const char *name, int want_certtype,
   return gpg_err_make (default_errsource, GPG_ERR_NOT_SUPPORTED);
 #endif
 }
+
+#ifdef USE_DNS_SRV
+static int
+priosort(const void *a,const void *b)
+{
+  const struct srventry *sa=a,*sb=b;
+  if(sa->priority>sb->priority)
+    return 1;
+  else if(sa->priority<sb->priority)
+    return -1;
+  else
+    return 0;
+}
+
+
+int
+getsrv (const char *name,struct srventry **list)
+{
+  int srvcount=0;
+  u16 count;
+  int i, rc;
+
+  *list = NULL;
+
+#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;
+      }
+
+    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;
+      }
+
+    for (count = 0; count < answer->nrrs; count++)
+      {
+        struct srventry *srv = NULL;
+        struct srventry *newlist;
+
+        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);
+      }
+
+    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 = buf16_to_u16 (pt);
+        pt += 2;
+        /* We asked for SRV and got something else !? */
+        if(type!=T_SRV)
+          goto fail;
+
+        class = buf16_to_u16 (pt);
+        pt += 2;
+        /* We asked for IN and got something else !? */
+        if(class!=C_IN)
+          goto fail;
+
+        pt += 4; /* ttl */
+        dlen = buf16_to_u16 (pt);
+        pt += 2;
+
+        srv->priority = buf16_to_ushort (pt);
+        pt += 2;
+        srv->weight = buf16_to_ushort (pt);
+        pt += 2;
+        srv->port = buf16_to_ushort (pt);
+        pt += 2;
+
+        /* 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;
+            }
+        }
+    }
+
+  /* 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());
+
+  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;
+
+ fail:
+  xfree(*list);
+  *list=NULL;
+  return -1;
+}
+#endif /*USE_DNS_SRV*/
diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
index 090e79b..5ffa017 100644
--- a/dirmngr/dns-stuff.h
+++ b/dirmngr/dns-stuff.h
@@ -72,6 +72,20 @@ struct dns_addrinfo_s
 
 
 
+#ifndef MAXDNAME
+#define MAXDNAME 1025
+#endif
+
+struct srventry
+{
+  unsigned short priority;
+  unsigned short weight;
+  unsigned short port;
+  int run_count;
+  char target[MAXDNAME];
+};
+
+
 /* Calling this function switches the DNS code into Tor mode if
    possibe.  Return 0 on success.  */
 gpg_error_t enable_dns_tormode (void);
@@ -89,6 +103,7 @@ gpg_error_t get_dns_cert (const char *name, int want_certtype,
                           unsigned char **r_fpr, size_t *r_fprlen,
                           char **r_url);
 
+int getsrv (const char *name,struct srventry **list);
 
 
 #endif /*GNUPG_DIRMNGR_DNS_STUFF_H*/
diff --git a/dirmngr/http.c b/dirmngr/http.c
index 19d5f8f..4387b96 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -100,23 +100,6 @@
 #include "i18n.h"
 #include "dns-stuff.h"
 #include "http.h"
-#ifdef USE_DNS_SRV
-# include "srv.h"
-#else /*!USE_DNS_SRV*/
-  /* If we are not compiling with SRV record support we provide stub
-     data structures. */
-# ifndef MAXDNAME
-#  define MAXDNAME 1025
-# endif
-struct srventry
-{
-  unsigned short priority;
-  unsigned short weight;
-  unsigned short port;
-  int run_count;
-  char target[MAXDNAME];
-};
-#endif/*!USE_DNS_SRV*/
 
 
 #ifdef USE_NPTH
diff --git a/dirmngr/t-dns-stuff.c b/dirmngr/t-dns-stuff.c
index e8a74ea..d2ead8f 100644
--- a/dirmngr/t-dns-stuff.c
+++ b/dirmngr/t-dns-stuff.c
@@ -41,10 +41,13 @@ main (int argc, char **argv)
 {
   int last_argc = -1;
   gpg_error_t err;
+  int any_options = 0;
   int opt_cert = 0;
-  char const *name;
+  int opt_srv = 0;
+  char const *name = NULL;
 
   gpgrt_init ();
+  log_set_prefix (PGM, GPGRT_LOG_WITH_PREFIX);
   if (argc)
     { argc--; argv++; }
   while (argc && last_argc != argc )
@@ -62,6 +65,7 @@ main (int argc, char **argv)
                  "  --verbose         print timings etc.\n"
                  "  --debug           flyswatter\n"
                  "  --cert            lookup a CERT RR\n"
+                 "  --srv             lookup a SRV RR\n"
                  , stdout);
           exit (0);
         }
@@ -78,7 +82,12 @@ main (int argc, char **argv)
         }
       else if (!strcmp (*argv, "--cert"))
         {
-          opt_cert = 1;
+          any_options = opt_cert = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--srv"))
+        {
+          any_options = opt_srv = 1;
           argc--; argv++;
         }
       else if (!strncmp (*argv, "--", 2))
@@ -88,7 +97,7 @@ main (int argc, char **argv)
         }
     }
 
-  if (!argc)
+  if (!argc && !any_options)
     {
       opt_cert = 1;
       name = "simon.josefsson.org";
@@ -97,7 +106,7 @@ main (int argc, char **argv)
     name = *argv;
   else
     {
-      fprintf (stderr, PGM ": too many host names given\n");
+      fprintf (stderr, PGM ": none or too many host names given\n");
       exit (1);
     }
 
@@ -145,6 +154,24 @@ main (int argc, char **argv)
       xfree (fpr);
       xfree (url);
     }
+  else if (opt_srv)
+    {
+      struct srventry *srv;
+      int rc,i;
+
+      rc=getsrv("_hkp._tcp.wwwkeys.pgp.net",&srv);
+      printf("Count=%d\n\n",rc);
+      for(i=0;i<rc;i++)
+        {
+          printf("priority=%hu\n",srv[i].priority);
+          printf("weight=%hu\n",srv[i].weight);
+          printf("port=%hu\n",srv[i].port);
+          printf("target=%s\n",srv[i].target);
+          printf("\n");
+        }
+
+      xfree(srv);
+    }
   else /* Standard lookup.  */
     {
       char *cname;
diff --git a/g10/keyserver.c b/g10/keyserver.c
index a6257e5..37e62fd 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -41,9 +41,6 @@
 #include "trustdb.h"
 #include "keyserver-internal.h"
 #include "util.h"
-#ifdef USE_DNS_SRV
-#include "srv.h"
-#endif
 #include "membuf.h"
 #include "call-dirmngr.h"
 
@@ -2029,6 +2026,7 @@ keyserver_import_ldap (ctrl_t ctrl,
 #ifdef USE_DNS_SRV
   snprintf(srvname,MAXDNAME,"_pgpkey-ldap._tcp.%s",domain);
 
+  FIXME("network related - move to dirmngr or drop the code");
   srvcount=getsrv(srvname,&srvlist);
 
   for(i=0;i<srvcount;i++)

-----------------------------------------------------------------------

Summary of changes:
 common/Makefile.am    |   7 --
 common/srv.c          | 333 --------------------------------------------------
 common/srv.h          |  62 ----------
 dirmngr/dns-stuff.c   | 290 +++++++++++++++++++++++++++++++++++++++++--
 dirmngr/dns-stuff.h   |  10 ++
 dirmngr/http.c        |  41 +++----
 dirmngr/t-dns-stuff.c |  53 +++++++-
 g10/keyserver.c       |   4 +-
 8 files changed, 356 insertions(+), 444 deletions(-)
 delete mode 100644 common/srv.c
 delete mode 100644 common/srv.h


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list