support of ldap-based crl fetching
This commit is contained in:
@@ -58,6 +58,10 @@ if USE_LIBCURL
|
|||||||
libstrongswan_la_LIBADD += -lcurl
|
libstrongswan_la_LIBADD += -lcurl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if USE_LIBLDAP
|
||||||
|
libstrongswan_la_LIBADD += -lldap -llber
|
||||||
|
endif
|
||||||
|
|
||||||
asn1/oid.c : asn1/oid.txt asn1/oid.pl
|
asn1/oid.c : asn1/oid.txt asn1/oid.pl
|
||||||
cd asn1 && $(PERL) 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->destroy(this->crl);
|
||||||
this->crl = crl;
|
this->crl = crl;
|
||||||
DBG1(" thisUpdate is newer - existing crl replaced");
|
DBG1(" this crl is newer - existing crl replaced");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
crl->destroy(crl);
|
crl->destroy(crl);
|
||||||
DBG1(" thisUpdate is not newer - existing crl retained");
|
DBG1(" this crl is older - existing crl retained");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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->destroy(this->crl);
|
||||||
this->crl = crl;
|
this->crl = crl;
|
||||||
DBG1(" thisUpdate is newer - existing crl replaced");
|
DBG1("this crl is newer - existing crl replaced");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
crl->destroy(crl);
|
crl->destroy(crl);
|
||||||
DBG1("thisUpdate is not newer - existing crl retained");
|
DBG1("this crl is older - existing crl retained");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (crl->is_valid(crl))
|
if (crl->is_valid(crl))
|
||||||
|
|||||||
@@ -24,6 +24,10 @@
|
|||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#endif /* LIBCURL */
|
#endif /* LIBCURL */
|
||||||
|
|
||||||
|
#ifdef LIBLDAP
|
||||||
|
#include <ldap.h>
|
||||||
|
#endif /* LIBLDAP */
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
@@ -52,13 +56,20 @@ struct private_fetcher_t {
|
|||||||
CURL* curl;
|
CURL* curl;
|
||||||
#endif /* LIBCURL */
|
#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
|
* writes data into a dynamically resizeable chunk_t
|
||||||
* needed for libcurl responses
|
* 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;
|
size_t realsize = size * nmemb;
|
||||||
chunk_t *mem = (chunk_t*)data;
|
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;
|
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_CONNECTTIMEOUT, FETCHER_TIMEOUT);
|
||||||
curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
|
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);
|
res = curl_easy_perform(this->curl);
|
||||||
|
|
||||||
if (res == CURLE_OK)
|
if (res == CURLE_OK)
|
||||||
{
|
{
|
||||||
DBG1("received valid http response");
|
DBG1("received valid curl response");
|
||||||
response = chunk_clone(curl_response);
|
response = chunk_clone(curl_response);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG1("http get request to '%s' using libcurl failed: %s",
|
DBG1("curl request to '%s' failed: %s",
|
||||||
this->uri, curl_error_buffer);
|
this->uri, curl_error_buffer);
|
||||||
}
|
}
|
||||||
curl_free(curl_response.ptr);
|
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;
|
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;
|
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
|
* Implements fetcher_t.destroy
|
||||||
*/
|
*/
|
||||||
static void destroy(private_fetcher_t *this)
|
static void destroy(private_fetcher_t *this)
|
||||||
{
|
{
|
||||||
#ifdef LIBCURL
|
#ifdef LIBCURL
|
||||||
curl_easy_cleanup(this->curl);
|
if (this->curl)
|
||||||
|
{
|
||||||
|
curl_easy_cleanup(this->curl);
|
||||||
|
}
|
||||||
#endif /* LIBCURL */
|
#endif /* LIBCURL */
|
||||||
|
|
||||||
|
#ifdef LIBLDAP
|
||||||
|
if (this->lurl)
|
||||||
|
{
|
||||||
|
ldap_free_urldesc(this->lurl);
|
||||||
|
}
|
||||||
|
#endif /* LIBLDAP */
|
||||||
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,17 +331,48 @@ fetcher_t *fetcher_create(const char *uri)
|
|||||||
|
|
||||||
/* initialize */
|
/* initialize */
|
||||||
this->uri = uri;
|
this->uri = uri;
|
||||||
|
|
||||||
#ifdef LIBCURL
|
#ifdef LIBCURL
|
||||||
this->curl = curl_easy_init();
|
this->curl = NULL;
|
||||||
if (this->curl == NULL)
|
|
||||||
{
|
|
||||||
DBG1("curl_easy_init_failed()");
|
|
||||||
}
|
|
||||||
#endif /* LIBCURL */
|
#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 */
|
/* public functions */
|
||||||
this->public.get = (chunk_t (*) (fetcher_t*))get;
|
this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))http_post;
|
||||||
this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))post;
|
|
||||||
this->public.destroy = (void (*) (fetcher_t*))destroy;
|
this->public.destroy = (void (*) (fetcher_t*))destroy;
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
@@ -209,7 +383,7 @@ fetcher_t *fetcher_create(const char *uri)
|
|||||||
*/
|
*/
|
||||||
void fetcher_initialize(void)
|
void fetcher_initialize(void)
|
||||||
{
|
{
|
||||||
#ifdef LIBCURL
|
#ifdef LIBCURL
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
|
|
||||||
/* initialize libcurl */
|
/* initialize libcurl */
|
||||||
@@ -227,7 +401,7 @@ void fetcher_initialize(void)
|
|||||||
*/
|
*/
|
||||||
void fetcher_finalize(void)
|
void fetcher_finalize(void)
|
||||||
{
|
{
|
||||||
#ifdef LIBCURL
|
#ifdef LIBCURL
|
||||||
/* finalize libcurl */
|
/* finalize libcurl */
|
||||||
DBG1("finalizing libcurl");
|
DBG1("finalizing libcurl");
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ if USE_LIBCURL
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# This compile option activates dynamic LDAP CRL fetching
|
# This compile option activates dynamic LDAP CRL fetching
|
||||||
if USE_LDAP
|
if USE_LIBLDAP
|
||||||
pluto_LDADD += -lldap -llber
|
pluto_LDADD += -lldap -llber
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -41,12 +41,8 @@ const char compile_time_interop_options[] = ""
|
|||||||
#ifdef LIBCURL
|
#ifdef LIBCURL
|
||||||
" LIBCURL"
|
" LIBCURL"
|
||||||
#endif
|
#endif
|
||||||
#ifdef LDAP_VER
|
#ifdef LIBLDAP
|
||||||
#if LDAP_VER == 2
|
" LIBLDAP"
|
||||||
" LDAP_V2"
|
|
||||||
#else
|
|
||||||
" LDAP_V3"
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef SMARTCARD
|
#ifdef SMARTCARD
|
||||||
" SMARTCARD"
|
" SMARTCARD"
|
||||||
|
|||||||
+5
-5
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include <freeswan.h>
|
#include <freeswan.h>
|
||||||
|
|
||||||
#ifdef LDAP_VER
|
#ifdef LIBLDAP
|
||||||
#include <ldap.h>
|
#include <ldap.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ fetch_curl(char *url, chunk_t *blob)
|
|||||||
#endif /* !LIBCURL */
|
#endif /* !LIBCURL */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LDAP_VER
|
#ifdef LIBLDAP
|
||||||
/*
|
/*
|
||||||
* parses the result returned by an ldap query
|
* parses the result returned by an ldap query
|
||||||
*/
|
*/
|
||||||
@@ -428,7 +428,7 @@ fetch_ldap_url(char *url, chunk_t *blob)
|
|||||||
|
|
||||||
if (ldap != NULL)
|
if (ldap != NULL)
|
||||||
{
|
{
|
||||||
int ldap_version = (LDAP_VER == 2)? LDAP_VERSION2 : LDAP_VERSION3;
|
int ldap_version = LDAP_VERSION3;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
timeout.tv_sec = FETCH_CMD_TIMEOUT;
|
timeout.tv_sec = FETCH_CMD_TIMEOUT;
|
||||||
@@ -479,13 +479,13 @@ fetch_ldap_url(char *url, chunk_t *blob)
|
|||||||
}
|
}
|
||||||
return ugh;
|
return ugh;
|
||||||
}
|
}
|
||||||
#else /* !LDAP_VER */
|
#else /* !LIBLDAP */
|
||||||
static err_t
|
static err_t
|
||||||
fetch_ldap_url(char *url, chunk_t *blob)
|
fetch_ldap_url(char *url, chunk_t *blob)
|
||||||
{
|
{
|
||||||
return "LDAP URL fetching not activated in pluto source code";
|
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
|
* fetch an ASN.1 blob coded in PEM or DER format from a URL
|
||||||
|
|||||||
Reference in New Issue
Block a user