Alejandro Alvarez Ayllon 8133b8a
commit 8ee578131b0ce334c0c5bd6f5a2bd96097875514
Alejandro Alvarez Ayllon 8133b8a
Author: Alejandro Alvarez Ayllon <alejandro.alvarez.ayllon@cern.ch>
Alejandro Alvarez Ayllon 8133b8a
Date:   Mon Nov 17 10:01:38 2014 +0100
Alejandro Alvarez Ayllon 8133b8a
Alejandro Alvarez Ayllon 8133b8a
    DMC-553: Accept only turls that have been requested
Alejandro Alvarez Ayllon 8133b8a
Alejandro Alvarez Ayllon 8133b8a
diff --git a/src/plugins/srm/gfal_srm_getput.c b/src/plugins/srm/gfal_srm_getput.c
Alejandro Alvarez Ayllon 8133b8a
index 94f5904..aaf8f19 100644
Alejandro Alvarez Ayllon 8133b8a
--- a/src/plugins/srm/gfal_srm_getput.c
Alejandro Alvarez Ayllon 8133b8a
+++ b/src/plugins/srm/gfal_srm_getput.c
Alejandro Alvarez Ayllon 8133b8a
@@ -26,6 +26,61 @@
Alejandro Alvarez Ayllon 8133b8a
 #include "gfal_srm_endpoint.h"
Alejandro Alvarez Ayllon 8133b8a
 
Alejandro Alvarez Ayllon 8133b8a
 
