diff --git a/g10/ChangeLog b/g10/ChangeLog index dec5a9187..031b5551c 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2009-07-23 David Shaw + + * 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 * trustdb.c (how_to_fix_the_trustdb): New. diff --git a/g10/keyserver.c b/g10/keyserver.c index 5d808f35a..b3945bb04 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -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;ihost=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);