pluto and scepclient use the curl and ldap fetcher plugins
This commit is contained in:
parent
82f0707fa3
commit
e67197a7f9
|
@ -45,6 +45,18 @@ enum fetcher_option_t {
|
||||||
*/
|
*/
|
||||||
FETCH_REQUEST_TYPE,
|
FETCH_REQUEST_TYPE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP header to be sent with with the fetch request.
|
||||||
|
* Additional argument is a char*.
|
||||||
|
*/
|
||||||
|
FETCH_REQUEST_HEADER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use HTTP Version 1.0 instead of 1.1.
|
||||||
|
* No additional argument is needed.
|
||||||
|
*/
|
||||||
|
FETCH_HTTP_VERSION_1_0,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timeout to use for fetch, in seconds.
|
* Timeout to use for fetch, in seconds.
|
||||||
* Additional argument is u_int
|
* Additional argument is u_int
|
||||||
|
|
|
@ -101,8 +101,12 @@ static status_t fetch(private_fetcher_manager_t *this,
|
||||||
good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t));
|
good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t));
|
||||||
continue;
|
continue;
|
||||||
case FETCH_REQUEST_TYPE:
|
case FETCH_REQUEST_TYPE:
|
||||||
|
case FETCH_REQUEST_HEADER:
|
||||||
good = fetcher->set_option(fetcher, opt, va_arg(args, char*));
|
good = fetcher->set_option(fetcher, opt, va_arg(args, char*));
|
||||||
continue;
|
continue;
|
||||||
|
case FETCH_HTTP_VERSION_1_0:
|
||||||
|
good = fetcher->set_option(fetcher, opt);
|
||||||
|
continue;
|
||||||
case FETCH_TIMEOUT:
|
case FETCH_TIMEOUT:
|
||||||
good = fetcher->set_option(fetcher, opt, va_arg(args, u_int));
|
good = fetcher->set_option(fetcher, opt, va_arg(args, u_int));
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -42,9 +42,9 @@ struct private_curl_fetcher_t {
|
||||||
CURL* curl;
|
CURL* curl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* request type, as set with FETCH_REQUEST_TYPE
|
* Optional HTTP headers
|
||||||
*/
|
*/
|
||||||
char *request_type;
|
struct curl_slist *headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,9 +68,8 @@ static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
|
||||||
*/
|
*/
|
||||||
static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
|
static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
|
||||||
{
|
{
|
||||||
struct curl_slist *headers = NULL;
|
|
||||||
char error[CURL_ERROR_SIZE];
|
char error[CURL_ERROR_SIZE];
|
||||||
char buf[256];;
|
char buf[256];
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
*result = chunk_empty;
|
*result = chunk_empty;
|
||||||
|
@ -85,14 +84,12 @@ static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
|
||||||
curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT);
|
curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT);
|
||||||
curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)append);
|
curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)append);
|
||||||
curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void*)result);
|
curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void*)result);
|
||||||
if (this->request_type)
|
if (this->headers)
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "Content-Type: %s", this->request_type);
|
curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, this->headers);
|
||||||
headers = curl_slist_append(headers, buf);
|
|
||||||
curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG2("sending http request to '%s'...", uri);
|
DBG2(" sending http request to '%s'...", uri);
|
||||||
switch (curl_easy_perform(this->curl))
|
switch (curl_easy_perform(this->curl))
|
||||||
{
|
{
|
||||||
case CURLE_UNSUPPORTED_PROTOCOL:
|
case CURLE_UNSUPPORTED_PROTOCOL:
|
||||||
|
@ -106,7 +103,6 @@ static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
|
||||||
status = FAILED;
|
status = FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
curl_slist_free_all(headers);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,13 +119,31 @@ static bool set_option(private_curl_fetcher_t *this, fetcher_option_t option, ..
|
||||||
case FETCH_REQUEST_DATA:
|
case FETCH_REQUEST_DATA:
|
||||||
{
|
{
|
||||||
chunk_t data = va_arg(args, chunk_t);
|
chunk_t data = va_arg(args, chunk_t);
|
||||||
|
|
||||||
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, (char*)data.ptr);
|
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, (char*)data.ptr);
|
||||||
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, data.len);
|
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, data.len);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case FETCH_REQUEST_TYPE:
|
case FETCH_REQUEST_TYPE:
|
||||||
{
|
{
|
||||||
this->request_type = va_arg(args, char*);
|
char header[BUF_LEN];
|
||||||
|
char *request_type = va_arg(args, char*);
|
||||||
|
|
||||||
|
snprintf(header, BUF_LEN, "Content-Type: %s", request_type);
|
||||||
|
this->headers = curl_slist_append(this->headers, header);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
case FETCH_REQUEST_HEADER:
|
||||||
|
{
|
||||||
|
char *header = va_arg(args, char*);
|
||||||
|
|
||||||
|
this->headers = curl_slist_append(this->headers, header);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
case FETCH_HTTP_VERSION_1_0:
|
||||||
|
{
|
||||||
|
curl_easy_setopt(this->curl, CURLOPT_HTTP_VERSION,
|
||||||
|
CURL_HTTP_VERSION_1_0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case FETCH_TIMEOUT:
|
case FETCH_TIMEOUT:
|
||||||
|
@ -148,6 +162,7 @@ static bool set_option(private_curl_fetcher_t *this, fetcher_option_t option, ..
|
||||||
*/
|
*/
|
||||||
static void destroy(private_curl_fetcher_t *this)
|
static void destroy(private_curl_fetcher_t *this)
|
||||||
{
|
{
|
||||||
|
curl_slist_free_all(this->headers);
|
||||||
curl_easy_cleanup(this->curl);
|
curl_easy_cleanup(this->curl);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +180,7 @@ curl_fetcher_t *curl_fetcher_create()
|
||||||
free(this);
|
free(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
this->request_type = NULL;
|
this->headers = NULL;
|
||||||
|
|
||||||
this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
|
this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
|
||||||
this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
|
this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
|
||||||
|
|
|
@ -84,6 +84,7 @@ AM_CFLAGS = \
|
||||||
-DIPSEC_PIDDIR=\"${piddir}\" \
|
-DIPSEC_PIDDIR=\"${piddir}\" \
|
||||||
-DSHARED_SECRETS_FILE=\"${confdir}/ipsec.secrets\" \
|
-DSHARED_SECRETS_FILE=\"${confdir}/ipsec.secrets\" \
|
||||||
-DIPSEC_PLUGINDIR=\"${plugindir}\" \
|
-DIPSEC_PLUGINDIR=\"${plugindir}\" \
|
||||||
|
-DPLUGINS=\""${pluto_plugins}\"" \
|
||||||
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
|
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
|
||||||
-DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \
|
-DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \
|
||||||
-DPLUTO -DKLIPS -DDEBUG
|
-DPLUTO -DKLIPS -DDEBUG
|
||||||
|
@ -100,11 +101,6 @@ $(LIBFREESWANDIR)/libfreeswan.a \
|
||||||
|
|
||||||
dist_man_MANS = pluto.8 ipsec.secrets.5
|
dist_man_MANS = pluto.8 ipsec.secrets.5
|
||||||
|
|
||||||
# This compile option activates the memory leak detective
|
|
||||||
if USE_LEAK_DETECTIVE
|
|
||||||
AM_CFLAGS += -DLEAK_DETECTIVE
|
|
||||||
endif
|
|
||||||
|
|
||||||
# This compile option activates the sending of a strongSwan VID
|
# This compile option activates the sending of a strongSwan VID
|
||||||
if USE_VENDORID
|
if USE_VENDORID
|
||||||
AM_CFLAGS += -DVENDORID
|
AM_CFLAGS += -DVENDORID
|
||||||
|
@ -125,18 +121,6 @@ if USE_NAT_TRANSPORT
|
||||||
AM_CFLAGS += -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
|
AM_CFLAGS += -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# This compile option activates dynamic URL fetching using libcurl
|
|
||||||
if USE_CURL
|
|
||||||
pluto_LDADD += -lcurl
|
|
||||||
AM_CFLAGS += -DLIBCURL
|
|
||||||
endif
|
|
||||||
|
|
||||||
# This compile option activates dynamic LDAP CRL fetching
|
|
||||||
if USE_LDAP
|
|
||||||
pluto_LDADD += -lldap -llber
|
|
||||||
AM_CFLAGS += -DLIBLDAP
|
|
||||||
endif
|
|
||||||
|
|
||||||
# This compile option activates smartcard support
|
# This compile option activates smartcard support
|
||||||
if USE_SMARTCARD
|
if USE_SMARTCARD
|
||||||
AM_CFLAGS += -DSMARTCARD
|
AM_CFLAGS += -DSMARTCARD
|
||||||
|
|
|
@ -38,12 +38,6 @@ const char compile_time_interop_options[] = ""
|
||||||
#ifdef THREADS
|
#ifdef THREADS
|
||||||
" THREADS"
|
" THREADS"
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIBCURL
|
|
||||||
" LIBCURL"
|
|
||||||
#endif
|
|
||||||
#ifdef LIBLDAP
|
|
||||||
" LIBLDAP"
|
|
||||||
#endif
|
|
||||||
#ifdef SMARTCARD
|
#ifdef SMARTCARD
|
||||||
" SMARTCARD"
|
" SMARTCARD"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,20 +25,11 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LIBCURL
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <freeswan.h>
|
#include <freeswan.h>
|
||||||
|
|
||||||
#ifdef LIBLDAP
|
#include <library.h>
|
||||||
#ifndef LDAP_DEPRECATED
|
#include <debug.h>
|
||||||
#define LDAP_DEPRECATED 1
|
#include <asn1/asn1.h>
|
||||||
#endif
|
|
||||||
#include <ldap.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "asn1/asn1.h"
|
|
||||||
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
@ -80,11 +71,10 @@ static pthread_mutex_t ocsp_fetch_list_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_mutex_t fetch_wake_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t fetch_wake_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_cond_t fetch_wake_cond = PTHREAD_COND_INITIALIZER;
|
static pthread_cond_t fetch_wake_cond = PTHREAD_COND_INITIALIZER;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* lock access to my certs and keys
|
* lock access to my certs and keys
|
||||||
*/
|
*/
|
||||||
void
|
void lock_certs_and_keys(const char *who)
|
||||||
lock_certs_and_keys(const char *who)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&certs_and_keys_mutex);
|
pthread_mutex_lock(&certs_and_keys_mutex);
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
|
@ -92,11 +82,10 @@ lock_certs_and_keys(const char *who)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* unlock access to my certs and keys
|
* Unlock access to my certs and keys
|
||||||
*/
|
*/
|
||||||
void
|
void unlock_certs_and_keys(const char *who)
|
||||||
unlock_certs_and_keys(const char *who)
|
|
||||||
{
|
{
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
DBG_log("certs and keys unlocked by '%s'", who)
|
DBG_log("certs and keys unlocked by '%s'", who)
|
||||||
|
@ -104,11 +93,10 @@ unlock_certs_and_keys(const char *who)
|
||||||
pthread_mutex_unlock(&certs_and_keys_mutex);
|
pthread_mutex_unlock(&certs_and_keys_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* lock access to the chained authcert list
|
* Lock access to the chained authcert list
|
||||||
*/
|
*/
|
||||||
void
|
void lock_authcert_list(const char *who)
|
||||||
lock_authcert_list(const char *who)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&authcert_list_mutex);
|
pthread_mutex_lock(&authcert_list_mutex);
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
|
@ -116,11 +104,10 @@ lock_authcert_list(const char *who)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* unlock access to the chained authcert list
|
* Unlock access to the chained authcert list
|
||||||
*/
|
*/
|
||||||
void
|
void unlock_authcert_list(const char *who)
|
||||||
unlock_authcert_list(const char *who)
|
|
||||||
{
|
{
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
DBG_log("authcert list unlocked by '%s'", who)
|
DBG_log("authcert list unlocked by '%s'", who)
|
||||||
|
@ -128,11 +115,10 @@ unlock_authcert_list(const char *who)
|
||||||
pthread_mutex_unlock(&authcert_list_mutex);
|
pthread_mutex_unlock(&authcert_list_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* lock access to the chained crl list
|
* Lock access to the chained crl list
|
||||||
*/
|
*/
|
||||||
void
|
void lock_crl_list(const char *who)
|
||||||
lock_crl_list(const char *who)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&crl_list_mutex);
|
pthread_mutex_lock(&crl_list_mutex);
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
|
@ -140,11 +126,10 @@ lock_crl_list(const char *who)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* unlock access to the chained crl list
|
* Unlock access to the chained crl list
|
||||||
*/
|
*/
|
||||||
void
|
void unlock_crl_list(const char *who)
|
||||||
unlock_crl_list(const char *who)
|
|
||||||
{
|
{
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
DBG_log("crl list unlocked by '%s'", who)
|
DBG_log("crl list unlocked by '%s'", who)
|
||||||
|
@ -152,11 +137,10 @@ unlock_crl_list(const char *who)
|
||||||
pthread_mutex_unlock(&crl_list_mutex);
|
pthread_mutex_unlock(&crl_list_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* lock access to the ocsp cache
|
* Lock access to the ocsp cache
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void lock_ocsp_cache(const char *who)
|
||||||
lock_ocsp_cache(const char *who)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&ocsp_cache_mutex);
|
pthread_mutex_lock(&ocsp_cache_mutex);
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
|
@ -164,11 +148,10 @@ lock_ocsp_cache(const char *who)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* unlock access to the ocsp cache
|
* Unlock access to the ocsp cache
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void unlock_ocsp_cache(const char *who)
|
||||||
unlock_ocsp_cache(const char *who)
|
|
||||||
{
|
{
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
DBG_log("ocsp cache unlocked by '%s'", who)
|
DBG_log("ocsp cache unlocked by '%s'", who)
|
||||||
|
@ -176,11 +159,10 @@ unlock_ocsp_cache(const char *who)
|
||||||
pthread_mutex_unlock(&ocsp_cache_mutex);
|
pthread_mutex_unlock(&ocsp_cache_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* lock access to the ca info list
|
* Lock access to the ca info list
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void lock_ca_info_list(const char *who)
|
||||||
lock_ca_info_list(const char *who)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&ca_info_list_mutex);
|
pthread_mutex_lock(&ca_info_list_mutex);
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
|
@ -188,11 +170,10 @@ lock_ca_info_list(const char *who)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* unlock access to the ca info list
|
* Unlock access to the ca info list
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void unlock_ca_info_list(const char *who)
|
||||||
unlock_ca_info_list(const char *who)
|
|
||||||
{
|
{
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
DBG_log("ca info list unlocked by '%s'", who)
|
DBG_log("ca info list unlocked by '%s'", who)
|
||||||
|
@ -200,11 +181,10 @@ unlock_ca_info_list(const char *who)
|
||||||
pthread_mutex_unlock(&ca_info_list_mutex);
|
pthread_mutex_unlock(&ca_info_list_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* lock access to the chained crl fetch request list
|
* Lock access to the chained crl fetch request list
|
||||||
*/
|
*/
|
||||||
static void
|
static void lock_crl_fetch_list(const char *who)
|
||||||
lock_crl_fetch_list(const char *who)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&crl_fetch_list_mutex);
|
pthread_mutex_lock(&crl_fetch_list_mutex);
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
|
@ -212,11 +192,10 @@ lock_crl_fetch_list(const char *who)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* unlock access to the chained crl fetch request list
|
* Unlock access to the chained crl fetch request list
|
||||||
*/
|
*/
|
||||||
static void
|
static void unlock_crl_fetch_list(const char *who)
|
||||||
unlock_crl_fetch_list(const char *who)
|
|
||||||
{
|
{
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
DBG_log("crl fetch request list unlocked by '%s'", who)
|
DBG_log("crl fetch request list unlocked by '%s'", who)
|
||||||
|
@ -224,11 +203,10 @@ unlock_crl_fetch_list(const char *who)
|
||||||
pthread_mutex_unlock(&crl_fetch_list_mutex);
|
pthread_mutex_unlock(&crl_fetch_list_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* lock access to the chained ocsp fetch request list
|
* Lock access to the chained ocsp fetch request list
|
||||||
*/
|
*/
|
||||||
static void
|
static void lock_ocsp_fetch_list(const char *who)
|
||||||
lock_ocsp_fetch_list(const char *who)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&ocsp_fetch_list_mutex);
|
pthread_mutex_lock(&ocsp_fetch_list_mutex);
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
|
@ -236,11 +214,10 @@ lock_ocsp_fetch_list(const char *who)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* unlock access to the chained ocsp fetch request list
|
* Unlock access to the chained ocsp fetch request list
|
||||||
*/
|
*/
|
||||||
static void
|
static void unlock_ocsp_fetch_list(const char *who)
|
||||||
unlock_ocsp_fetch_list(const char *who)
|
|
||||||
{
|
{
|
||||||
DBG(DBG_CONTROLMORE,
|
DBG(DBG_CONTROLMORE,
|
||||||
DBG_log("ocsp fetch request list unlocked by '%s'", who)
|
DBG_log("ocsp fetch request list unlocked by '%s'", who)
|
||||||
|
@ -248,11 +225,10 @@ unlock_ocsp_fetch_list(const char *who)
|
||||||
pthread_mutex_unlock(&ocsp_fetch_list_mutex);
|
pthread_mutex_unlock(&ocsp_fetch_list_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* wakes up the sleeping fetch thread
|
* Wakes up the sleeping fetch thread
|
||||||
*/
|
*/
|
||||||
void
|
void wake_fetch_thread(const char *who)
|
||||||
wake_fetch_thread(const char *who)
|
|
||||||
{
|
{
|
||||||
if (crl_check_interval > 0)
|
if (crl_check_interval > 0)
|
||||||
{
|
{
|
||||||
|
@ -271,11 +247,10 @@ wake_fetch_thread(const char *who)
|
||||||
#define unlock_ocsp_fetch_list(who) /* do nothing */
|
#define unlock_ocsp_fetch_list(who) /* do nothing */
|
||||||
#endif /* !THREADS */
|
#endif /* !THREADS */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* free the dynamic memory used to store fetch requests
|
* Free the dynamic memory used to store fetch requests
|
||||||
*/
|
*/
|
||||||
static void
|
static void free_fetch_request(fetch_req_t *req)
|
||||||
free_fetch_request(fetch_req_t *req)
|
|
||||||
{
|
{
|
||||||
free(req->issuer.ptr);
|
free(req->issuer.ptr);
|
||||||
free(req->authKeySerialNumber.ptr);
|
free(req->authKeySerialNumber.ptr);
|
||||||
|
@ -284,269 +259,53 @@ free_fetch_request(fetch_req_t *req)
|
||||||
free(req);
|
free(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writes data into a dynamically resizeable chunk_t
|
|
||||||
* needed for libcurl responses
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
write_buffer(void *ptr, size_t size, size_t nmemb, void *data)
|
|
||||||
{
|
|
||||||
size_t realsize = size * nmemb;
|
|
||||||
chunk_t *mem = (chunk_t*)data;
|
|
||||||
|
|
||||||
mem->ptr = (u_char *)realloc(mem->ptr, mem->len + realsize);
|
|
||||||
if (mem->ptr) {
|
|
||||||
memcpy(&(mem->ptr[mem->len]), ptr, realsize);
|
|
||||||
mem->len += realsize;
|
|
||||||
}
|
|
||||||
return realsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef THREADS
|
#ifdef THREADS
|
||||||
/*
|
/**
|
||||||
* fetches a binary blob from a url with libcurl
|
* Fetch an ASN.1 blob coded in PEM or DER format from a URL
|
||||||
*/
|
*/
|
||||||
static err_t
|
bool fetch_asn1_blob(char *url, chunk_t *blob)
|
||||||
fetch_curl(char *url, chunk_t *blob)
|
|
||||||
{
|
|
||||||
#ifdef LIBCURL
|
|
||||||
char errorbuffer[CURL_ERROR_SIZE] = "";
|
|
||||||
chunk_t response = chunk_empty;
|
|
||||||
CURLcode res;
|
|
||||||
|
|
||||||
/* get it with libcurl */
|
|
||||||
CURL *curl = curl_easy_init();
|
|
||||||
|
|
||||||
if (curl != NULL)
|
|
||||||
{
|
|
||||||
DBG(DBG_CONTROL,
|
|
||||||
DBG_log("Trying cURL '%s'", url)
|
|
||||||
)
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
|
|
||||||
|
|
||||||
res = curl_easy_perform(curl);
|
|
||||||
|
|
||||||
if (res == CURLE_OK)
|
|
||||||
{
|
|
||||||
blob->len = response.len;
|
|
||||||
blob->ptr = malloc(response.len);
|
|
||||||
memcpy(blob->ptr, response.ptr, response.len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plog("fetching uri (%s) with libcurl failed: %s", url, errorbuffer);
|
|
||||||
}
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl_free(response.ptr);
|
|
||||||
}
|
|
||||||
return strlen(errorbuffer) > 0 ? "libcurl error" : NULL;
|
|
||||||
#else /* !LIBCURL */
|
|
||||||
return "warning: not compiled with libcurl support";
|
|
||||||
#endif /* !LIBCURL */
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LIBLDAP
|
|
||||||
/*
|
|
||||||
* parses the result returned by an ldap query
|
|
||||||
*/
|
|
||||||
static err_t
|
|
||||||
parse_ldap_result(LDAP * ldap, LDAPMessage *result, chunk_t *blob)
|
|
||||||
{
|
{
|
||||||
err_t ugh = NULL;
|
err_t ugh = NULL;
|
||||||
|
|
||||||
LDAPMessage * entry = ldap_first_entry(ldap, result);
|
DBG1(" fetching crl from '%s' ...", url);
|
||||||
|
if (lib->fetcher->fetch(lib->fetcher, url, blob, FETCH_END) != SUCCESS)
|
||||||
if (entry != NULL)
|
|
||||||
{
|
{
|
||||||
BerElement *ber = NULL;
|
DBG1("crl fetching failed");
|
||||||
char *attr;
|
return FALSE;
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
blob->len = values[0]->bv_len;
|
|
||||||
blob->ptr = malloc(blob->len);
|
|
||||||
memcpy(blob->ptr, values[0]->bv_val, blob->len);
|
|
||||||
if (values[1] != NULL)
|
|
||||||
{
|
|
||||||
plog("warning: more than one value was fetched from LDAP URL");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = "no values in attribute";
|
|
||||||
}
|
|
||||||
ldap_value_free_len(values);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
|
|
||||||
}
|
|
||||||
ldap_memfree(attr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
|
|
||||||
}
|
|
||||||
ber_free(ber, 0);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = ldap_err2string(ldap_result2error(ldap, result, 0));
|
|
||||||
}
|
|
||||||
return ugh;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fetches a binary blob from an ldap url
|
|
||||||
*/
|
|
||||||
static err_t
|
|
||||||
fetch_ldap_url(char *url, chunk_t *blob)
|
|
||||||
{
|
|
||||||
LDAPURLDesc *lurl;
|
|
||||||
err_t ugh = NULL;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
DBG(DBG_CONTROL,
|
|
||||||
DBG_log("Trying LDAP URL '%s'", url)
|
|
||||||
)
|
|
||||||
|
|
||||||
rc = ldap_url_parse(url, &lurl);
|
|
||||||
|
|
||||||
if (rc == LDAP_SUCCESS)
|
|
||||||
{
|
|
||||||
LDAP *ldap = ldap_init(lurl->lud_host, lurl->lud_port);
|
|
||||||
|
|
||||||
if (ldap != NULL)
|
|
||||||
{
|
|
||||||
int ldap_version = LDAP_VERSION3;
|
|
||||||
struct timeval timeout;
|
|
||||||
|
|
||||||
timeout.tv_sec = FETCH_CMD_TIMEOUT;
|
|
||||||
timeout.tv_usec = 0;
|
|
||||||
ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
|
|
||||||
ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
|
|
||||||
|
|
||||||
rc = ldap_simple_bind_s(ldap, NULL, NULL);
|
|
||||||
|
|
||||||
if (rc == LDAP_SUCCESS)
|
|
||||||
{
|
|
||||||
LDAPMessage *result;
|
|
||||||
|
|
||||||
timeout.tv_sec = FETCH_CMD_TIMEOUT;
|
|
||||||
timeout.tv_usec = 0;
|
|
||||||
|
|
||||||
rc = ldap_search_st(ldap, lurl->lud_dn
|
|
||||||
, lurl->lud_scope
|
|
||||||
, lurl->lud_filter
|
|
||||||
, lurl->lud_attrs
|
|
||||||
, 0, &timeout, &result);
|
|
||||||
|
|
||||||
if (rc == LDAP_SUCCESS)
|
|
||||||
{
|
|
||||||
ugh = parse_ldap_result(ldap, result, blob);
|
|
||||||
ldap_msgfree(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = ldap_err2string(rc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = ldap_err2string(rc);
|
|
||||||
}
|
|
||||||
ldap_unbind_s(ldap);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = "ldap init";
|
|
||||||
}
|
|
||||||
ldap_free_urldesc(lurl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = ldap_err2string(rc);
|
|
||||||
}
|
|
||||||
return ugh;
|
|
||||||
}
|
|
||||||
#else /* !LIBLDAP */
|
|
||||||
static err_t
|
|
||||||
fetch_ldap_url(char *url, chunk_t *blob)
|
|
||||||
{
|
|
||||||
return "LDAP URL fetching not activated in pluto source code";
|
|
||||||
}
|
|
||||||
#endif /* !LIBLDAP */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fetch an ASN.1 blob coded in PEM or DER format from a URL
|
|
||||||
*/
|
|
||||||
static err_t
|
|
||||||
fetch_asn1_blob(char *url, chunk_t *blob)
|
|
||||||
{
|
|
||||||
err_t ugh = NULL;
|
|
||||||
|
|
||||||
if (strlen(url) >= 4 && strncasecmp(url, "ldap", 4) == 0)
|
|
||||||
{
|
|
||||||
ugh = fetch_ldap_url(url, blob);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = fetch_curl(url, blob);
|
|
||||||
}
|
|
||||||
if (ugh != NULL)
|
|
||||||
return ugh;
|
|
||||||
|
|
||||||
if (is_asn1(*blob))
|
if (is_asn1(*blob))
|
||||||
{
|
{
|
||||||
DBG(DBG_PARSING,
|
DBG2(" fetched blob coded in DER format");
|
||||||
DBG_log(" fetched blob coded in DER format")
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool pgp = FALSE;
|
bool pgp = FALSE;
|
||||||
|
|
||||||
ugh = pemtobin(blob, NULL, "", &pgp);
|
ugh = pemtobin(blob, NULL, "", &pgp);
|
||||||
if (ugh == NULL)
|
if (ugh != NULL)
|
||||||
{
|
{
|
||||||
if (is_asn1(*blob))
|
free(blob->ptr);
|
||||||
{
|
return FALSE;
|
||||||
DBG(DBG_PARSING,
|
};
|
||||||
DBG_log(" fetched blob coded in PEM format")
|
if (is_asn1(*blob))
|
||||||
)
|
{
|
||||||
}
|
DBG2(" fetched blob coded in PEM format");
|
||||||
else
|
|
||||||
{
|
|
||||||
ugh = "blob coded in unknown format";
|
|
||||||
free(blob->ptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DBG1("crl fetched successfully but data coded in unknown format");
|
||||||
free(blob->ptr);
|
free(blob->ptr);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ugh;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* complete a distributionPoint URI with ca information
|
* Complete a distributionPoint URI with ca information
|
||||||
*/
|
*/
|
||||||
static char*
|
static char* complete_uri(chunk_t distPoint, const char *ldaphost)
|
||||||
complete_uri(chunk_t distPoint, const char *ldaphost)
|
|
||||||
{
|
{
|
||||||
char *uri;
|
char *uri;
|
||||||
char *ptr = distPoint.ptr;
|
char *ptr = distPoint.ptr;
|
||||||
|
@ -589,11 +348,10 @@ complete_uri(chunk_t distPoint, const char *ldaphost)
|
||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* try to fetch the crls defined by the fetch requests
|
* Try to fetch the crls defined by the fetch requests
|
||||||
*/
|
*/
|
||||||
static void
|
static void fetch_crls(bool cache_crls)
|
||||||
fetch_crls(bool cache_crls)
|
|
||||||
{
|
{
|
||||||
fetch_req_t *req;
|
fetch_req_t *req;
|
||||||
fetch_req_t **reqp;
|
fetch_req_t **reqp;
|
||||||
|
@ -619,14 +377,7 @@ fetch_crls(bool cache_crls)
|
||||||
{
|
{
|
||||||
char *uri = complete_uri(gn->name, ldaphost);
|
char *uri = complete_uri(gn->name, ldaphost);
|
||||||
|
|
||||||
err_t ugh = fetch_asn1_blob(uri, &blob);
|
if (fetch_asn1_blob(uri, &blob))
|
||||||
free(uri);
|
|
||||||
|
|
||||||
if (ugh != NULL)
|
|
||||||
{
|
|
||||||
plog("fetch failed: %s", ugh);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
chunk_t crl_uri = chunk_clone(gn->name);
|
chunk_t crl_uri = chunk_clone(gn->name);
|
||||||
|
|
||||||
|
@ -636,9 +387,11 @@ fetch_crls(bool cache_crls)
|
||||||
DBG_log("we have a valid crl")
|
DBG_log("we have a valid crl")
|
||||||
)
|
)
|
||||||
valid_crl = TRUE;
|
valid_crl = TRUE;
|
||||||
|
free(uri);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(uri);
|
||||||
gn = gn->next;
|
gn = gn->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,73 +417,33 @@ fetch_crls(bool cache_crls)
|
||||||
unlock_crl_fetch_list("fetch_crls");
|
unlock_crl_fetch_list("fetch_crls");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void fetch_ocsp_status(ocsp_location_t* location)
|
||||||
fetch_ocsp_status(ocsp_location_t* location)
|
|
||||||
{
|
{
|
||||||
#ifdef LIBCURL
|
chunk_t request, response;
|
||||||
chunk_t request;
|
char *uri;
|
||||||
chunk_t response = chunk_empty;
|
|
||||||
|
|
||||||
CURL* curl;
|
|
||||||
CURLcode res;
|
|
||||||
|
|
||||||
request = build_ocsp_request(location);
|
request = build_ocsp_request(location);
|
||||||
|
response = chunk_empty;
|
||||||
|
|
||||||
DBG(DBG_CONTROL,
|
/* we need a null terminated string for curl */
|
||||||
DBG_log("sending ocsp request to location '%.*s'"
|
uri = malloc(location->uri.len + 1);
|
||||||
, (int)location->uri.len, location->uri.ptr)
|
memcpy(uri, location->uri.ptr, location->uri.len);
|
||||||
)
|
*(uri + location->uri.len) = '\0';
|
||||||
DBG(DBG_RAW,
|
|
||||||
DBG_dump_chunk("OCSP request", request)
|
|
||||||
)
|
|
||||||
|
|
||||||
/* send via http post using libcurl */
|
DBG1(" requesting ocsp status from '%s' ...", uri);
|
||||||
curl = curl_easy_init();
|
if (lib->fetcher->fetch(lib->fetcher, uri, &response,
|
||||||
|
FETCH_REQUEST_DATA, request,
|
||||||
if (curl != NULL)
|
FETCH_REQUEST_TYPE, "application/ocsp-request",
|
||||||
|
FETCH_END) == SUCCESS)
|
||||||
{
|
{
|
||||||
char errorbuffer[CURL_ERROR_SIZE];
|
parse_ocsp(location, response);
|
||||||
struct curl_slist *headers = NULL;
|
|
||||||
char* uri = malloc(location->uri.len + 1);
|
|
||||||
|
|
||||||
/* we need a null terminated string for curl */
|
|
||||||
memcpy(uri, location->uri.ptr, location->uri.len);
|
|
||||||
*(uri + location->uri.len) = '\0';
|
|
||||||
|
|
||||||
/* set content type header */
|
|
||||||
headers = curl_slist_append(headers, "Content-Type: application/ocsp-request");
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, uri);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (void*)request.ptr);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, request.len);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
|
|
||||||
|
|
||||||
res = curl_easy_perform(curl);
|
|
||||||
|
|
||||||
if (res == CURLE_OK)
|
|
||||||
{
|
|
||||||
DBG(DBG_CONTROL,
|
|
||||||
DBG_log("received ocsp response")
|
|
||||||
)
|
|
||||||
DBG(DBG_RAW,
|
|
||||||
DBG_dump_chunk("OCSP response:\n", response)
|
|
||||||
)
|
|
||||||
parse_ocsp(location, response);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plog("failed to fetch ocsp status from '%s': %s", uri, errorbuffer);
|
|
||||||
}
|
|
||||||
curl_slist_free_all(headers);
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
free(uri);
|
|
||||||
curl_free(response.ptr);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1("ocsp request to %s failed", uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(uri);
|
||||||
free(request.ptr);
|
free(request.ptr);
|
||||||
chunk_free(&location->nonce);
|
chunk_free(&location->nonce);
|
||||||
|
|
||||||
|
@ -744,17 +457,12 @@ fetch_ocsp_status(ocsp_location_t* location)
|
||||||
certinfo = certinfo->next;
|
certinfo = certinfo->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
#else /* !LIBCURL */
|
|
||||||
plog("ocsp error: pluto wasn't compiled with libcurl support");
|
|
||||||
#endif /* !LIBCURL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* try to fetch the necessary ocsp information
|
* Try to fetch the necessary ocsp information
|
||||||
*/
|
*/
|
||||||
static void
|
static void fetch_ocsp(void)
|
||||||
fetch_ocsp(void)
|
|
||||||
{
|
{
|
||||||
ocsp_location_t *location;
|
ocsp_location_t *location;
|
||||||
|
|
||||||
|
@ -765,15 +473,16 @@ fetch_ocsp(void)
|
||||||
while (location != NULL)
|
while (location != NULL)
|
||||||
{
|
{
|
||||||
if (location->certinfo != NULL)
|
if (location->certinfo != NULL)
|
||||||
|
{
|
||||||
fetch_ocsp_status(location);
|
fetch_ocsp_status(location);
|
||||||
|
}
|
||||||
location = location->next;
|
location = location->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_ocsp_fetch_list("fetch_ocsp");
|
unlock_ocsp_fetch_list("fetch_ocsp");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
static void* fetch_thread(void *arg)
|
||||||
fetch_thread(void *arg)
|
|
||||||
{
|
{
|
||||||
struct timespec wait_interval;
|
struct timespec wait_interval;
|
||||||
|
|
||||||
|
@ -817,29 +526,16 @@ fetch_thread(void *arg)
|
||||||
}
|
}
|
||||||
#endif /* THREADS*/
|
#endif /* THREADS*/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* initializes curl and starts the fetching thread
|
* Initializes curl and starts the fetching thread
|
||||||
*/
|
*/
|
||||||
void
|
void init_fetch(void)
|
||||||
init_fetch(void)
|
|
||||||
{
|
{
|
||||||
#if defined(LIBCURL) || defined (THREADS)
|
|
||||||
int status;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LIBCURL
|
|
||||||
/* init curl */
|
|
||||||
status = curl_global_init(CURL_GLOBAL_NOTHING);
|
|
||||||
if (status != CURLE_OK)
|
|
||||||
{
|
|
||||||
plog("libcurl could not be initialized, status = %d", status);
|
|
||||||
}
|
|
||||||
#endif /* LIBCURL */
|
|
||||||
|
|
||||||
if (crl_check_interval > 0)
|
if (crl_check_interval > 0)
|
||||||
{
|
{
|
||||||
#ifdef THREADS
|
#ifdef THREADS
|
||||||
status = pthread_create( &thread, NULL, fetch_thread, NULL);
|
int status = pthread_create( &thread, NULL, fetch_thread, NULL);
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
plog("fetching thread could not be started, status = %d", status);
|
plog("fetching thread could not be started, status = %d", status);
|
||||||
|
@ -850,8 +546,7 @@ init_fetch(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void free_crl_fetch(void)
|
||||||
free_crl_fetch(void)
|
|
||||||
{
|
{
|
||||||
lock_crl_fetch_list("free_crl_fetch");
|
lock_crl_fetch_list("free_crl_fetch");
|
||||||
|
|
||||||
|
@ -863,21 +558,12 @@ free_crl_fetch(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_crl_fetch_list("free_crl_fetch");
|
unlock_crl_fetch_list("free_crl_fetch");
|
||||||
|
|
||||||
#ifdef LIBCURL
|
|
||||||
if (crl_check_interval > 0)
|
|
||||||
{
|
|
||||||
/* cleanup curl */
|
|
||||||
curl_global_cleanup();
|
|
||||||
}
|
|
||||||
#endif /* LIBCURL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* free the chained list of ocsp requests
|
* Free the chained list of ocsp requests
|
||||||
*/
|
*/
|
||||||
void
|
void free_ocsp_fetch(void)
|
||||||
free_ocsp_fetch(void)
|
|
||||||
{
|
{
|
||||||
lock_ocsp_fetch_list("free_ocsp_fetch");
|
lock_ocsp_fetch_list("free_ocsp_fetch");
|
||||||
free_ocsp_locations(&ocsp_fetch_reqs);
|
free_ocsp_locations(&ocsp_fetch_reqs);
|
||||||
|
@ -885,11 +571,10 @@ free_ocsp_fetch(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* add additional distribution points
|
* Add additional distribution points
|
||||||
*/
|
*/
|
||||||
void
|
void add_distribution_points(const generalName_t *newPoints ,generalName_t **distributionPoints)
|
||||||
add_distribution_points(const generalName_t *newPoints ,generalName_t **distributionPoints)
|
|
||||||
{
|
{
|
||||||
while (newPoints != NULL)
|
while (newPoints != NULL)
|
||||||
{
|
{
|
||||||
|
@ -927,9 +612,8 @@ add_distribution_points(const generalName_t *newPoints ,generalName_t **distribu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch_req_t*
|
fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber,
|
||||||
build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber
|
chunk_t authKeyID, const generalName_t *gn)
|
||||||
, chunk_t authKeyID, const generalName_t *gn)
|
|
||||||
{
|
{
|
||||||
fetch_req_t *req = malloc_thing(fetch_req_t);
|
fetch_req_t *req = malloc_thing(fetch_req_t);
|
||||||
*req = empty_fetch_req;
|
*req = empty_fetch_req;
|
||||||
|
@ -948,11 +632,10 @@ build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* add a crl fetch request to the chained list
|
* Add a crl fetch request to the chained list
|
||||||
*/
|
*/
|
||||||
void
|
void add_crl_fetch_request(fetch_req_t *req)
|
||||||
add_crl_fetch_request(fetch_req_t *req)
|
|
||||||
{
|
{
|
||||||
fetch_req_t *r;
|
fetch_req_t *r;
|
||||||
|
|
||||||
|
@ -990,11 +673,10 @@ add_crl_fetch_request(fetch_req_t *req)
|
||||||
unlock_crl_fetch_list("add_crl_fetch_request");
|
unlock_crl_fetch_list("add_crl_fetch_request");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* add an ocsp fetch request to the chained list
|
* Add an ocsp fetch request to the chained list
|
||||||
*/
|
*/
|
||||||
void
|
void add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
|
||||||
add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
|
|
||||||
{
|
{
|
||||||
ocsp_certinfo_t certinfo;
|
ocsp_certinfo_t certinfo;
|
||||||
|
|
||||||
|
@ -1005,11 +687,10 @@ add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
|
||||||
unlock_ocsp_fetch_list("add_ocsp_fetch_request");
|
unlock_ocsp_fetch_list("add_ocsp_fetch_request");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* list all distribution points
|
* List all distribution points
|
||||||
*/
|
*/
|
||||||
void
|
void list_distribution_points(const generalName_t *gn)
|
||||||
list_distribution_points(const generalName_t *gn)
|
|
||||||
{
|
{
|
||||||
bool first_gn = TRUE;
|
bool first_gn = TRUE;
|
||||||
|
|
||||||
|
@ -1022,11 +703,10 @@ list_distribution_points(const generalName_t *gn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* list all fetch requests in the chained list
|
* List all fetch requests in the chained list
|
||||||
*/
|
*/
|
||||||
void
|
void list_crl_fetch_requests(bool utc)
|
||||||
list_crl_fetch_requests(bool utc)
|
|
||||||
{
|
{
|
||||||
fetch_req_t *req;
|
fetch_req_t *req;
|
||||||
|
|
||||||
|
@ -1066,8 +746,7 @@ list_crl_fetch_requests(bool utc)
|
||||||
unlock_crl_fetch_list("list_crl_fetch_requests");
|
unlock_crl_fetch_list("list_crl_fetch_requests");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void list_ocsp_fetch_requests(bool utc)
|
||||||
list_ocsp_fetch_requests(bool utc)
|
|
||||||
{
|
{
|
||||||
lock_ocsp_fetch_list("list_ocsp_fetch_requests");
|
lock_ocsp_fetch_list("list_ocsp_fetch_requests");
|
||||||
list_ocsp_locations(ocsp_fetch_reqs, TRUE, utc, FALSE);
|
list_ocsp_locations(ocsp_fetch_reqs, TRUE, utc, FALSE);
|
||||||
|
|
|
@ -631,7 +631,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/* load plugins, further infrastructure may need it */
|
/* load plugins, further infrastructure may need it */
|
||||||
lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
|
lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
|
||||||
lib->settings->get_str(lib->settings, "pluto.load", ""));
|
lib->settings->get_str(lib->settings, "pluto.load", PLUGINS));
|
||||||
print_plugins();
|
print_plugins();
|
||||||
|
|
||||||
init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
|
init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
|
||||||
|
|
|
@ -18,6 +18,7 @@ INCLUDES = \
|
||||||
AM_CFLAGS = \
|
AM_CFLAGS = \
|
||||||
-DIPSEC_CONFDIR=\"${confdir}\" \
|
-DIPSEC_CONFDIR=\"${confdir}\" \
|
||||||
-DIPSEC_PLUGINDIR=\"${plugindir}\" \
|
-DIPSEC_PLUGINDIR=\"${plugindir}\" \
|
||||||
|
-DPLUGINS=\""${pluto_plugins}\"" \
|
||||||
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
|
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
|
||||||
-DDEBUG -DNO_PLUTO
|
-DDEBUG -DNO_PLUTO
|
||||||
|
|
||||||
|
@ -34,23 +35,12 @@ $(LIBFREESWANBUILDDIR)/libfreeswan.a \
|
||||||
$(LIBCRYPTOBUILDDIR)/libcrypto.a \
|
$(LIBCRYPTOBUILDDIR)/libcrypto.a \
|
||||||
-lgmp
|
-lgmp
|
||||||
|
|
||||||
# This compile option activates the memory leak detective
|
|
||||||
if USE_LEAK_DETECTIVE
|
|
||||||
AM_CFLAGS += -DLEAK_DETECTIVE
|
|
||||||
endif
|
|
||||||
|
|
||||||
# This compile option activates smartcard support
|
# This compile option activates smartcard support
|
||||||
if USE_SMARTCARD
|
if USE_SMARTCARD
|
||||||
AM_CFLAGS += -DSMARTCARD
|
AM_CFLAGS += -DSMARTCARD
|
||||||
scepclient_LDADD += -ldl
|
scepclient_LDADD += -ldl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# This compile option activates dynamic URL fetching using libcurl
|
|
||||||
if USE_CURL
|
|
||||||
AM_CFLAGS += -DLIBCURL
|
|
||||||
scepclient_LDADD += -lcurl
|
|
||||||
endif
|
|
||||||
|
|
||||||
dist_man_MANS = scepclient.8
|
dist_man_MANS = scepclient.8
|
||||||
|
|
||||||
ca.o : $(PLUTODIR)/ca.c $(PLUTODIR)/ca.h
|
ca.o : $(PLUTODIR)/ca.c $(PLUTODIR)/ca.h
|
||||||
|
|
|
@ -25,14 +25,11 @@
|
||||||
|
|
||||||
#include <freeswan.h>
|
#include <freeswan.h>
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
#include <asn1/asn1.h>
|
#include <asn1/asn1.h>
|
||||||
#include <asn1/asn1_parser.h>
|
#include <asn1/asn1_parser.h>
|
||||||
#include <asn1/oid.h>
|
#include <asn1/oid.h>
|
||||||
|
|
||||||
#ifdef LIBCURL
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../pluto/constants.h"
|
#include "../pluto/constants.h"
|
||||||
#include "../pluto/defs.h"
|
#include "../pluto/defs.h"
|
||||||
#include "../pluto/rnd.h"
|
#include "../pluto/rnd.h"
|
||||||
|
@ -264,11 +261,11 @@ end:
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generates a unique fingerprint of the pkcs10 request
|
/**
|
||||||
|
* Generates a unique fingerprint of the pkcs10 request
|
||||||
* by computing an MD5 hash over it
|
* by computing an MD5 hash over it
|
||||||
*/
|
*/
|
||||||
void
|
void scep_generate_pkcs10_fingerprint(chunk_t pkcs10, chunk_t *fingerprint)
|
||||||
scep_generate_pkcs10_fingerprint(chunk_t pkcs10, chunk_t *fingerprint)
|
|
||||||
{
|
{
|
||||||
char buf[MD5_DIGEST_SIZE];
|
char buf[MD5_DIGEST_SIZE];
|
||||||
chunk_t digest = { buf, sizeof(buf) };
|
chunk_t digest = { buf, sizeof(buf) };
|
||||||
|
@ -280,12 +277,12 @@ scep_generate_pkcs10_fingerprint(chunk_t pkcs10, chunk_t *fingerprint)
|
||||||
datatot(digest.ptr, digest.len, 16, fingerprint->ptr, fingerprint->len + 1);
|
datatot(digest.ptr, digest.len, 16, fingerprint->ptr, fingerprint->len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a transaction id as the MD5 hash of an public key
|
/**
|
||||||
|
* Generate a transaction id as the MD5 hash of an public key
|
||||||
* the transaction id is also used as a unique serial number
|
* the transaction id is also used as a unique serial number
|
||||||
*/
|
*/
|
||||||
void
|
void scep_generate_transaction_id(const RSA_public_key_t *rsak,
|
||||||
scep_generate_transaction_id(const RSA_public_key_t *rsak
|
chunk_t *transID, chunk_t *serialNumber)
|
||||||
, chunk_t *transID, chunk_t *serialNumber)
|
|
||||||
{
|
{
|
||||||
char buf[MD5_DIGEST_SIZE];
|
char buf[MD5_DIGEST_SIZE];
|
||||||
|
|
||||||
|
@ -319,11 +316,10 @@ scep_generate_transaction_id(const RSA_public_key_t *rsak
|
||||||
datatot(digest.ptr, digest.len, 16, transID->ptr, transID->len + 1);
|
datatot(digest.ptr, digest.len, 16, transID->ptr, transID->len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* builds a transId attribute
|
* Builds a transId attribute
|
||||||
*/
|
*/
|
||||||
chunk_t
|
chunk_t scep_transId_attribute(chunk_t transID)
|
||||||
scep_transId_attribute(chunk_t transID)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
||||||
, ASN1_transId_oid
|
, ASN1_transId_oid
|
||||||
|
@ -333,11 +329,10 @@ scep_transId_attribute(chunk_t transID)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* builds a messageType attribute
|
* Builds a messageType attribute
|
||||||
*/
|
*/
|
||||||
chunk_t
|
chunk_t scep_messageType_attribute(scep_msg_t m)
|
||||||
scep_messageType_attribute(scep_msg_t m)
|
|
||||||
{
|
{
|
||||||
chunk_t msgType = {
|
chunk_t msgType = {
|
||||||
(u_char*)msgType_values[m],
|
(u_char*)msgType_values[m],
|
||||||
|
@ -352,11 +347,10 @@ scep_messageType_attribute(scep_msg_t m)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* builds a senderNonce attribute
|
* Builds a senderNonce attribute
|
||||||
*/
|
*/
|
||||||
chunk_t
|
chunk_t scep_senderNonce_attribute(void)
|
||||||
scep_senderNonce_attribute(void)
|
|
||||||
{
|
{
|
||||||
const size_t nonce_len = 16;
|
const size_t nonce_len = 16;
|
||||||
u_char nonce_buf[nonce_len];
|
u_char nonce_buf[nonce_len];
|
||||||
|
@ -372,14 +366,13 @@ scep_senderNonce_attribute(void)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* builds a pkcs7 enveloped and signed scep request
|
* Builds a pkcs7 enveloped and signed scep request
|
||||||
*/
|
*/
|
||||||
chunk_t
|
chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
|
||||||
scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg
|
const x509cert_t *enc_cert, int enc_alg,
|
||||||
, const x509cert_t *enc_cert, int enc_alg
|
const x509cert_t *signer_cert, int digest_alg,
|
||||||
, const x509cert_t *signer_cert, int digest_alg
|
const RSA_private_key_t *private_key)
|
||||||
, const RSA_private_key_t *private_key)
|
|
||||||
{
|
{
|
||||||
chunk_t envelopedData, attributes, request;
|
chunk_t envelopedData, attributes, request;
|
||||||
|
|
||||||
|
@ -400,12 +393,11 @@ scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIBCURL
|
/**
|
||||||
/* converts a binary request to base64 with 64 characters per line
|
* Converts a binary request to base64 with 64 characters per line
|
||||||
* newline and '+' characters are escaped by %0A and %2B, respectively
|
* newline and '+' characters are escaped by %0A and %2B, respectively
|
||||||
*/
|
*/
|
||||||
static char*
|
static char* escape_http_request(chunk_t req)
|
||||||
escape_http_request(chunk_t req)
|
|
||||||
{
|
{
|
||||||
char *escaped_req = NULL;
|
char *escaped_req = NULL;
|
||||||
char *p1, *p2;
|
char *p1, *p2;
|
||||||
|
@ -460,70 +452,58 @@ escape_http_request(chunk_t req)
|
||||||
free(encoded_req);
|
free(encoded_req);
|
||||||
return escaped_req;
|
return escaped_req;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* send a SCEP request via HTTP and wait for a response
|
* Send a SCEP request via HTTP and wait for a response
|
||||||
*/
|
*/
|
||||||
bool
|
bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
|
||||||
scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op
|
bool http_get_request, chunk_t *response)
|
||||||
, fetch_request_t req_type, chunk_t *response)
|
|
||||||
{
|
{
|
||||||
#ifdef LIBCURL
|
int len;
|
||||||
char errorbuffer[CURL_ERROR_SIZE] = "";
|
status_t status;
|
||||||
char *complete_url = NULL;
|
char *complete_url = NULL;
|
||||||
struct curl_slist *headers = NULL;
|
|
||||||
CURL *curl;
|
|
||||||
CURLcode res;
|
|
||||||
|
|
||||||
/* initialize response */
|
/* initialize response */
|
||||||
*response = chunk_empty;
|
*response = chunk_empty;
|
||||||
|
|
||||||
/* initialize curl context */
|
DBG(DBG_CONTROL,
|
||||||
curl = curl_easy_init();
|
DBG_log("sending scep request to '%s'", url)
|
||||||
if (curl == NULL)
|
)
|
||||||
{
|
|
||||||
plog("could not initialize curl context");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op == SCEP_PKI_OPERATION)
|
if (op == SCEP_PKI_OPERATION)
|
||||||
{
|
{
|
||||||
const char operation[] = "PKIOperation";
|
const char operation[] = "PKIOperation";
|
||||||
|
|
||||||
if (req_type == FETCH_GET)
|
if (http_get_request)
|
||||||
{
|
{
|
||||||
char *escaped_req = escape_http_request(pkcs7);
|
char *escaped_req = escape_http_request(pkcs7);
|
||||||
|
|
||||||
/* form complete url */
|
/* form complete url */
|
||||||
int len = strlen(url) + 20 + strlen(operation) + strlen(escaped_req) + 1;
|
len = strlen(url) + 20 + strlen(operation) + strlen(escaped_req) + 1;
|
||||||
|
|
||||||
complete_url = malloc(len);
|
complete_url = malloc(len);
|
||||||
snprintf(complete_url, len, "%s?operation=%s&message=%s"
|
snprintf(complete_url, len, "%s?operation=%s&message=%s"
|
||||||
, url, operation, escaped_req);
|
, url, operation, escaped_req);
|
||||||
free(escaped_req);
|
free(escaped_req);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, TRUE);
|
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
|
||||||
headers = curl_slist_append(headers, "Pragma:");
|
FETCH_HTTP_VERSION_1_0,
|
||||||
headers = curl_slist_append(headers, "Host:");
|
FETCH_REQUEST_HEADER, "Pragma:",
|
||||||
headers = curl_slist_append(headers, "Accept:");
|
FETCH_REQUEST_HEADER, "Host:",
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
FETCH_REQUEST_HEADER, "Accept:",
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
FETCH_END);
|
||||||
}
|
}
|
||||||
else /* HTTP_POST */
|
else /* HTTP_POST */
|
||||||
{
|
{
|
||||||
/* form complete url */
|
/* form complete url */
|
||||||
int len = strlen(url) + 11 + strlen(operation) + 1;
|
len = strlen(url) + 11 + strlen(operation) + 1;
|
||||||
|
|
||||||
complete_url = malloc(len);
|
complete_url = malloc(len);
|
||||||
snprintf(complete_url, len, "%s?operation=%s", url, operation);
|
snprintf(complete_url, len, "%s?operation=%s", url, operation);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, FALSE);
|
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
|
||||||
headers = curl_slist_append(headers, "Content-Type:");
|
FETCH_REQUEST_DATA, pkcs7,
|
||||||
headers = curl_slist_append(headers, "Expect:");
|
FETCH_REQUEST_TYPE, "",
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
FETCH_REQUEST_HEADER, "Expect:",
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char*)pkcs7.ptr);
|
FETCH_END);
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, pkcs7.len);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* SCEP_GET_CA_CERT */
|
else /* SCEP_GET_CA_CERT */
|
||||||
|
@ -531,54 +511,21 @@ scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op
|
||||||
const char operation[] = "GetCACert";
|
const char operation[] = "GetCACert";
|
||||||
|
|
||||||
/* form complete url */
|
/* form complete url */
|
||||||
int len = strlen(url) + 32 + strlen(operation) + 1;
|
len = strlen(url) + 32 + strlen(operation) + 1;
|
||||||
|
|
||||||
complete_url = malloc(len);
|
complete_url = malloc(len);
|
||||||
snprintf(complete_url, len, "%s?operation=%s&message=CAIdentifier"
|
snprintf(complete_url, len, "%s?operation=%s&message=CAIdentifier"
|
||||||
, url, operation);
|
, url, operation);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, TRUE);
|
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
|
||||||
|
FETCH_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, complete_url);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)response);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
|
|
||||||
|
|
||||||
DBG(DBG_CONTROL,
|
|
||||||
DBG_log("sending scep request to '%s'", url)
|
|
||||||
)
|
|
||||||
res = curl_easy_perform(curl);
|
|
||||||
|
|
||||||
if (res == CURLE_OK)
|
|
||||||
{
|
|
||||||
DBG(DBG_CONTROL,
|
|
||||||
DBG_log("received scep response")
|
|
||||||
)
|
|
||||||
DBG(DBG_RAW,
|
|
||||||
DBG_dump_chunk("SCEP response:\n", *response)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plog("failed to fetch scep response from '%s': %s", url, errorbuffer);
|
|
||||||
}
|
|
||||||
curl_slist_free_all(headers);
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
free(complete_url);
|
free(complete_url);
|
||||||
|
return (status == SUCCESS);
|
||||||
return (res == CURLE_OK);
|
|
||||||
#else /* !LIBCURL */
|
|
||||||
plog("scep error: pluto wasn't compiled with libcurl support");
|
|
||||||
return FALSE;
|
|
||||||
#endif /* !LIBCURL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err_t
|
err_t scep_parse_response(chunk_t response, chunk_t transID, contentInfo_t *data,
|
||||||
scep_parse_response(chunk_t response, chunk_t transID, contentInfo_t *data
|
scep_attributes_t *attrs, x509cert_t *signer_cert)
|
||||||
, scep_attributes_t *attrs, x509cert_t *signer_cert)
|
|
||||||
{
|
{
|
||||||
chunk_t attributes;
|
chunk_t attributes;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ extern chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg
|
||||||
, const x509cert_t *signer_cert, int digest_alg
|
, const x509cert_t *signer_cert, int digest_alg
|
||||||
, const RSA_private_key_t *private_key);
|
, const RSA_private_key_t *private_key);
|
||||||
extern bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op
|
extern bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op
|
||||||
, fetch_request_t request_type, chunk_t *response);
|
, bool http_get_request, chunk_t *response);
|
||||||
extern err_t scep_parse_response(chunk_t response, chunk_t transID
|
extern err_t scep_parse_response(chunk_t response, chunk_t transID
|
||||||
, contentInfo_t *data, scep_attributes_t *attrs, x509cert_t *signer_cert);
|
, contentInfo_t *data, scep_attributes_t *attrs, x509cert_t *signer_cert);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
#include "../pluto/pkcs1.h"
|
#include "../pluto/pkcs1.h"
|
||||||
#include "../pluto/pkcs7.h"
|
#include "../pluto/pkcs7.h"
|
||||||
#include "../pluto/certs.h"
|
#include "../pluto/certs.h"
|
||||||
#include "../pluto/fetch.h"
|
|
||||||
#include "../pluto/rnd.h"
|
#include "../pluto/rnd.h"
|
||||||
|
|
||||||
#include "rsakey.h"
|
#include "rsakey.h"
|
||||||
|
@ -355,17 +354,17 @@ int main(int argc, char **argv)
|
||||||
/* symmetric encryption algorithm used by pkcs7, default is 3DES */
|
/* symmetric encryption algorithm used by pkcs7, default is 3DES */
|
||||||
int pkcs7_symmetric_cipher = OID_3DES_EDE_CBC;
|
int pkcs7_symmetric_cipher = OID_3DES_EDE_CBC;
|
||||||
|
|
||||||
/* digest algorithm used by pkcs7, default is MD5 */
|
/* digest algorithm used by pkcs7, default is SHA-1 */
|
||||||
int pkcs7_digest_alg = OID_MD5;
|
int pkcs7_digest_alg = OID_SHA1;
|
||||||
|
|
||||||
/* signature algorithm used by pkcs10, default is MD5 with RSA encryption */
|
/* signature algorithm used by pkcs10, default is SHA-1 with RSA encryption */
|
||||||
int pkcs10_signature_alg = OID_MD5;
|
int pkcs10_signature_alg = OID_SHA1;
|
||||||
|
|
||||||
/* URL of the SCEP-Server */
|
/* URL of the SCEP-Server */
|
||||||
char *scep_url = NULL;
|
char *scep_url = NULL;
|
||||||
|
|
||||||
/* http request method, default is GET */
|
/* http request method, default is GET */
|
||||||
fetch_request_t request_type = FETCH_GET;
|
bool http_get_request = TRUE;
|
||||||
|
|
||||||
/* poll interval time in manual mode in seconds */
|
/* poll interval time in manual mode in seconds */
|
||||||
u_int poll_interval = DEFAULT_POLL_INTERVAL;
|
u_int poll_interval = DEFAULT_POLL_INTERVAL;
|
||||||
|
@ -669,13 +668,13 @@ int main(int argc, char **argv)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'm': /* --method */
|
case 'm': /* --method */
|
||||||
if (strcaseeq("post", optarg))
|
if (strcaseeq("get", optarg))
|
||||||
{
|
{
|
||||||
request_type = FETCH_POST;
|
http_get_request = TRUE;
|
||||||
}
|
}
|
||||||
else if (strcaseeq("get", optarg))
|
else if (strcaseeq("post", optarg))
|
||||||
{
|
{
|
||||||
request_type = FETCH_GET;
|
http_get_request = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -745,7 +744,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/* load plugins, further infrastructure may need it */
|
/* load plugins, further infrastructure may need it */
|
||||||
lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
|
lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
|
||||||
lib->settings->get_str(lib->settings, "scepclient.load", ""));
|
lib->settings->get_str(lib->settings, "scepclient.load", PLUGINS));
|
||||||
print_plugins();
|
print_plugins();
|
||||||
|
|
||||||
init_rnd_pool();
|
init_rnd_pool();
|
||||||
|
@ -1006,8 +1005,8 @@ int main(int argc, char **argv)
|
||||||
exit_scepclient("could not load signature cacert file '%s'", path);
|
exit_scepclient("could not load signature cacert file '%s'", path);
|
||||||
x509_ca_sig = cert.u.x509;
|
x509_ca_sig = cert.u.x509;
|
||||||
|
|
||||||
if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION
|
if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION,
|
||||||
, request_type, &scep_response))
|
http_get_request, &scep_response))
|
||||||
{
|
{
|
||||||
exit_scepclient("did not receive a valid scep response");
|
exit_scepclient("did not receive a valid scep response");
|
||||||
}
|
}
|
||||||
|
@ -1053,8 +1052,8 @@ int main(int argc, char **argv)
|
||||||
, x509_ca_enc, pkcs7_symmetric_cipher
|
, x509_ca_enc, pkcs7_symmetric_cipher
|
||||||
, x509_signer, pkcs7_digest_alg, private_key);
|
, x509_signer, pkcs7_digest_alg, private_key);
|
||||||
|
|
||||||
if (!scep_http_request(scep_url, getCertInitial, SCEP_PKI_OPERATION
|
if (!scep_http_request(scep_url, getCertInitial, SCEP_PKI_OPERATION,
|
||||||
, request_type, &scep_response))
|
http_get_request, &scep_response))
|
||||||
{
|
{
|
||||||
exit_scepclient("did not receive a valid scep response");
|
exit_scepclient("did not receive a valid scep response");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue