summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhil Pennock <pdp@exim.org>2011-02-05 00:22:28 -0500
committerPhil Pennock <pdp@exim.org>2011-02-05 00:22:28 -0500
commitbc19a55bf1d4db3a09f8030484faf8a824a9805d (patch)
treea1731b5abf2d3b6c527a039963eda7ccace69c4e /src
parent09dcaba9252681dbacff8c19b34e983c659e44b9 (diff)
LDAP TLS negotiation support.
closes bug 230 Applies patches provided by Adam Ciarcinski of NetBSD in bug 230. Adds documentation. Tested the negotiation and server verification, not tested the client certificate presentation but looks sane.
Diffstat (limited to 'src')
-rw-r--r--src/src/globals.c7
-rw-r--r--src/src/globals.h7
-rw-r--r--src/src/lookups/ldap.c58
-rw-r--r--src/src/readconf.c7
4 files changed, 79 insertions, 0 deletions
diff --git a/src/src/globals.c b/src/src/globals.c
index 6653d62df..8631c7d8c 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -60,8 +60,15 @@ uschar *ibase_servers = NULL;
#endif
#ifdef LOOKUP_LDAP
+uschar *eldap_ca_cert_dir = NULL;
+uschar *eldap_ca_cert_file = NULL;
+uschar *eldap_cert_file = NULL;
+uschar *eldap_cert_key = NULL;
+uschar *eldap_cipher_suite = NULL;
uschar *eldap_default_servers = NULL;
+uschar *eldap_require_cert = NULL;
int eldap_version = -1;
+BOOL eldap_start_tls = FALSE;
#endif
#ifdef LOOKUP_MYSQL
diff --git a/src/src/globals.h b/src/src/globals.h
index db7a79bf7..bdc9bcf6d 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -35,7 +35,14 @@ extern uschar *ibase_servers;
#endif
#ifdef LOOKUP_LDAP
+extern uschar *eldap_ca_cert_dir; /* Directory with CA certificates */
+extern uschar *eldap_ca_cert_file; /* CA certificate file */
+extern uschar *eldap_cert_file; /* Certificate file */
+extern uschar *eldap_cert_key; /* Certificate key file */
+extern uschar *eldap_cipher_suite; /* Allowed cipher suite */
extern uschar *eldap_default_servers; /* List of default servers */
+extern uschar *eldap_require_cert; /* Peer certificate checking strategy */
+extern BOOL eldap_start_tls; /* Use STARTTLS */
extern int eldap_version; /* LDAP version */
#endif
diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c
index 943e431db..ddf803e21 100644
--- a/src/src/lookups/ldap.c
+++ b/src/src/lookups/ldap.c
@@ -431,6 +431,60 @@ if (lcp == NULL)
}
#endif /* LDAP_OPT_X_TLS */
+ #ifdef LDAP_OPT_X_TLS_CACERTFILE
+ if (eldap_ca_cert_file != NULL)
+ {
+ ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTFILE, eldap_ca_cert_file);
+ }
+ #endif
+ #ifdef LDAP_OPT_X_TLS_CACERTDIR
+ if (eldap_ca_cert_dir != NULL)
+ {
+ ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTDIR, eldap_ca_cert_dir);
+ }
+ #endif
+ #ifdef LDAP_OPT_X_TLS_CERTFILE
+ if (eldap_cert_file != NULL)
+ {
+ ldap_set_option(ld, LDAP_OPT_X_TLS_CERTFILE, eldap_cert_file);
+ }
+ #endif
+ #ifdef LDAP_OPT_X_TLS_KEYFILE
+ if (eldap_cert_key != NULL)
+ {
+ ldap_set_option(ld, LDAP_OPT_X_TLS_KEYFILE, eldap_cert_key);
+ }
+ #endif
+ #ifdef LDAP_OPT_X_TLS_CIPHER_SUITE
+ if (eldap_cipher_suite != NULL)
+ {
+ ldap_set_option(ld, LDAP_OPT_X_TLS_CIPHER_SUITE, eldap_cipher_suite);
+ }
+ #endif
+ #ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
+ if (eldap_require_cert != NULL)
+ {
+ int cert_option = LDAP_OPT_X_TLS_NEVER;
+ if (Ustrcmp(eldap_require_cert, "hard") == 0)
+ {
+ cert_option = LDAP_OPT_X_TLS_HARD;
+ }
+ else if (Ustrcmp(eldap_require_cert, "demand") == 0)
+ {
+ cert_option = LDAP_OPT_X_TLS_DEMAND;
+ }
+ else if (Ustrcmp(eldap_require_cert, "allow") == 0)
+ {
+ cert_option = LDAP_OPT_X_TLS_ALLOW;
+ }
+ else if (Ustrcmp(eldap_require_cert, "try") == 0)
+ {
+ cert_option = LDAP_OPT_X_TLS_TRY;
+ }
+ ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, cert_option);
+ }
+ #endif
+
/* Now add this connection to the chain of cached connections */
lcp = store_get(sizeof(LDAP_CONNECTION));
@@ -467,6 +521,10 @@ if (!lcp->bound ||
{
DEBUG(D_lookup) debug_printf("%sbinding with user=%s password=%s\n",
(lcp->bound)? "re-" : "", user, password);
+ if (eldap_start_tls)
+ {
+ ldap_start_tls_s(lcp->ld, NULL, NULL);
+ }
if ((msgid = ldap_bind(lcp->ld, CS user, CS password, LDAP_AUTH_SIMPLE))
== -1)
{
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 0b78958e4..b9d3747a5 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -262,7 +262,14 @@ static optionlist optionlist_config[] = {
{ "ignore_fromline_local", opt_bool, &ignore_fromline_local },
{ "keep_malformed", opt_time, &keep_malformed },
#ifdef LOOKUP_LDAP
+ { "ldap_ca_cert_dir", opt_stringptr, &eldap_ca_cert_dir },
+ { "ldap_ca_cert_file", opt_stringptr, &eldap_ca_cert_file },
+ { "ldap_cert_file", opt_stringptr, &eldap_cert_file },
+ { "ldap_cert_key", opt_stringptr, &eldap_cert_key },
+ { "ldap_cipher_suite", opt_stringptr, &eldap_cipher_suite },
{ "ldap_default_servers", opt_stringptr, &eldap_default_servers },
+ { "ldap_require_cert", opt_stringptr, &eldap_require_cert },
+ { "ldap_start_tls", opt_bool, &eldap_start_tls },
{ "ldap_version", opt_int, &eldap_version },
#endif
{ "local_from_check", opt_bool, &local_from_check },