[git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-36-g5c557a5

by David Shaw cvs at cvs.gnupg.org
Wed Dec 19 19:58:41 CET 2012


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, STABLE-BRANCH-1-4 has been updated
       via  5c557a51cdf37d9f50b3d5d7e11d17e6ea6bb2b8 (commit)
       via  6c3a76cca064070d0a9e636fedc824415e710451 (commit)
      from  3d56d486e1cfd7c32930a92afd6d0c558a90b77e (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 5c557a51cdf37d9f50b3d5d7e11d17e6ea6bb2b8
Author: David Shaw <dshaw at jabberwocky.com>
Date:   Wed Dec 19 13:54:27 2012 -0500

    Issue 1447: Pass proper Host header and SNI when SRV is used with curl.
    
    * configure.ac: Check for inet_ntop.
    
    * m4/libcurl.m4: Provide a #define for the version of the curl
      library.
    
    * keyserver/gpgkeys_hkp.c (main, srv_replace): Call getaddrinfo() on
      each target.  Once we find one that resolves to an address (whether
      IPv4 or IPv6), pass it into libcurl via CURLOPT_RESOLVE using the
      SRV name as the "host".  Force the HTTP Host header to be the same.
    
    Backported from 6b1f71055ebab36989e2089cfde319d2ba40ada7
    
    * keyserver/gpgkeys_hkp.c (main): Only default try-dns-srv to on if we
      have SRV support in the first place.
    
    Backported from 732f3d1d4786239db5f31f82cc04ec79326cc13c

diff --git a/configure.ac b/configure.ac
index ef0bb6e..0955eee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1021,7 +1021,7 @@ AC_CHECK_FUNCS(strcasecmp strncasecmp ctermid times unsetenv getpwnam getpwuid)
 AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime)
 AC_CHECK_FUNCS(atexit raise getpagesize strftime nl_langinfo setlocale)
 AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat getaddrinfo)
-AC_CHECK_FUNCS(fcntl ftruncate)
+AC_CHECK_FUNCS(fcntl ftruncate inet_ntop)
 AC_REPLACE_FUNCS(mkdtemp timegm isascii memrchr strsep)
 
 AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include <signal.h>])
diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c
index 27d67c6..382bee5 100644
--- a/keyserver/gpgkeys_hkp.c
+++ b/keyserver/gpgkeys_hkp.c
@@ -36,15 +36,29 @@
 #include <errno.h>
 #include <unistd.h>
 #ifdef HAVE_GETOPT_H
-#include <getopt.h>
+# include <getopt.h>
 #endif
 #ifdef HAVE_LIBCURL
-#include <curl/curl.h>
+# include <curl/curl.h>
+/* This #define rigamarole is to enable a hack to fake DNS SRV using
+   libcurl.  It only works if we have getaddrinfo(), inet_ntop(), and
+   a modern enough version of libcurl (7.21.3) so we can use
+   CURLOPT_RESOLVE to feed the resolver from the outside to force
+   libcurl to pass the right SNI. */
+#if (defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP)	\
+     && LIBCURL_VERNUM >= 0x071503)
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <arpa/inet.h>
 #else
-#include "curl-shim.h"
+# undef USE_DNS_SRV
+#endif
+#else
+# include "curl-shim.h"
 #endif
 #ifdef USE_DNS_SRV
-#include "srv.h"
+# include "srv.h"
 #endif
 #include "compat.h"
 #include "keyserver.h"
@@ -62,7 +76,8 @@ static char *proto,*port;
 static size_t
 curl_mrindex_writer(const void *ptr,size_t size,size_t nmemb,void *stream)
 {
-  static int checked=0,swallow=0;
+  static int checked=0;
+  static int swallow=0;
 
   if(!checked)
     {
@@ -496,18 +511,29 @@ fail_all(struct keylist *keylist,int err)
       }
 }
 
-#ifdef HAVE_LIBCURL
+#if defined(HAVE_LIBCURL) && defined(USE_DNS_SRV)
 /* If there is a SRV record, take the highest ranked possibility.
-   This is a hack, as we don't proceed downwards. */
+   This is a hack, as we don't proceed downwards if we can't
+   connect(), but only if we can't getaddinfo().  All this should
+   ideally be replaced by actual SRV support in libcurl someday! */
+
+#define HOST_HEADER "Host:"
+
 static void
