commit 8ee578131b0ce334c0c5bd6f5a2bd96097875514 Author: Alejandro Alvarez Ayllon 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,