return false;
}
+bool RGWFormPost::is_integral()
+{
+ const std::string form_signature = get_part_str(ctrl_parts, "signature");
+
+ for (const auto& kv : s->user->temp_url_keys) {
+ const int temp_url_key_num = kv.first;
+ const string& temp_url_key = kv.second;
+
+ if (temp_url_key.empty()) {
+ continue;
+ }
+
+ SignatureHelper sig_helper;
+ sig_helper.calc(temp_url_key,
+ s->info.request_uri,
+ get_part_str(ctrl_parts, "redirect"),
+ get_part_str(ctrl_parts, "max_file_size", "0"),
+ get_part_str(ctrl_parts, "max_file_count", "0"),
+ get_part_str(ctrl_parts, "expires", "0"));
+
+ const auto local_sig = sig_helper.get_signature();
+
+ ldout(s->cct, 20) << "FormPost signature [" << temp_url_key_num << "]"
+ << " (calculated): " << local_sig << dendl;
+
+ if (sig_helper.is_equal_to(form_signature)) {
+ return true;
+ } else {
+ ldout(s->cct, 5) << "FormPost's signature mismatch: "
+ << local_sig << " != " << form_signature << dendl;
+ }
+ }
+
+ return false;
+}
+
int RGWFormPost::get_params()
{
/* The parentt class extracts boundary info from the Content-Type. */
return -EACCES;
}
+ if (! is_integral()) {
+ err_msg = "FormPost: Invalid Signature";
+ return -EACCES;
+ }
+
return ! current_data_part ? -EINVAL : 0;
}
#include "rgw_rest.h"
#include "rgw_swift_auth.h"
+#include <boost/utility/string_ref.hpp>
+
class RGWGetObj_ObjStore_SWIFT : public RGWGetObj_ObjStore {
int custom_http_ret = 0;
public:
class RGWFormPost : public RGWPostObj_ObjStore {
std::string get_current_filename() const override;
bool is_next_file_to_upload() override;
+ bool is_integral();
static bool is_expired(const std::string& expires);
parts_collection_t ctrl_parts;
std::string prefix;
bool stream_done = false;
+ class SignatureHelper;
public:
RGWFormPost() = default;
~RGWFormPost() = default;
static bool is_formpost_req(req_state* const s);
};
+class RGWFormPost::SignatureHelper
+{
+private:
+ static constexpr uint32_t output_size =
+ CEPH_CRYPTO_HMACSHA1_DIGESTSIZE * 2 + 1;
+
+ unsigned char dest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE]; // 20
+ char dest_str[output_size];
+
+public:
+ SignatureHelper() = default;
+
+ const char* calc(const std::string& key,
+ const boost::string_ref& path_info,
+ const boost::string_ref& redirect,
+ const boost::string_ref& max_file_size,
+ const boost::string_ref& max_file_count,
+ const boost::string_ref& expires) {
+ using ceph::crypto::HMACSHA1;
+ using UCHARPTR = const unsigned char*;
+
+ HMACSHA1 hmac((UCHARPTR) key.data(), key.size());
+
+ hmac.Update((UCHARPTR) path_info.data(), path_info.size());
+ hmac.Update((UCHARPTR) "\n", 1);
+
+ hmac.Update((UCHARPTR) redirect.data(), redirect.size());
+ hmac.Update((UCHARPTR) "\n", 1);
+
+ hmac.Update((UCHARPTR) max_file_size.data(), max_file_size.size());
+ hmac.Update((UCHARPTR) "\n", 1);
+
+ hmac.Update((UCHARPTR) max_file_count.data(), max_file_count.size());
+ hmac.Update((UCHARPTR) "\n", 1);
+
+ hmac.Update((UCHARPTR) expires.data(), expires.size());
+
+ hmac.Final(dest);
+
+ buf_to_hex((UCHARPTR) dest, sizeof(dest), dest_str);
+
+ return dest_str;
+ }
+
+ const char* get_signature() const {
+ return dest_str;
+ }
+
+ bool is_equal_to(const std::string& rhs) const {
+ /* never allow out-of-range exception */
+ if (rhs.size() < (output_size - 1)) {
+ return false;
+ }
+ return rhs.compare(0 /* pos */, output_size, dest_str) == 0;
+ }
+
+}; /* RGWFormPost::SignatureHelper */
+
class RGWSwiftWebsiteHandler {
RGWRados* const store;