-srv_replace(const char *srvtag)
+srv_replace(const char *srvtag,
+	    struct curl_slist **headers, struct curl_slist **resolve)
 {
-#ifdef USE_DNS_SRV
   struct srventry *srvlist=NULL;
+  int srvcount, srvindex;
+  char *portstr;
 
   if(!srvtag)
     return;
 
+  portstr=malloc (MAX_PORT);
+  if(!portstr)
+    return;
+
   if(1+strlen(srvtag)+6+strlen(opt->host)+1<=MAXDNAME)
     {
       char srvname[MAXDNAME];
@@ -516,30 +542,78 @@ srv_replace(const char *srvtag)
       strcat(srvname,srvtag);
       strcat(srvname,"._tcp.");
       strcat(srvname,opt->host);
-      getsrv(srvname,&srvlist);
+      srvcount=getsrv(srvname,&srvlist);
     }
 
-  if(srvlist)
+  for(srvindex=0 ; srvindex<srvcount && portstr ; srvindex++)
     {
-      char *newname,*newport;
+      struct addrinfo hints, *res;
+
+      sprintf (portstr, "%hu", srvlist[srvindex].port);
+      memset (&hints, 0, sizeof (hints));
+      hints.ai_socktype = SOCK_STREAM;
 
-      newname=strdup(srvlist->target);
-      newport=xtrymalloc(MAX_PORT);
-      if(newname && newport)
+      if (getaddrinfo (srvlist[srvindex].target, portstr, &hints, &res) == 0)
 	{
-	  free(opt->host);
-	  free(opt->port);
-	  opt->host=newname;
-	  snprintf(newport,MAX_PORT,"%u",srvlist->port);
-	  opt->port=newport;
+	  /* Very safe */
+	  char ipaddr[INET_ADDRSTRLEN+INET6_ADDRSTRLEN];
+
+	  if((res->ai_family==AF_INET
+	      && inet_ntop (res->ai_family,
+			    &((struct sockaddr_in *)res->ai_addr)->sin_addr,
+			    ipaddr,sizeof(ipaddr)))
+	     || (res->ai_family==AF_INET6
+		 && inet_ntop (res->ai_family,
+			       &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
+			       ipaddr,sizeof(ipaddr))))
+	    {
+	      char *entry,*host;
+
+	      entry=malloc (strlen(opt->host)+1
+			    +strlen(portstr)+1+strlen(ipaddr)+1);
+
+	      host=malloc (strlen(HOST_HEADER)+1+strlen(opt->host)+1);
+
+	      if(entry && host)
+		{
+		  sprintf (entry, "%s:%s:%s", opt->host, portstr, ipaddr);
+		  sprintf (host, "%s %s", HOST_HEADER, opt->host);
+
+		  *resolve=curl_slist_append (*resolve,entry);
+		  *headers=curl_slist_append (*headers,host);
+
+		  if(*resolve && *headers)
+		    {
+		      if(curl_easy_setopt (curl,
+					   CURLOPT_RESOLVE,*resolve)==CURLE_OK)
+
+			{
+			  if(opt->debug)
+			    fprintf (console, "gpgkeys: Faking %s SRV from"
+				     " %s to %s:%u\n",
+				     srvtag, opt->host,
+				     srvlist[srvindex].target,
+				     srvlist[srvindex].port);
+
+			  free (opt->port);
+			  opt->port=portstr;
+			  portstr=NULL;
+			}
+		    }
+		}
+
+	      free (entry);
+	      free (host);
+	    }
+
+	  freeaddrinfo (res);
 	}
       else
-	{
-	  free(newname);
-	  free(newport);
-	}
+	continue; /* Not found */
     }
-#endif
+
+  free (srvlist);
+  free (portstr);
 }
 #endif
 
@@ -555,12 +629,20 @@ show_help (FILE *fp)
 int
 main(int argc,char *argv[])
 {
-  int arg,ret=KEYSERVER_INTERNAL_ERROR,try_srv=1;
+  int arg,ret=KEYSERVER_INTERNAL_ERROR;
   char line[MAX_LINE];
   int failed=0;
   struct keylist *keylist=NULL,*keyptr=NULL;
   char *proxy=NULL;
   struct curl_slist *headers=NULL;
+  struct curl_slist *resolve=NULL;
+
+  /* Only default this to on if we have SRV support */
+#ifdef USE_DNS_SRV
+  int try_srv = 1;
+#else
+  int try_srv = 0;
+#endif
 
   console=stderr;
 
@@ -723,6 +805,13 @@ main(int argc,char *argv[])
       goto fail;
     }
 
+  if(opt->debug)
+    {
+      fprintf(console,"gpgkeys: curl version = %s\n",curl_version());
+      curl_easy_setopt(curl,CURLOPT_STDERR,console);
+      curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);
+    }
+
   /* Only use SRV if the user does not provide a :port.  The semantics
      of a specified port and SRV do not play well together. */
   if(!opt->port && try_srv)
@@ -741,8 +830,12 @@ main(int argc,char *argv[])
 	 This isn't as good as true SRV support, as we do not try all
 	 possible targets at one particular level and work our way
 	 down the list, but it's better than nothing. */
-      srv_replace(srvtag);
+#ifdef USE_DNS_SRV
+      srv_replace(srvtag,&headers,&resolve);
 #else
+      fprintf(console,"gpgkeys: try-dns-srv was requested, but not SRV capable\n");
+#endif
+#else /* !HAVE_LIBCURL */
       /* We're using our internal curl shim, so we can use its (true)
 	 SRV support.  Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real
 	 libcurl option.  It's specific to our shim. */
