support of ldap-based crl fetching

This commit is contained in:
Andreas Steffen
2007-04-06 09:44:06 +00:00
parent 4c56bd64e5
commit 241d2ff3bc
6 changed files with 208 additions and 34 deletions
+4
View File
@@ -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
+4 -4
View File
@@ -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))
+192 -18
View File
@@ -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();
+1 -1
View File
@@ -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
+2 -6
View File
@@ -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
View File
@@ -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