diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog index c9e2997bb..9a4784398 100644 --- a/keyserver/ChangeLog +++ b/keyserver/ChangeLog @@ -1,5 +1,13 @@ 2004-02-19 David Shaw + * Makefile.am: Add automake conditionals to symlink gpgkeys_ldaps + to gpgkeys_ldap when needed. + + * gpgkeys_ldap.c (main): Add support for LDAPS and TLS + connections. These are only useful and usable when talking to + real LDAP keyservers. Add new "tls" option to tune TLS use from + off, to try quietly, to try loudly, or to require TLS. + * gpgkeys_ldap.c (find_basekeyspacedn): New function to figure out what kind of LDAP server we're talking to (either real LDAP or the LDAP keyserver), and return the baseKeySpaceDN to find keys under. diff --git a/keyserver/Makefile.am b/keyserver/Makefile.am index 2e7367fcc..e85865dfc 100644 --- a/keyserver/Makefile.am +++ b/keyserver/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2001, 2002 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. # # This file is part of GnuPG. # @@ -30,3 +30,13 @@ noinst_SCRIPTS = gpgkeys_test gpgkeys_ldap_LDADD = @LDAPLIBS@ @NETLIBS@ @GETOPT@ @W32LIBS@ gpgkeys_hkp_LDADD = ../util/libutil.a @NETLIBS@ @SRVLIBS@ @LIBINTL@ \ @CAPLIBS@ @GETOPT@ @W32LIBS@ + +install-exec-hook: +if GPGKEYS_LDAP + -(cd $(libexecdir) && $(LN_S) gpgkeys_ldap$(EXEEXT) gpgkeys_ldaps$(EXEEXT)) +endif + +uninstall-hook: +if GPGKEYS_LDAP + rm -f $(libexecdir)/gpgkeys_ldaps$(EXEEXT) +endif diff --git a/keyserver/gpgkeys_ldap.c b/keyserver/gpgkeys_ldap.c index b282dbd3d..37c0ffac3 100644 --- a/keyserver/gpgkeys_ldap.c +++ b/keyserver/gpgkeys_ldap.c @@ -28,9 +28,6 @@ #endif #include #include -#ifdef NEED_LBER_H -#include -#endif #include #include "keyserver.h" @@ -46,13 +43,14 @@ extern int optind; #define SEARCH 2 #define MAX_LINE 80 -int verbose=0,include_disabled=0,include_revoked=0,include_subkeys=0; -char *basekeyspacedn=NULL; -char host[80]={'\0'}; -char portstr[10]={'\0'}; -char *pgpkeystr="pgpKey"; -FILE *input=NULL,*output=NULL,*console=NULL; -LDAP *ldap=NULL; +static int verbose=0,include_disabled=0,include_revoked=0,include_subkeys=0; +static int real_ldap=0; +static char *basekeyspacedn=NULL; +static char host[80]={'\0'}; +static char portstr[10]={'\0'}; +static char *pgpkeystr="pgpKey"; +static FILE *input=NULL,*output=NULL,*console=NULL; +static LDAP *ldap=NULL; struct keylist { @@ -811,6 +809,8 @@ find_basekeyspacedn(void) attr[1]="pgpVersion"; attr[2]="pgpSoftware"; + real_ldap=1; + /* We found some, so try each namingContext as the search base and look for pgpBaseKeySpaceDN. Because we found this, we know we're talking to a regular-ish LDAP server and not a @@ -919,7 +919,7 @@ main(int argc,char *argv[]) { int port=0,arg,err,action=-1,ret=KEYSERVER_INTERNAL_ERROR; char line[MAX_LINE]; - int version,failed=0; + int version,failed=0,use_ssl=0,use_tls=0; struct keylist *keylist=NULL,*keyptr=NULL; console=stderr; @@ -973,6 +973,7 @@ main(int argc,char *argv[]) { char commandstr[7]; char optionstr[30]; + char schemestr[80]; char hash; if(line[0]=='\n') @@ -1008,6 +1009,17 @@ main(int argc,char *argv[]) continue; } + if(sscanf(line,"SCHEME %79s\n",schemestr)==1) + { + schemestr[79]='\0'; + if(strcasecmp(schemestr,"ldaps")==0) + { + port=636; + use_ssl=1; + } + continue; + } + if(sscanf(line,"VERSION %d\n",&version)==1) { if(version!=KEYSERVER_PROTO_VERSION) @@ -1060,6 +1072,26 @@ main(int argc,char *argv[]) else include_subkeys=1; } + else if(strncasecmp(start,"tls",3)==0) + { + if(no) + use_tls=0; + else if(start[3]=='=') + { + if(strcasecmp(&start[4],"no")==0) + use_tls=0; + else if(strcasecmp(&start[4],"try")==0) + use_tls=1; + else if(strcasecmp(&start[4],"warn")==0) + use_tls=2; + else if(strcasecmp(&start[4],"require")==0) + use_tls=3; + else + use_tls=1; + } + else if(start[3]=='\0') + use_tls=1; + } continue; } @@ -1141,6 +1173,88 @@ main(int argc,char *argv[]) goto fail; } + if(use_ssl) + { + if(!real_ldap) + { + fprintf(console,"gpgkeys: unable to make SSL connection: %s\n", + "not supported by the NAI LDAP keyserver"); + fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR); + goto fail; + } + else + { +#if defined(LDAP_OPT_X_TLS_HARD) && defined(HAVE_LDAP_SET_OPTION) + int ssl=LDAP_OPT_X_TLS_HARD; + err=ldap_set_option(ldap,LDAP_OPT_X_TLS,&ssl); + if(err!=LDAP_SUCCESS) + { + fprintf(console,"gpgkeys: unable to make SSL connection: %s\n", + ldap_err2string(err)); + fail_all(keylist,action,ldap_err_to_gpg_err(err)); + goto fail; + } +#else + fprintf(console,"gpgkeys: unable to make SSL connection: %s\n", + "not built with LDAPS support"); + fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR); + goto fail; +#endif + } + } + + /* use_tls: 0=don't use, 1=try silently to use, 2=try loudly to use, + 3=force use. */ + if(use_tls) + { + if(!real_ldap && use_tls) + { + if(use_tls>=2) + fprintf(console,"gpgkeys: unable to start TLS: %s\n", + "not supported by the NAI LDAP keyserver"); + if(use_tls==3) + { + fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR); + goto fail; + } + } + else + { +#if defined(HAVE_LDAP_START_TLS_S) && defined(HAVE_LDAP_SET_OPTION) + int ver=LDAP_VERSION3; + + err=LDAP_SUCCESS; + + err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver); + if(err==LDAP_SUCCESS) + err=ldap_start_tls_s(ldap,NULL,NULL); + + if(err!=LDAP_SUCCESS && use_tls>=2) + { + fprintf(console,"gpgkeys: unable to start TLS: %s\n", + ldap_err2string(err)); + /* Are we forcing it? */ + if(use_tls==3) + { + fail_all(keylist,action,ldap_err_to_gpg_err(err)); + goto fail; + } + } + else if(verbose>1) + fprintf(console,"gpgkeys: TLS started successfully.\n"); +#else + if(use_tls>=2) + fprintf(console,"gpgkeys: unable to start TLS: %s\n", + "not built with TLS support"); + if(use_tls==3) + { + fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR); + goto fail; + } +#endif + } + } + err=ldap_simple_bind_s(ldap,NULL,NULL); if(err!=0) {