From ccba0d10b6baf5c73cae8cf4fb3f29f0f55c5a34 Mon Sep 17 00:00:00 2001 From: Gunter Knauf Date: Thu, 16 Aug 2007 14:08:47 +0000 Subject: added basic ldaps support; for now its ifdef'd with HAVE_LDAP_SSL unless we know its fully working, and available with all LDAP SDKs. Win32 requires to have the trusted CA in local keystore - I've not found yet a way to disable the cert check. --- lib/ldap.c | 101 ++++++++++++++++++++++++++++++++++++++++++++-------------- lib/url.c | 17 ++++++++++ lib/version.c | 3 ++ 3 files changed, 97 insertions(+), 24 deletions(-) diff --git a/lib/ldap.c b/lib/ldap.c index 3c7584a6a..28253f98c 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -48,6 +48,9 @@ #else #define LDAP_DEPRECATED 1 /* Be sure ldap_init() is defined. */ # include +#ifdef HAVE_LDAP_SSL +# include +#endif /* CURL_LDAP_USE_SSL */ #endif #ifdef HAVE_UNISTD_H @@ -107,7 +110,16 @@ static void _ldap_free_urldesc (LDAPURLDesc *ludp); #ifndef LDAP_OPT_PROTOCOL_VERSION #define LDAP_OPT_PROTOCOL_VERSION 0x0011 #endif - +#ifndef LDAP_OPT_NETWORK_TIMEOUT /* socket level timeout */ +#define LDAP_OPT_NETWORK_TIMEOUT 0x5005 +#endif +#ifndef LDAPSSL_VERIFY_NONE +#define LDAPSSL_VERIFY_NONE 0x00 +#endif +#ifndef LDAPSSL_VERIFY_SERVER +#define LDAPSSL_VERIFY_SERVER 0x01 +#endif + #ifdef DEBUG_LDAP #define LDAP_TRACE(x) do { \ _ldap_trace ("%u: ", __LINE__); \ @@ -131,26 +143,72 @@ CURLcode Curl_ldap(struct connectdata *conn, bool *done) int num = 0; struct SessionHandle *data=conn->data; int ldap_proto; + int ldap_ssl = 0; char *val_b64; size_t val_b64_sz; + struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */ *done = TRUE; /* unconditionally */ infof(data, "LDAP local: %s\n", data->change.url); - server = ldap_init(conn->host.name, (int)conn->port); +#ifndef HAVE_LDAP_URL_PARSE + rc = _ldap_url_parse(conn, &ludp); +#else + rc = ldap_url_parse(data->change.url, &ludp); +#endif + if (rc != 0) { + failf(data, "LDAP local: %s", ldap_err2string(rc)); + status = CURLE_LDAP_INVALID_URL; + goto quit; + } + + /* Get the URL scheme ( either ldap or ldaps ) */ + if (strequal(conn->protostr, "LDAPS")) + ldap_ssl = 1; + infof(data, "LDAP local: trying to establish %s connection\n", + ldap_ssl ? "encrypted" : "cleartext"); + + ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout); + ldap_proto = LDAP_VERSION3; + ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); + + if (ldap_ssl) { +#ifdef HAVE_LDAP_SSL +#ifdef CURL_LDAP_WIN + server = ldap_sslinit(conn->host.name, (int)conn->port, 1); + ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON); +#else + rc = ldapssl_client_init(NULL, /* DER encoded cert file */ + NULL); /* reserved, use NULL */ + if (rc != LDAP_SUCCESS) { + failf(data, "LDAP local: %s", ldap_err2string(rc)); + status = CURLE_SSL_CERTPROBLEM; + goto quit; + } + rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE); + if (rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ldapssl_set_verify_mode error: %d", rc); + status = CURLE_SSL_CERTPROBLEM; + goto quit; + } + server = ldapssl_init(conn->host.name, (int)conn->port, 1); +#endif +#endif /* CURL_LDAP_USE_SSL */ + } else { + server = ldap_init(conn->host.name, (int)conn->port); + } + if (server == NULL) { failf(data, "LDAP local: Cannot connect to %s:%d", - conn->host.name, conn->port); + conn->host.name, conn->port); status = CURLE_COULDNT_CONNECT; goto quit; } - ldap_proto = LDAP_VERSION3; - ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); rc = ldap_simple_bind_s(server, conn->bits.user_passwd ? conn->user : NULL, conn->bits.user_passwd ? conn->passwd : NULL); - if (rc != 0) { + if (!ldap_ssl && rc != 0) { ldap_proto = LDAP_VERSION2; ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); rc = ldap_simple_bind_s(server, @@ -163,18 +221,6 @@ CURLcode Curl_ldap(struct connectdata *conn, bool *done) goto quit; } -#ifndef HAVE_LDAP_URL_PARSE - rc = _ldap_url_parse(conn, &ludp); -#else - rc = ldap_url_parse(data->change.url, &ludp); -#endif - - if (rc != 0) { - failf(data, "LDAP local: %s", ldap_err2string(rc)); - status = CURLE_LDAP_INVALID_URL; - goto quit; - } - rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &result); @@ -242,15 +288,22 @@ CURLcode Curl_ldap(struct connectdata *conn, bool *done) } quit: - LDAP_TRACE (("Received %d entries\n", num)); + if (result) { + ldap_msgfree(result); + LDAP_TRACE (("Received %d entries\n", num)); + } if (rc == LDAP_SIZELIMIT_EXCEEDED) - infof(data, "There are more than %d entries\n", num); - if (result) - ldap_msgfree(result); + infof(data, "There are more than %d entries\n", num); if (ludp) - ldap_free_urldesc(ludp); + ldap_free_urldesc(ludp); if (server) - ldap_unbind_s(server); + ldap_unbind_s(server); +#ifdef HAVE_LDAP_SSL +#ifndef CURL_LDAP_WIN + if (ldap_ssl) + ldapssl_client_deinit(); +#endif +#endif /* CURL_LDAP_USE_SSL */ /* no data to transfer */ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); diff --git a/lib/url.c b/lib/url.c index 7699e38d2..ca7f51431 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3062,6 +3062,23 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, #endif } +#ifdef HAVE_LDAP_SSL + else if (strequal(conn->protostr, "LDAPS")) { +#ifndef CURL_DISABLE_LDAP + conn->protocol |= PROT_LDAP|PROT_SSL; + conn->port = PORT_LDAPS; + conn->remote_port = PORT_LDAPS; + conn->curl_do = Curl_ldap; + /* no LDAP-specific done */ + conn->curl_done = (Curl_done_func)ZERO_NULL; +#else + failf(data, LIBCURL_NAME + " was built with LDAP disabled!"); + return CURLE_UNSUPPORTED_PROTOCOL; +#endif + } +#endif /* CURL_LDAP_USE_SSL */ + else if (strequal(conn->protostr, "FILE")) { #ifndef CURL_DISABLE_FILE conn->protocol |= PROT_FILE; diff --git a/lib/version.c b/lib/version.c index 43b993694..de803babb 100644 --- a/lib/version.c +++ b/lib/version.c @@ -120,6 +120,9 @@ static const char * const protocols[] = { #endif #ifndef CURL_DISABLE_LDAP "ldap", +#ifdef HAVE_LDAP_SSL + "ldaps", +#endif #endif #ifndef CURL_DISABLE_HTTP "http", -- cgit v1.2.3