#include <boost/utility/string_view.hpp>
#include <boost/container/static_vector.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string.hpp>
#include "rgw_swift_auth.h"
#include "rgw_rest.h"
}; /* TempURLEngine::SignatureHelper */
+class TempURLEngine::PrefixableSignatureHelper
+ : private TempURLEngine::SignatureHelper {
+ using base_t = SignatureHelper;
+
+ const boost::string_view decoded_uri;
+ const boost::string_view object_name;
+ boost::string_view no_obj_uri;
+
+ const boost::optional<const std::string&> prefix;
+
+public:
+ PrefixableSignatureHelper(const std::string& decoded_uri,
+ const std::string& object_name,
+ const boost::optional<const std::string&> prefix)
+ : decoded_uri(decoded_uri),
+ object_name(object_name),
+ prefix(prefix) {
+ /* Transform: v1/acct/cont/obj - > v1/acct/cont/ */
+ no_obj_uri = \
+ decoded_uri.substr(0, decoded_uri.length() - object_name.length());
+ }
+
+ const char* calc(const std::string& key,
+ const boost::string_view& method,
+ const boost::string_view& path,
+ const std::string& expires) {
+ if (!prefix) {
+ return base_t::calc(key, method, path, expires);
+ } else {
+ const auto prefixed_path = \
+ string_cat_reserve("prefix:", no_obj_uri, *prefix);
+ return base_t::calc(key, method, prefixed_path, expires);
+ }
+ }
+
+ bool is_equal_to(const std::string& rhs) const {
+ bool is_auth_ok = base_t::is_equal_to(rhs);
+
+ if (prefix && is_auth_ok) {
+ const auto prefix_uri = string_cat_reserve(no_obj_uri, *prefix);
+ is_auth_ok = boost::algorithm::starts_with(decoded_uri, prefix_uri);
+ }
+
+ return is_auth_ok;
+ }
+}; /* TempURLEngine::PrefixableSignatureHelper */
+
TempURLEngine::result_t
TempURLEngine::authenticate(const req_state* const s) const
{
return result_t::deny();
}
- const string& temp_url_sig = s->info.args.get("temp_url_sig");
- const string& temp_url_expires = s->info.args.get("temp_url_expires");
+ /* NOTE(rzarzynski): RGWHTTPArgs::get(), in contrast to RGWEnv::get(),
+ * never returns nullptr. If the requested parameter is absent, we will
+ * get the empty string. */
+ const std::string& temp_url_sig = s->info.args.get("temp_url_sig");
+ const std::string& temp_url_expires = s->info.args.get("temp_url_expires");
if (temp_url_sig.empty() || temp_url_expires.empty()) {
return result_t::deny();
}
+ /* Though, for prefixed tempurls we need to differentiate between empty
+ * prefix and lack of prefix. Empty prefix means allowance for whole
+ * container. */
+ const boost::optional<const std::string&> temp_url_prefix = \
+ s->info.args.get_optional("temp_url_prefix");
+
RGWUserInfo owner_info;
try {
get_owner_info(s, owner_info);
}
/* Need to try each combination of keys, allowed path and methods. */
- SignatureHelper sig_helper;
+ PrefixableSignatureHelper sig_helper {
+ s->decoded_uri,
+ s->object.name,
+ temp_url_prefix
+ };
+
for (const auto& kv : owner_info.temp_url_keys) {
const int temp_url_key_num = kv.first;
const string& temp_url_key = kv.second;