Alejandro Alvarez Ayllon 8133b8a
+// Make sure the TURL returned by the endpoint is one of the requested protocols
Alejandro Alvarez Ayllon 8133b8a
+static int validate_turls(int n_results, gfal_srm_result** resu,
Alejandro Alvarez Ayllon 8133b8a
+        gfal_srm_params_t params, GError** tmp_err)
Alejandro Alvarez Ayllon 8133b8a
+{
Alejandro Alvarez Ayllon 8133b8a
+    int failed = 0;
Alejandro Alvarez Ayllon 8133b8a
+    int n_protocols = g_strv_length(params->protocols);
Alejandro Alvarez Ayllon 8133b8a
+    int i, j;
Alejandro Alvarez Ayllon 8133b8a
+
Alejandro Alvarez Ayllon 8133b8a
+    for (i = 0; i < n_results && !failed; ++i) {
Alejandro Alvarez Ayllon 8133b8a
+        const char* turl = (*resu)[i].turl;
Alejandro Alvarez Ayllon 8133b8a
+
Alejandro Alvarez Ayllon 8133b8a
+        // Never ever accept file, even if it was asked for
Alejandro Alvarez Ayllon 8133b8a
+        if (strncmp("file:", turl, 5) == 0) {
Alejandro Alvarez Ayllon 8133b8a
+            failed = -1;
Alejandro Alvarez Ayllon 8133b8a
+            gfal2_set_error(tmp_err, gfal2_get_plugin_srm_quark(), EBADMSG, __func__,
Alejandro Alvarez Ayllon 8133b8a
+                    "file:// is not a valid turl");
Alejandro Alvarez Ayllon 8133b8a
+            break;
Alejandro Alvarez Ayllon 8133b8a
+        }
Alejandro Alvarez Ayllon 8133b8a
+        else if (turl[0] == '/') {
Alejandro Alvarez Ayllon 8133b8a
+            failed = -1;
Alejandro Alvarez Ayllon 8133b8a
+            gfal2_set_error(tmp_err, gfal2_get_plugin_srm_quark(), EBADMSG, __func__,
Alejandro Alvarez Ayllon 8133b8a
+                    "A turl can not start with /");
Alejandro Alvarez Ayllon 8133b8a
+            break;
Alejandro Alvarez Ayllon 8133b8a
+        }
Alejandro Alvarez Ayllon 8133b8a
+
Alejandro Alvarez Ayllon 8133b8a
+        // If error is set, skip the check
Alejandro Alvarez Ayllon 8133b8a
+        if ((*resu)[i].err_code != 0)
Alejandro Alvarez Ayllon 8133b8a
+            continue;
Alejandro Alvarez Ayllon 8133b8a
+
Alejandro Alvarez Ayllon 8133b8a
+        // Check the turl protocol is in the request list
Alejandro Alvarez Ayllon 8133b8a
+        int matching_protocol = 0;
Alejandro Alvarez Ayllon 8133b8a
+        for (j = 0; j < n_protocols; ++j) {
Alejandro Alvarez Ayllon 8133b8a
+            size_t proto_len = strlen(params->protocols[j]);
Alejandro Alvarez Ayllon 8133b8a
+            if (strncmp(params->protocols[j], turl, proto_len) == 0 && turl[proto_len] == ':') {
Alejandro Alvarez Ayllon 8133b8a
+                matching_protocol = 1;
Alejandro Alvarez Ayllon 8133b8a
+                break;
Alejandro Alvarez Ayllon 8133b8a
+            }
Alejandro Alvarez Ayllon 8133b8a
+        }
Alejandro Alvarez Ayllon 8133b8a
+
Alejandro Alvarez Ayllon 8133b8a
+        // If no matching protocol, fail already
Alejandro Alvarez Ayllon 8133b8a
+        if (!matching_protocol) {
Alejandro Alvarez Ayllon 8133b8a
+            failed = -1;
Alejandro Alvarez Ayllon 8133b8a
+            gfal2_set_error(tmp_err, gfal2_get_plugin_srm_quark(), EBADMSG, __func__,
Alejandro Alvarez Ayllon 8133b8a
+                    "The SRM endpoint returned a protocol that wasn't requested: %s");
Alejandro Alvarez Ayllon 8133b8a
+        }
Alejandro Alvarez Ayllon 8133b8a
+    }
Alejandro Alvarez Ayllon 8133b8a
+    // Didn't match, so free and set an error
Alejandro Alvarez Ayllon 8133b8a
+    if (failed) {
Alejandro Alvarez Ayllon 8133b8a
+        free(*resu);
Alejandro Alvarez Ayllon 8133b8a
+        *resu = NULL;
Alejandro Alvarez Ayllon 8133b8a
+    }
Alejandro Alvarez Ayllon 8133b8a
+    return failed;
Alejandro Alvarez Ayllon 8133b8a
+}
Alejandro Alvarez Ayllon 8133b8a
+
Alejandro Alvarez Ayllon 8133b8a
+
Alejandro Alvarez Ayllon 8133b8a
 static int gfal_srm_convert_filestatuses_to_srm_result(struct srmv2_pinfilestatus* statuses, char* reqtoken, int n, gfal_srm_result** resu, GError** err){
Alejandro Alvarez Ayllon 8133b8a
 	g_return_val_err_if_fail(statuses && n && resu, -1, err, "[gfal_srm_convert_filestatuses_to_srm_result] args invalids");
Alejandro Alvarez Ayllon 8133b8a
 	*resu = calloc(n, sizeof(gfal_srm_result));
Alejandro Alvarez Ayllon 8133b8a
@@ -167,8 +222,16 @@ static int gfal_srm_mTURLS_internal(gfal_srmv2_opt* opts, gfal_srm_params_t para
Alejandro Alvarez Ayllon 8133b8a
             ret = gfal_srm_putTURLS_srmv2_internal(context, opts, params, surls, resu, &tmp_err);
Alejandro Alvarez Ayllon 8133b8a
     }
Alejandro Alvarez Ayllon 8133b8a
 
Alejandro Alvarez Ayllon 8133b8a
-    if (ret < 0)
Alejandro Alvarez Ayllon 8133b8a
+    if (ret < 0) {
Alejandro Alvarez Ayllon 8133b8a
         gfal2_propagate_prefixed_error(err, tmp_err, __func__);
Alejandro Alvarez Ayllon 8133b8a
+    }
Alejandro Alvarez Ayllon 8133b8a
+    else {
Alejandro Alvarez Ayllon 8133b8a
+        int n_results = g_strv_length(surls);
Alejandro Alvarez Ayllon 8133b8a
+        if (validate_turls(n_results, resu, params, &tmp_err)) {
Alejandro Alvarez Ayllon 8133b8a
+            gfal2_propagate_prefixed_error(err, tmp_err, __func__);
Alejandro Alvarez Ayllon 8133b8a
+            ret = -1;
Alejandro Alvarez Ayllon 8133b8a
+        }
Alejandro Alvarez Ayllon 8133b8a
+    }
Alejandro Alvarez Ayllon 8133b8a
 
Alejandro Alvarez Ayllon 8133b8a
     return ret;
Alejandro Alvarez Ayllon 8133b8a
 }
Alejandro Alvarez Ayllon 8133b8a
@@ -232,9 +295,6 @@ int gfal_srm_getTURL_checksum(plugin_handle ch, const char* surl, char* buff_tur
Alejandro Alvarez Ayllon 8133b8a
     G_RETURN_ERR(ret, tmp_err, err);
Alejandro Alvarez Ayllon 8133b8a
 }
Alejandro Alvarez Ayllon 8133b8a
 
Alejandro Alvarez Ayllon 8133b8a
-
Alejandro Alvarez Ayllon 8133b8a
-
Alejandro Alvarez Ayllon 8133b8a
-
Alejandro Alvarez Ayllon 8133b8a
 //  execute a get for thirdparty transfer turl
Alejandro Alvarez Ayllon 8133b8a
 int gfal_srm_get_rd3_turl(plugin_handle ch, gfalt_params_t p, const char* surl,
Alejandro Alvarez Ayllon 8133b8a
         char* buff_turl, int size_turl,