@@ -760,13 +853,6 @@ main(int argc,char *argv[])
   if(opt->auth)
     curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth);
 
-  if(opt->debug)
-    {
-      fprintf(console,"gpgkeys: curl version = %s\n",curl_version());
-      curl_easy_setopt(curl,CURLOPT_STDERR,console);
-      curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);
-    }
-
   curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert);
   curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file);
 
@@ -968,6 +1054,7 @@ main(int argc,char *argv[])
   free_ks_options(opt);
 
   curl_slist_free_all(headers);
+  curl_slist_free_all(resolve);
 
   if(curl)
     curl_easy_cleanup(curl);
diff --git a/m4/libcurl.m4 b/m4/libcurl.m4
index c763146..ce02add 100644
--- a/m4/libcurl.m4
+++ b/m4/libcurl.m4
@@ -66,6 +66,11 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG],
 
      _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'"
 
+     # More recent versions of curl-config have a direct --vernum
+     # option, but we'd like this code to work with older versions as
+     # well, so just convert --version.
+     _libcurl_vernum_parse="eval $AWK '{printf \"0x%06X\",\$NF}'"
+
      _libcurl_try_link=yes
 
      if test -d "$_libcurl_with" ; then
@@ -206,6 +211,10 @@ x=CURLOPT_VERBOSE;
            AC_SUBST(LIBCURL_CPPFLAGS)
            AC_SUBST(LIBCURL)
 
+	   _libcurl_vernum=`echo $_libcurl_version | $_libcurl_vernum_parse`
+
+	   AC_DEFINE_UNQUOTED(LIBCURL_VERNUM,$_libcurl_vernum,[The version of the libcurl library in packed hex form])
+
            for _libcurl_feature in $_libcurl_features ; do
 	      AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1])
 	      eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes
@@ -246,6 +255,7 @@ x=CURLOPT_VERBOSE;
      unset _libcurl_protocol
      unset _libcurl_protocols
      unset _libcurl_version
+     unset _libcurl_vernum
      unset _libcurl_ldflags
   fi
 

commit 6c3a76cca064070d0a9e636fedc824415e710451
Author: David Shaw <dshaw at jabberwocky.com>
Date:   Wed Dec 19 11:43:28 2012 -0500

    Part of issue 1447: Pass proper Host header when SRV is used.
    
    * common/http.c (send_request, connect_server): Set proper Host header
      (no :port, host is that of the SRV) when SRV is used in the
      curl-shim.
    
    Backported from cbe98b2cb1e40ba253300e604996681ae191e363

diff --git a/util/http.c b/util/http.c
index e5db605..2f630ae 100644
--- a/util/http.c
+++ b/util/http.c
@@ -599,16 +599,18 @@ send_request( HTTP_HD hd, const char *auth, const char *proxy,
 	       authstr?authstr:"",proxy_authstr?proxy_authstr:"" );
     else
       {
-	char portstr[15];
+	char portstr[35];
 
-	if(port!=80)
+	if(port == 80 || (srv && srv->used_server))
+	  *portstr = 0;
+	else
 	  sprintf(portstr,":%u",port);
 
 	sprintf( request, "%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
 		 hd->req_type == HTTP_REQ_GET ? "GET" :
 		 hd->req_type == HTTP_REQ_HEAD? "HEAD":
 		 hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
-		 *p == '/'? "":"/", p, server, (port!=80)?portstr:"",
+		 *p == '/'? "":"/", p, server, portstr,
 		 authstr?authstr:"");
       }
 
@@ -822,6 +824,7 @@ connect_server( const char *server, ushort port, unsigned int flags,
   int connected = 0;
   int hostfound = 0;
   int chosen = -1;
+  int fakesrv = 0;
   struct srventry *srvlist = NULL;
   int srvindex;
 
@@ -885,7 +888,8 @@ connect_server( const char *server, ushort port, unsigned int flags,
       srvlist->port=port;
       strncpy(srvlist->target,server,MAXDNAME);
       srvlist->target[MAXDNAME-1]='\0';
-      srvcount=1;
+      srvcount = 1;
+      fakesrv = 1;
     }
 
 #ifdef HAVE_GETADDRINFO
@@ -986,7 +990,7 @@ connect_server( const char *server, ushort port, unsigned int flags,
     }
 #endif /* !HAVE_GETADDRINFO */
 
-  if(chosen > -1 && srv)
+  if(!fakesrv && chosen > -1 && srv)
     {
       srv->used_server = strdup (srvlist[chosen].target);
       srv->used_port = srvlist[chosen].port;

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

Summary of changes:
 configure.ac            |    2 +-
 keyserver/gpgkeys_hkp.c |  155 ++++++++++++++++++++++++++++++++++++----------
 m4/libcurl.m4           |   10 +++
 util/http.c             |   14 +++--
 4 files changed, 141 insertions(+), 40 deletions(-)


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




More information about the Gnupg-commits mailing list