support of ldap-based crl fetching
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
DBG1("curl_easy_init_failed()");
|
||||
}
|
||||
this->curl = NULL;
|
||||
#endif /* LIBCURL */
|
||||
|
||||
#ifdef LIBLDAP
|
||||
this->lurl = NULL;
|
||||
this->ldap = NULL;
|
||||
#endif /* LIBLDAP */
|
||||
|
||||
if (strlen(uri) >= 4 && strncasecmp(uri, "ldap", 4) == 0)
|
||||
{
|
||||
#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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
+5
-5
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user