diff --git a/src/plugins/apache-httpd/etc/httpd/conf.d/zlcgdm-dav.conf.in b/src/plugins/apache-httpd/etc/httpd/conf.d/zlcgdm-dav.conf.in
index 8d7d471b..062979ec 100644
--- a/src/plugins/apache-httpd/etc/httpd/conf.d/zlcgdm-dav.conf.in
+++ b/src/plugins/apache-httpd/etc/httpd/conf.d/zlcgdm-dav.conf.in
@@ -175,7 +175,9 @@ DiskDMLite /etc/dmlite-disk.conf
# Trusted certificates for TPC connection to remote storage
#DiskSSLCACertificatePath /etc/grid-security/certificates
#DiskSSLCACertificateFile
+ #DiskSSLCARevocationPath /etc/grid-security/certificates
#DiskSSLCARevocationFile
+ #DiskSSLCARevocationCheck chain
# Terminate slow (stuck) transfers if bytes transferred
# in given time window is smaller then configured tresholds
diff --git a/src/plugins/apache-httpd/src/client/htext.h b/src/plugins/apache-httpd/src/client/htext.h
index 1303e77e..fcf33f79 100644
--- a/src/plugins/apache-httpd/src/client/htext.h
+++ b/src/plugins/apache-httpd/src/client/htext.h
@@ -44,6 +44,7 @@ typedef enum
HTEXTOP_CAPATH, /* CA Path */
HTEXTOP_CAFILE, /* CA File */
+ HTEXTOP_CRLPATH, /* CRL Path */
HTEXTOP_CRLFILE, /* CRL File */
HTEXTOP_VERIFYPEER, /* Validate (!0) or not (0) the remote certificate */
diff --git a/src/plugins/apache-httpd/src/client/htext_api.c b/src/plugins/apache-httpd/src/client/htext_api.c
index 1c3df75c..09a3fa3f 100644
--- a/src/plugins/apache-httpd/src/client/htext_api.c
+++ b/src/plugins/apache-httpd/src/client/htext_api.c
@@ -72,6 +72,7 @@ static option_entry option_definitions[] = {
{ OT_STRING, (option_value) NULL }, /* HTEXTOP_CAPATH */
{ OT_STRING, (option_value) NULL }, /* HTEXTOP_CAFILE */
+ { OT_STRING, (option_value) NULL }, /* HTEXTOP_CRLPATH */
{ OT_STRING, (option_value) NULL }, /* HTEXTOP_CRLFILE */
{ OT_INT, (option_value) 1 }, /* HTEXTOP_VERIFYPEER */
diff --git a/src/plugins/apache-httpd/src/client/htext_common.c b/src/plugins/apache-httpd/src/client/htext_common.c
index 34a28353..4b7c9dc9 100644
--- a/src/plugins/apache-httpd/src/client/htext_common.c
+++ b/src/plugins/apache-httpd/src/client/htext_common.c
@@ -21,6 +21,7 @@
#define _GNU_SOURCE
#include <ctype.h>
#include <curl/curl.h>
+#include <openssl/ssl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -121,6 +122,32 @@ int htext_error(htext_handle *handle, const char *fmt, ...)
return n;
}
+CURLcode htext_sslctx_callback(CURL *curl, void *ssl_ctx, void *pp)
+{
+ X509_STORE *store = SSL_CTX_get_cert_store((SSL_CTX*)ssl_ctx);
+ htext_chunk *partial = (htext_chunk*) pp;
+ const char *capath = GETSTR(partial->handle, HTEXTOP_CAPATH);
+ const char *crlpath = GETSTR(partial->handle, HTEXTOP_CRLPATH);
+
+ if (!crlpath) return CURLE_OK;
+
+ if (!store) {
+ htext_log(partial->handle, "unable to get SSL storage");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ if (!capath || strcmp(capath, crlpath)) {
+ if (!X509_STORE_load_locations(store, NULL, crlpath)) {
+ htext_log(partial->handle, "unable to load X.509 CRL from %s", crlpath);
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+
+ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+
+ return CURLE_OK;
+}
+
size_t htext_header_callback(void *buffer, size_t size, size_t nmemb, void *st)
{
htext_chunk *partial = (htext_chunk*) st;
diff --git a/src/plugins/apache-httpd/src/client/htext_copy.c b/src/plugins/apache-httpd/src/client/htext_copy.c
index 88c4aacd..36b04f75 100644
--- a/src/plugins/apache-httpd/src/client/htext_copy.c
+++ b/src/plugins/apache-httpd/src/client/htext_copy.c
@@ -203,6 +203,9 @@ void *htext_copy_method(void *h)
curl_easy_setopt(curl, CURLOPT_USERAGENT, GETSTR(handle, HTEXTOP_CLIENTID));
curl_easy_setopt(curl, CURLOPT_CAPATH, GETSTR(handle, HTEXTOP_CAPATH));
curl_easy_setopt(curl, CURLOPT_CAINFO, GETSTR(handle, HTEXTOP_CAFILE));
+ // CURL doesn't provide direct interface for "CRLPATH", use openssl context directly
+ curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, htext_sslctx_callback);
+ curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, &control);
curl_easy_setopt(curl, CURLOPT_CRLFILE, GETSTR(handle, HTEXTOP_CRLFILE));
curl_easy_setopt(curl, CURLOPT_SSLCERT,
GETSTR(handle, HTEXTOP_USERCERTIFICATE));
diff --git a/src/plugins/apache-httpd/src/client/htext_get.c b/src/plugins/apache-httpd/src/client/htext_get.c
index 0fb49bde..310c773b 100644
--- a/src/plugins/apache-httpd/src/client/htext_get.c
+++ b/src/plugins/apache-httpd/src/client/htext_get.c
@@ -51,6 +51,7 @@ static void* htext_get_subthread(void *pp)
GETIO(partial->handle)->write);
curl_easy_setopt(partial->curl, CURLOPT_WRITEDATA, partial->fd);
curl_easy_setopt(partial->curl, CURLOPT_DEBUGDATA, partial);
+ curl_easy_setopt(partial->curl, CURLOPT_SSL_CTX_DATA, partial);
/* Range */
if (partial->nchunks > 1) {
@@ -89,6 +90,8 @@ void *htext_get_method(void *h)
curl_easy_setopt(curl, CURLOPT_USERAGENT, GETSTR(handle, HTEXTOP_CLIENTID));
curl_easy_setopt(curl, CURLOPT_CAPATH, GETSTR(handle, HTEXTOP_CAPATH));
curl_easy_setopt(curl, CURLOPT_CAINFO, GETSTR(handle, HTEXTOP_CAFILE));
+ // CURL doesn't provide direct interface for "CRLPATH", use openssl context directly
+ curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, htext_sslctx_callback);
curl_easy_setopt(curl, CURLOPT_CRLFILE, GETSTR(handle, HTEXTOP_CRLFILE));
curl_easy_setopt(curl, CURLOPT_SSLCERT,
GETSTR(handle, HTEXTOP_USERCERTIFICATE));
@@ -136,6 +139,7 @@ void *htext_get_method(void *h)
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &head);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, head.headers);
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &head);
+ curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, &head);
handle->status = HTEXTS_WAITING;
htext_log(handle, "Asking for the size");
@@ -152,6 +156,12 @@ void *htext_get_method(void *h)
curl_easy_setopt(curl, CURLOPT_URL, head.location);
}
+ /* Explicitly reset pointers to released head data structure */
+ curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL);
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL);
+ curl_easy_setopt(curl, CURLOPT_DEBUGDATA, NULL);
+ curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, NULL);
+
htext_partial_clean(&head);
}
diff --git a/src/plugins/apache-httpd/src/client/htext_private.h b/src/plugins/apache-httpd/src/client/htext_private.h
index 0a406df7..49c6c60a 100644
--- a/src/plugins/apache-httpd/src/client/htext_private.h
+++ b/src/plugins/apache-httpd/src/client/htext_private.h
@@ -187,6 +187,15 @@ int htext_log(htext_handle *handle, const char *fmt, ...);
*/
int htext_error(htext_handle *handle, const char *fmt, ...);
+/**
+ * Called by Curl every time a line of the header needs to be processed
+ * @param curl The CURL handle calling
+ * @param ssl_ctx The SSL library context
+ * @param pp A pointer to a htext_partial structure
+ * @return Continue with SSL connection or return error
+ */
+CURLcode htext_sslctx_callback(CURL *curl, void *ssl_ctx, void *pp);
+
/**
* Called by Curl every time a line of the header needs to be processed
* @param buffer Where the data is
diff --git a/src/plugins/apache-httpd/src/client/htext_put.c b/src/plugins/apache-httpd/src/client/htext_put.c
index 0c3e4c1d..a23f0c0e 100644
--- a/src/plugins/apache-httpd/src/client/htext_put.c
+++ b/src/plugins/apache-httpd/src/client/htext_put.c
@@ -101,6 +101,7 @@ static void* htext_put_subthread(void *pp)
curl_easy_setopt(partial->curl, CURLOPT_READDATA, partial);
curl_easy_setopt(partial->curl, CURLOPT_IOCTLDATA, partial);
curl_easy_setopt(partial->curl, CURLOPT_DEBUGDATA, partial);
+ curl_easy_setopt(partial->curl, CURLOPT_SSL_CTX_DATA, partial);
/* Range (not for last empty PUT) */
if (partial->nchunks > 1 && partial->index >= 0) {
@@ -154,6 +155,8 @@ void *htext_put_method(void *h)
curl_easy_setopt(curl, CURLOPT_USERAGENT, GETSTR(handle, HTEXTOP_CLIENTID));
curl_easy_setopt(curl, CURLOPT_CAPATH, GETSTR(handle, HTEXTOP_CAPATH));
curl_easy_setopt(curl, CURLOPT_CAINFO, GETSTR(handle, HTEXTOP_CAFILE));
+ // CURL doesn't provide direct interface for "CRLPATH", use openssl context directly
+ curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, htext_sslctx_callback);
curl_easy_setopt(curl, CURLOPT_CRLFILE, GETSTR(handle, HTEXTOP_CRLFILE));
curl_easy_setopt(curl, CURLOPT_SSLCERT, GETSTR(handle, HTEXTOP_USERCERTIFICATE));
curl_easy_setopt(curl, CURLOPT_SSLKEY, GETSTR(handle, HTEXTOP_USERPRIVKEY));
diff --git a/src/plugins/apache-httpd/src/mod_lcgdm_disk/copy.c b/src/plugins/apache-httpd/src/mod_lcgdm_disk/copy.c
index dd586da6..f3fd2caa 100644
--- a/src/plugins/apache-httpd/src/mod_lcgdm_disk/copy.c
+++ b/src/plugins/apache-httpd/src/mod_lcgdm_disk/copy.c
@@ -465,8 +465,14 @@ static dav_error *dav_disk_generic_copy(const dav_resource* res, const char* upr
if (d_conf->capath) {
htext_setopt(handle, HTEXTOP_CAPATH, d_conf->capath);
}
- if (d_conf->crlfile) {
- htext_setopt(handle, HTEXTOP_CRLFILE, d_conf->crlfile);
+ if (d_conf->crlcheck && strcmp("chain", d_conf->crlcheck))
+ {
+ if (d_conf->crlpath) {
+ htext_setopt(handle, HTEXTOP_CRLPATH, d_conf->crlpath);
+ }
+ if (d_conf->crlfile) {
+ htext_setopt(handle, HTEXTOP_CRLFILE, d_conf->crlfile);
+ }
}
if (uproxy || d_conf->capath || d_conf->cafile) {
htext_setopt(handle, HTEXTOP_VERIFYPEER, 1);
diff --git a/src/plugins/apache-httpd/src/mod_lcgdm_disk/mod_lcgdm_disk.c b/src/plugins/apache-httpd/src/mod_lcgdm_disk/mod_lcgdm_disk.c
index 9529fbc8..2b875028 100644
--- a/src/plugins/apache-httpd/src/mod_lcgdm_disk/mod_lcgdm_disk.c
+++ b/src/plugins/apache-httpd/src/mod_lcgdm_disk/mod_lcgdm_disk.c
@@ -84,7 +84,9 @@ static void *dav_disk_create_dir_config(apr_pool_t *p, char *dir)
conf->proxy_cache = "/var/proxycache";
conf->capath = "/etc/grid-security/certificates";
conf->cafile = NULL;
+ conf->crlpath = "/etc/grid-security/certificates";
conf->crlfile = NULL;
+ conf->crlcheck = "chain";
conf->low_speed_time = 2*60;
conf->low_speed_limit = 10*1024;
@@ -261,6 +263,23 @@ static const char *dav_disk_cmd_cafile(cmd_parms *cmd, void *config,
return NULL ;
}
+/**
+ * Set CRLPath with revocated certificates for TPC
+ * @param cmd Lots of information about the configuration contexts (as pool)
+ * @param config A pointer to the directory configuration
+ * @param arg The CRLPath
+ * @return NULL on success. An error string otherwise
+ */
+static const char *dav_disk_cmd_crlpath(cmd_parms *cmd, void *config,
+ const char *arg)
+{
+ (void) cmd;
+
+ dav_disk_dir_conf *conf = (dav_disk_dir_conf*) config;
+ conf->crlpath = (!arg || !strlen(arg)) ? NULL : arg;
+ return NULL ;
+}
+
/**
* Set CRLFile with revocated certificates for TPC
* @param cmd Lots of information about the configuration contexts (as pool)
@@ -278,6 +297,24 @@ static const char *dav_disk_cmd_crlfile(cmd_parms *cmd, void *config,
return NULL ;
}
+/**
+ * Set CRL validation for revocated certificates used by TPC
+ * @param cmd Lots of information about the configuration contexts (as pool)
+ * @param config A pointer to the directory configuration
+ * @param arg The configuration
+ * @return NULL on success. An error string otherwise
+ */
+static const char *dav_disk_cmd_crlcheck(cmd_parms *cmd, void *config,
+ const char *arg)
+{
+ if (strcmp("none", arg) && strcmp("chain", arg))
+ return apr_psprintf(cmd->pool, "%s is not a recognised value", arg);
+
+ dav_disk_dir_conf *conf = (dav_disk_dir_conf*) config;
+ conf->crlcheck = arg;
+ return NULL ;
+}
+
/** Command list (configuration parameters) */
static const command_rec dav_disk_cmds[] = {
AP_INIT_TAKE1 ("DiskDMLite", dav_disk_cmd_dmlite, NULL, ACCESS_CONF | RSRC_CONF,
@@ -294,10 +331,12 @@ static const command_rec dav_disk_cmds[] = {
"SSL CA Certificate path ('/path/to/dir' - contains PEM encoded files)"),
AP_INIT_TAKE1 ("DiskSSLCACertificateFile", dav_disk_cmd_cafile, NULL, ACCESS_CONF,
"SSL CA Certificate file ('/path/to/file' - PEM encoded)"),
- //AP_INIT_TAKE1 ("DiskSSLCARevocationPath", dav_disk_cmd_crlpath, NULL, ACCESS_CONF,
- // "SSL CA Certificate Revocation List (CRL) path ('/path/to/dir' - contains PEM encoded files)"),
+ AP_INIT_TAKE1 ("DiskSSLCARevocationPath", dav_disk_cmd_crlpath, NULL, ACCESS_CONF,
+ "SSL CA Certificate Revocation List (CRL) path ('/path/to/dir' - contains PEM encoded files)"),
AP_INIT_TAKE1 ("DiskSSLCARevocationFile", dav_disk_cmd_crlfile, NULL, ACCESS_CONF,
"SSL CA Certificate Revocation List (CRL) file ('/path/to/file' - PEM encoded)"),
+ AP_INIT_TAKE1 ("DiskSSLCARevocationCheck", dav_disk_cmd_crlcheck, NULL, ACCESS_CONF,
+ "SSL CA Certificate Revocation List checkging (chain|none)"),
AP_INIT_TAKE1 ("DiskLowSpeedTime", ap_set_int_slot,
(void *)APR_OFFSETOF(dav_disk_dir_conf, low_speed_time), ACCESS_CONF,
"Low speed limit time period in seconds"),
diff --git a/src/plugins/apache-httpd/src/mod_lcgdm_disk/mod_lcgdm_disk.h b/src/plugins/apache-httpd/src/mod_lcgdm_disk/mod_lcgdm_disk.h
index 42164d74..f2bdaf57 100644
--- a/src/plugins/apache-httpd/src/mod_lcgdm_disk/mod_lcgdm_disk.h
+++ b/src/plugins/apache-httpd/src/mod_lcgdm_disk/mod_lcgdm_disk.h
@@ -60,7 +60,9 @@ struct dav_disk_dir_conf
const char *delegation_service;
const char *capath;
const char *cafile;
+ const char *crlpath;
const char *crlfile;
+ const char *crlcheck;
int low_speed_time;
int low_speed_limit;
};
diff --git a/src/puppet/dmlite/manifests/dav.pp b/src/puppet/dmlite/manifests/dav.pp
index 0518bbe5..9ff82e08 100644
--- a/src/puppet/dmlite/manifests/dav.pp
+++ b/src/puppet/dmlite/manifests/dav.pp
@@ -16,6 +16,8 @@ class dmlite::dav (
Stdlib::Unixpath $ssl_cert = $dmlite::dav::params::ssl_cert,
Stdlib::Unixpath $ssl_key = $dmlite::dav::params::ssl_key,
Stdlib::Unixpath $ssl_capath = $dmlite::dav::params::ssl_capath,
+ Stdlib::Unixpath $ssl_tpc_capath = $dmlite::dav::params::ssl_tpc_capath,
+ Optional[Stdlib::Unixpath] $ssl_tpc_crlpath = $dmlite::dav::params::ssl_tpc_crlpath,
String $ssl_options = $dmlite::dav::params::ssl_options,
String $log_error = $dmlite::dav::params::log_error,
String $log_transfer = $dmlite::dav::params::log_transfer,
diff --git a/src/puppet/dmlite/manifests/dav/config.pp b/src/puppet/dmlite/manifests/dav/config.pp
index 1d6eb596..94adea76 100644
--- a/src/puppet/dmlite/manifests/dav/config.pp
+++ b/src/puppet/dmlite/manifests/dav/config.pp
@@ -18,6 +18,8 @@ class dmlite::dav::config (
$ssl_options = $dmlite::dav::ssl_options,
$ssl_protocol = $dmlite::dav::ssl_protocol,
$ssl_ciphersuite = $dmlite::dav::ssl_ciphersuite,
+ $ssl_tpc_capath = $dmlite::dav::ssl_tpc_capath,
+ $ssl_tpc_crlpath = $dmlite::dav::ssl_tpc_crlpath,
$log_error = $dmlite::dav::log_error,
$log_transfer = $dmlite::dav::log_transfer,
$log_level = $dmlite::dav::log_level,
diff --git a/src/puppet/dmlite/manifests/dav/params.pp b/src/puppet/dmlite/manifests/dav/params.pp
index f2dcee6e..15b3c449 100644
--- a/src/puppet/dmlite/manifests/dav/params.pp
+++ b/src/puppet/dmlite/manifests/dav/params.pp
@@ -20,6 +20,8 @@ class dmlite::dav::params (
$ssl_protocol = hiera('dmlite::dav::params::ssl_protocol', 'all -SSLv2 -SSLv3')
$ssl_ciphersuite = hiera('dmlite::dav::params::ssl_ciphersuite', 'RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5:!RC4')
$ssl_options = hiera('dmlite::dav::params::ssl_options','+StdEnvVars')
+ $ssl_tpc_capath = hiera('dmlite::dav::params::ssl_tpc_capath', '/etc/grid-security/certificates')
+ $ssl_tpc_crlpath = hiera('dmlite::dav::params::ssl_tpc_crlpath', '/etc/grid-security/certificates')
$log_error = hiera('dmlite::dav::params::log_error', 'logs/ssl_error_log')
$log_transfer = hiera('dmlite::dav::params::log_transfer', 'logs/ssl_access_log')
$log_level = hiera('dmlite::dav::params::log_level','warn')
diff --git a/src/puppet/dmlite/templates/dav/zlcgdm-dav.conf b/src/puppet/dmlite/templates/dav/zlcgdm-dav.conf
index 65d8e165..64565ccf 100644
--- a/src/puppet/dmlite/templates/dav/zlcgdm-dav.conf
+++ b/src/puppet/dmlite/templates/dav/zlcgdm-dav.conf
@@ -206,14 +206,23 @@ DiskDMLite <%= @dmlite_disk_conf %>
# CGI, it allways has to be DocumentRoot/../proxycache
DiskProxyCache /var/www/proxycache
- <% if @dav_http_port.to_i != 80 or @dav_https_port.to_i != 443 -%>
+<% if @dav_http_port.to_i != 80 or @dav_https_port.to_i != 443 -%>
NSRedirectPort <%= @dav_http_port %> <%= @dav_https_port %>
- <% end -%>
+<% end -%>
# Trusted certificates for TPC connection to remote storage
+<% if @ssl_tpc_capath -%>
+ DiskSSLCACertificatePath <%= @ssl_tpc_capath %>
+<% else -%>
#DiskSSLCACertificatePath /etc/grid-security/certificates
- #DiskSSLCACertificateFile
- #DiskSSLCARevocationFile
+<% end -%>
+<% if @ssl_tpc_crlpath -%>
+ DiskSSLCARevocationPath <%= @ssl_tpc_crlpath %>
+ DiskSSLCARevocationCheck chain
+<% else -%>
+ #DiskSSLCARevocationPath /etc/grid-security/certificates
+ DiskSSLCARevocationCheck none
+<% end -%>
# Terminate slow (stuck) transfers if bytes transferred
# in given time window is smaller then configured tresholds