diff options
-rw-r--r-- | src/libstrongswan/Makefile.am | 4 | ||||
-rw-r--r-- | src/libstrongswan/crypto/ca.c | 8 | ||||
-rw-r--r-- | src/libstrongswan/utils/fetcher.c | 206 | ||||
-rw-r--r-- | src/pluto/Makefile.am | 2 | ||||
-rw-r--r-- | src/pluto/constants.c | 8 | ||||
-rw-r--r-- | src/pluto/fetch.c | 10 |
6 files changed, 206 insertions, 32 deletions
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 0236ba375..b103be193 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -58,6 +58,10 @@ if USE_LIBCURL libstrongswan_la_LIBADD += -lcurl endif +if USE_LIBLDAP + libstrongswan_la_LIBADD += -lldap -llber +endif + asn1/oid.c : asn1/oid.txt asn1/oid.pl cd asn1 && $(PERL) oid.pl diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c index 4ec8c8430..9633c77be 100644 --- a/src/libstrongswan/crypto/ca.c +++ b/src/libstrongswan/crypto/ca.c @@ -191,12 +191,12 @@ static void add_crl(private_ca_info_t *this, crl_t *crl) { this->crl->destroy(this->crl); this->crl = crl; - DBG1(" thisUpdate is newer - existing crl replaced"); + DBG1(" this crl is newer - existing crl replaced"); } else { crl->destroy(crl); - DBG1(" thisUpdate is not newer - existing crl retained"); + DBG1(" this crl is older - existing crl retained"); } } else @@ -500,12 +500,12 @@ static cert_status_t verify_by_crl(private_ca_info_t* this, certinfo_t *certinfo { this->crl->destroy(this->crl); this->crl = crl; - DBG1(" thisUpdate is newer - existing crl replaced"); + DBG1("this crl is newer - existing crl replaced"); } else { crl->destroy(crl); - DBG1("thisUpdate is not newer - existing crl retained"); + DBG1("this crl is older - existing crl retained"); continue; } if (crl->is_valid(crl)) diff --git a/src/libstrongswan/utils/fetcher.c b/src/libstrongswan/utils/fetcher.c index cf83adbdc..d728f0d00 100644 --- a/src/libstrongswan/utils/fetcher.c +++ b/src/libstrongswan/utils/fetcher.c @@ -24,6 +24,10 @@ #include <curl/curl.h> #endif /* LIBCURL */ +#ifdef LIBLDAP +#include <ldap.h> +#endif /* LIBLDAP */ + #include <library.h> #include <debug.h> @@ -52,13 +56,20 @@ struct private_fetcher_t { CURL* curl; #endif /* LIBCURL */ +#ifdef LIBLDAP + /** + * we use libldap from http://www.openssl.org/ as a fetcher + */ + LDAP *ldap; + LDAPURLDesc *lurl; +#endif /* LIBLDAP */ }; /** * writes data into a dynamically resizeable chunk_t * needed for libcurl responses */ -size_t curl_write_buffer(void *ptr, size_t size, size_t nmemb, void *data) +static size_t curl_write_buffer(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; chunk_t *mem = (chunk_t*)data; @@ -72,9 +83,9 @@ size_t curl_write_buffer(void *ptr, size_t size, size_t nmemb, void *data) } /** - * Implements fetcher_t.get + * Implements fetcher_t.get for http[s] and file URIs */ -static chunk_t get(private_fetcher_t *this) +static chunk_t curl_get(private_fetcher_t *this) { chunk_t response = chunk_empty; @@ -93,17 +104,17 @@ static chunk_t get(private_fetcher_t *this) curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT); curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE); - DBG1("sending http get request to '%s'...", this->uri); + DBG1("sending curl request to '%s'...", this->uri); res = curl_easy_perform(this->curl); if (res == CURLE_OK) { - DBG1("received valid http response"); + DBG1("received valid curl response"); response = chunk_clone(curl_response); } else { - DBG1("http get request to '%s' using libcurl failed: %s", + DBG1("curl request to '%s' failed: %s", this->uri, curl_error_buffer); } curl_free(curl_response.ptr); @@ -115,9 +126,9 @@ static chunk_t get(private_fetcher_t *this) } /** - * Implements fetcher_t.post + * Implements fetcher_t.post. */ -static chunk_t post(private_fetcher_t *this, const char *request_type, chunk_t request) +static chunk_t http_post(private_fetcher_t *this, const char *request_type, chunk_t request) { chunk_t response = chunk_empty; @@ -168,14 +179,146 @@ static chunk_t post(private_fetcher_t *this, const char *request_type, chunk_t r return response; } +#ifdef LIBLDAP +/** + * parses the result returned by an ldap query + */ +static chunk_t ldap_parse(LDAP *ldap, LDAPMessage *result) +{ + chunk_t response = chunk_empty; + + LDAPMessage *entry = ldap_first_entry(ldap, result); + if (entry != NULL) + { + BerElement *ber = NULL; + char *attr; + + attr = ldap_first_attribute(ldap, entry, &ber); + + if (attr != NULL) + { + struct berval **values = ldap_get_values_len(ldap, entry, attr); + + if (values != NULL) + { + if (values[0] != NULL) + { + response.len = values[0]->bv_len; + response.ptr = malloc(response.len); + memcpy(response.ptr, values[0]->bv_val, response.len); + if (values[1] != NULL) + { + DBG1("ldap: more than one value was fetched from LDAP URL"); + } + } + else + { + DBG1("ldap: no values in attribute"); + } + ldap_value_free_len(values); + } + else + { + DBG1("ldap: %s", ldap_err2string(ldap_result2error(ldap, entry, 0))); + } + ldap_memfree(attr); + } + else + { + DBG1("ldap: %s", ldap_err2string(ldap_result2error(ldap, entry, 0))); + } + ber_free(ber, 0); + } + else + { + DBG1("ldap: %s", ldap_err2string(ldap_result2error(ldap, result, 0))); + } + return response; +} +#endif /* LIBLDAP */ + +/** + * fetches a binary blob from an ldap url + */ +static chunk_t ldap_get(private_fetcher_t *this) +{ + chunk_t response = chunk_empty; + +#ifdef LIBLDAP + if (this->ldap) + { + int rc; + int ldap_version = LDAP_VERSION3; + + struct timeval timeout; + + timeout.tv_sec = FETCHER_TIMEOUT; + timeout.tv_usec = 0; + + ldap_set_option(this->ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version); + ldap_set_option(this->ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout); + + DBG1("sending ldap request to '%s'...", this->uri); + + rc = ldap_simple_bind_s(this->ldap, NULL, NULL); + if (rc == LDAP_SUCCESS) + { + LDAPMessage *result; + + timeout.tv_sec = FETCHER_TIMEOUT; + timeout.tv_usec = 0; + + rc = ldap_search_st(this->ldap, this->lurl->lud_dn, + this->lurl->lud_scope, + this->lurl->lud_filter, + this->lurl->lud_attrs, + 0, &timeout, &result); + + if (rc == LDAP_SUCCESS) + { + response = ldap_parse(this->ldap, result); + if (response.ptr) + { + DBG1("received valid ldap response"); + } + ldap_msgfree(result); + } + else + { + DBG1("ldap: %s", ldap_err2string(rc)); + } + } + else + { + DBG1("ldap: %s", ldap_err2string(rc)); + } + ldap_unbind_s(this->ldap); + } +#else /* !LIBLDAP */ + DBG1("warning: libldap fetching not compiled in"); +#endif /* !LIBLDAP */ + return response; +} + /** * Implements fetcher_t.destroy */ static void destroy(private_fetcher_t *this) { #ifdef LIBCURL - curl_easy_cleanup(this->curl); + if (this->curl) + { + curl_easy_cleanup(this->curl); + } #endif /* LIBCURL */ + +#ifdef LIBLDAP + if (this->lurl) + { + ldap_free_urldesc(this->lurl); + } +#endif /* LIBLDAP */ + free(this); } @@ -188,17 +331,48 @@ fetcher_t *fetcher_create(const char *uri) /* initialize */ this->uri = uri; + #ifdef LIBCURL - this->curl = curl_easy_init(); - if (this->curl == NULL) + this->curl = NULL; +#endif /* LIBCURL */ + +#ifdef LIBLDAP + this->lurl = NULL; + this->ldap = NULL; +#endif /* LIBLDAP */ + + if (strlen(uri) >= 4 && strncasecmp(uri, "ldap", 4) == 0) { - DBG1("curl_easy_init_failed()"); +#ifdef LIBLDAP + int rc = ldap_url_parse(uri, &this->lurl); + + if (rc == LDAP_SUCCESS) + { + this->ldap = ldap_init(this->lurl->lud_host, + this->lurl->lud_port); + } + else + { + DBG1("ldap: %s", ldap_err2string(rc)); + this->ldap = NULL; + } +#endif /* LIBLDAP */ + this->public.get = (chunk_t (*) (fetcher_t*))ldap_get; } + else + { +#ifdef LIBCURL + this->curl = curl_easy_init(); + if (this->curl == NULL) + { + DBG1("curl_easy_init_failed()"); + } #endif /* LIBCURL */ + this->public.get = (chunk_t (*) (fetcher_t*))curl_get; + } /* public functions */ - this->public.get = (chunk_t (*) (fetcher_t*))get; - this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))post; + this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))http_post; this->public.destroy = (void (*) (fetcher_t*))destroy; return &this->public; @@ -209,7 +383,7 @@ fetcher_t *fetcher_create(const char *uri) */ void fetcher_initialize(void) { - #ifdef LIBCURL +#ifdef LIBCURL CURLcode res; /* initialize libcurl */ @@ -227,7 +401,7 @@ void fetcher_initialize(void) */ void fetcher_finalize(void) { - #ifdef LIBCURL +#ifdef LIBCURL /* finalize libcurl */ DBG1("finalizing libcurl"); curl_global_cleanup(); diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am index 208dea175..b1b848c76 100644 --- a/src/pluto/Makefile.am +++ b/src/pluto/Makefile.am @@ -123,7 +123,7 @@ if USE_LIBCURL endif # This compile option activates dynamic LDAP CRL fetching -if USE_LDAP +if USE_LIBLDAP pluto_LDADD += -lldap -llber endif diff --git a/src/pluto/constants.c b/src/pluto/constants.c index 1fc5ec422..e7d7216ee 100644 --- a/src/pluto/constants.c +++ b/src/pluto/constants.c @@ -41,12 +41,8 @@ const char compile_time_interop_options[] = "" #ifdef LIBCURL " LIBCURL" #endif -#ifdef LDAP_VER -#if LDAP_VER == 2 - " LDAP_V2" -#else - " LDAP_V3" -#endif +#ifdef LIBLDAP + " LIBLDAP" #endif #ifdef SMARTCARD " SMARTCARD" diff --git a/src/pluto/fetch.c b/src/pluto/fetch.c index d3d922f63..e3e56d3a8 100644 --- a/src/pluto/fetch.c +++ b/src/pluto/fetch.c @@ -31,7 +31,7 @@ #include <freeswan.h> -#ifdef LDAP_VER +#ifdef LIBLDAP #include <ldap.h> #endif @@ -347,7 +347,7 @@ fetch_curl(char *url, chunk_t *blob) #endif /* !LIBCURL */ } -#ifdef LDAP_VER +#ifdef LIBLDAP /* * parses the result returned by an ldap query */ @@ -428,7 +428,7 @@ fetch_ldap_url(char *url, chunk_t *blob) if (ldap != NULL) { - int ldap_version = (LDAP_VER == 2)? LDAP_VERSION2 : LDAP_VERSION3; + int ldap_version = LDAP_VERSION3; struct timeval timeout; timeout.tv_sec = FETCH_CMD_TIMEOUT; @@ -479,13 +479,13 @@ fetch_ldap_url(char *url, chunk_t *blob) } return ugh; } -#else /* !LDAP_VER */ +#else /* !LIBLDAP */ static err_t fetch_ldap_url(char *url, chunk_t *blob) { return "LDAP URL fetching not activated in pluto source code"; } -#endif /* !LDAP_VER */ +#endif /* !LIBLDAP */ /* * fetch an ASN.1 blob coded in PEM or DER format from a URL |