Blob Blame History Raw
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