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