aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--keyserver/ChangeLog8
-rw-r--r--keyserver/Makefile.am12
-rw-r--r--keyserver/gpgkeys_ldap.c136
3 files changed, 144 insertions, 12 deletions
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 <[email protected]>
+ * 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 <stdlib.h>
#include <errno.h>
-#ifdef NEED_LBER_H
-#include <lber.h>
-#endif
#include <ldap.h>
#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)
{