* keyserver.c (keyserver_import_ldap): Try a DNS-SD lookup to find a
authorDavid Shaw <dshaw@jabberwocky.com>
Thu, 23 Jul 2009 19:50:25 +0000 (19:50 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Thu, 23 Jul 2009 19:50:25 +0000 (19:50 +0000)
domain-specific LDAP server before resorting to keys.{domain}.

g10/ChangeLog
g10/keyserver.c

index dec5a91..031b555 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-23  David Shaw  <dshaw@jabberwocky.com>
+
+       * keyserver.c (keyserver_import_ldap): Try a DNS-SD lookup to find
+       a domain-specific LDAP server before resorting to keys.{domain}.
+
 2009-07-23  Werner Koch  <wk@g10code.com>
 
        * trustdb.c (how_to_fix_the_trustdb): New.
index 5d808f3..b3945bb 100644 (file)
@@ -38,6 +38,9 @@
 #include "trustdb.h"
 #include "keyserver-internal.h"
 #include "util.h"
+#ifdef USE_DNS_SRV
+#include "srv.h"
+#endif
 
 #ifdef HAVE_W32_SYSTEM
 /* It seems Vista doesn't grok X_OK and so fails access() tests.
@@ -2093,17 +2096,19 @@ keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
   return rc;
 }
 
-/* Use the PGP Universal trick of asking ldap://keys.(maildomain) for
-   the key. */
+/* Import a key by name using LDAP */
 int
 keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len)
 {
   char *domain;
   struct keyserver_spec *keyserver;
   STRLIST list=NULL;
-  int rc;
-
-  append_to_strlist(&list,name);
+  int rc,hostlen=1;
+#ifdef USE_DNS_SRV
+  struct srventry *srvlist=NULL;
+  int srvcount,i;
+  char srvname[MAXDNAME];
+#endif
 
   /* Parse out the domain */
   domain=strrchr(name,'@');
@@ -2113,16 +2118,48 @@ keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len)
   domain++;
 
   keyserver=xmalloc_clear(sizeof(struct keyserver_spec));
-
   keyserver->scheme=xstrdup("ldap");
-  keyserver->host=xmalloc(5+strlen(domain)+1);
-  strcpy(keyserver->host,"keys.");
+  keyserver->host=xmalloc(1);
+  keyserver->host[0]='\0';
+
+#ifdef USE_DNS_SRV
+  snprintf(srvname,MAXDNAME,"_pgpkey-ldap._tcp.%s",domain);
+
+  srvcount=getsrv(srvname,&srvlist);
+
+  for(i=0;i<srvcount;i++)
+    {
+      hostlen+=strlen(srvlist[i].target)+1;
+      keyserver->host=xrealloc(keyserver->host,hostlen);
+
+      strcat(keyserver->host,srvlist[i].target);
+
+      if(srvlist[i].port!=389)
+       {
+         char port[7];
+
+         hostlen+=6; /* a colon, plus 5 digits (unsigned 16-bit value) */
+         keyserver->host=xrealloc(keyserver->host,hostlen);
+
+         snprintf(port,7,":%u",srvlist[i].port);
+         strcat(keyserver->host,port);
+       }
+       
+      strcat(keyserver->host," ");
+    }
+
+  free(srvlist);
+#endif
+
+  /* If all else fails, do the PGP Universal trick of
+     ldap://keys.(domain) */
+
+  hostlen+=5+strlen(domain);
+  keyserver->host=xrealloc(keyserver->host,hostlen);
+  strcat(keyserver->host,"keys.");
   strcat(keyserver->host,domain);
-  keyserver->uri=xmalloc(strlen(keyserver->scheme)+
-                        3+strlen(keyserver->host)+1);
-  strcpy(keyserver->uri,keyserver->scheme);
-  strcat(keyserver->uri,"://");
-  strcat(keyserver->uri,keyserver->host);
+
+  append_to_strlist(&list,name);
     
   rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver);