Skip to content

Commit

Permalink
Added resigning of AWS requests
Browse files Browse the repository at this point in the history
  • Loading branch information
durner committed Mar 19, 2024
1 parent e7b3933 commit d80f01c
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 5 deletions.
2 changes: 2 additions & 0 deletions include/cloud/aws.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ class AWS : public Provider {

/// Creates the generic http request and signs it
[[nodiscard]] std::unique_ptr<utils::DataVector<uint8_t>> buildRequest(network::HttpRequest& request, const uint8_t* bodyData = nullptr, uint64_t bodyLength = 0, bool initHeaders = true) const;
/// Reigns header
[[nodiscard]] std::unique_ptr<utils::DataVector<uint8_t>> resignRequest(const utils::DataVector<uint8_t>& data, const uint8_t* bodyData = nullptr, uint64_t bodyLength = 0) const override;
/// Builds the http request for downloading a blob or listing the directory
[[nodiscard]] std::unique_ptr<utils::DataVector<uint8_t>> getRequest(const std::string& filePath, const std::pair<uint64_t, uint64_t>& range) const override;
/// Builds the http request for putting objects without the object data itself
Expand Down
6 changes: 4 additions & 2 deletions include/cloud/provider.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once
#include <memory>
#include <vector>
#include <string>
#include <string_view>
#include <vector>
//---------------------------------------------------------------------------
// AnyBlob - Universal Cloud Object Storage Library
// Dominik Durner, 2021
Expand Down Expand Up @@ -32,7 +32,7 @@ class Provider {
/// The remote prefixes count
static constexpr unsigned remoteFileCount = 8;
/// The remote prefixes
static constexpr std::string_view remoteFile[] = { "http://", "https://", "s3://", "azure://", "gcp://", "oci://", "ibm://", "minio://"};
static constexpr std::string_view remoteFile[] = {"http://", "https://", "s3://", "azure://", "gcp://", "oci://", "ibm://", "minio://"};
/// Are we currently testing the provdiers
static bool testEnviornment;

Expand Down Expand Up @@ -109,6 +109,8 @@ class Provider {
[[nodiscard]] virtual std::unique_ptr<utils::DataVector<uint8_t>> completeMultiPartRequest(const std::string& /*filePath*/, std::string_view /*uploadId*/, const std::vector<std::string>& /*etags*/, std::string& /*eTagsContent*/) const;
/// Supports resigning?
[[nodiscard]] virtual bool supportsResigning() const { return false; }
/// Reigns header
[[nodiscard]] virtual std::unique_ptr<utils::DataVector<uint8_t>> resignRequest(const utils::DataVector<uint8_t>& data, const uint8_t* bodyData = nullptr, uint64_t bodyLength = 0) const;

/// The destructor
virtual ~Provider() noexcept = default;
Expand Down
19 changes: 17 additions & 2 deletions src/cloud/aws.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <iomanip>
#include <sstream>
#include <string>
#include <string_view>
//---------------------------------------------------------------------------
// AnyBlob - Universal Cloud Object Storage Library
// Dominik Durner, 2021
Expand Down Expand Up @@ -308,6 +309,22 @@ void AWS::initResolver(network::TaskedSendReceiver& sendReceiver)
}
}
//---------------------------------------------------------------------------
unique_ptr<utils::DataVector<uint8_t>> AWS::resignRequest(const utils::DataVector<uint8_t>& data, const uint8_t* bodyData, uint64_t bodyLength) const
// Resigns the request
{
if (!validKeys() || (_settings.zonal && !validSession()))
return nullptr;

auto header = network::HttpRequest::deserialize(string_view(reinterpret_cast<const char*>(data.cdata()), data.size()));
for (auto it = header.headers.begin(); it != header.headers.end();) {
if (it->first != "Range" && it->first != "Content-Length")
it = header.headers.erase(it);
else
it++;
}
return buildRequest(header, bodyData, bodyLength);
}
//---------------------------------------------------------------------------
unique_ptr<utils::DataVector<uint8_t>> AWS::buildRequest(network::HttpRequest& request, const uint8_t* bodyData, uint64_t bodyLength, bool initHeaders) const
// Creates and signs the request
{
Expand Down Expand Up @@ -386,7 +403,6 @@ unique_ptr<utils::DataVector<uint8_t>> AWS::putRequestGeneric(const string& file
}

auto bodyLength = object.size();
request.headers.emplace("Host", getAddress());
request.headers.emplace("Content-Length", to_string(bodyLength));

return buildRequest(request, bodyData, bodyLength);
Expand Down Expand Up @@ -432,7 +448,6 @@ unique_ptr<utils::DataVector<uint8_t>> AWS::createMultiPartRequest(const string&
else
request.path = "/" + _settings.bucket + "/" + filePath;
request.queries.emplace("uploads", "");
request.headers.emplace("Host", getAddress());

return buildRequest(request);
}
Expand Down
6 changes: 6 additions & 0 deletions src/cloud/provider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ unique_ptr<utils::DataVector<uint8_t>> Provider::completeMultiPartRequest(const
return nullptr;
}
//---------------------------------------------------------------------------
unique_ptr<utils::DataVector<uint8_t>> Provider::resignRequest(const utils::DataVector<uint8_t>& /*data*/, const uint8_t* /*bodyData*/, uint64_t /*bodyLength*/) const
// Resigned header
{
return nullptr;
}
//---------------------------------------------------------------------------
network::Config Provider::getConfig(network::TaskedSendReceiver& sendReceiver)
// Uses the send receiver to get instance configs
{
Expand Down
3 changes: 2 additions & 1 deletion src/network/http_request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ HttpRequest HttpRequest::deserialize(string_view data)
key = query.substr(0, keyPos);
value = query.substr(keyPos + 1);
}
request.queries.emplace(key, value);
if (key.size() > 0)
request.queries.emplace(key, value);
if (queryPos == queries.npos)
break;
queries = queries.substr(queryPos + 1);
Expand Down
6 changes: 6 additions & 0 deletions test/unit/cloud/aws_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,25 @@ class AWSTester {
resultString += aws.fakeAMZTimestamp;
resultString += "\r\nx-amz-request-payer: requester\r\nx-amz-security-token: ABC\r\n\r\n";
REQUIRE(string_view(reinterpret_cast<char*>(dv->data()), dv->size()) == resultString);
auto dvResigned = aws.resignRequest(*dv.get());
REQUIRE(string_view(reinterpret_cast<char*>(dvResigned->data()), dvResigned->size()) == resultString);

utils::DataVector<uint8_t> putData(10);
dv = aws.putRequest("a/b/c.d", string_view(reinterpret_cast<const char*>(putData.data()), putData.size()));
resultString = "PUT /a/b/c.d? HTTP/1.1\r\nAuthorization: AWS4-HMAC-SHA256 Credential=ABC/21000101/test/s3/aws4_request, SignedHeaders=content-length;content-md5;host;x-amz-content-sha256;x-amz-date;x-amz-request-payer;x-amz-security-token, Signature=8b1d89369e758299ed4fa88bdb34416b727f9d002bd4fb1a17c6e657d70f3e66\r\nContent-Length: 10\r\nContent-MD5: pjyQzDaErYsKIXamqP6QBQ==\r\nHost: test.s3.test.amazonaws.com\r\nx-amz-content-sha256: 01d448afd928065458cf670b60f5a594d735af0172c8d67f22a81680132681ca\r\nx-amz-date: ";
resultString += aws.fakeAMZTimestamp;
resultString += "\r\nx-amz-request-payer: requester\r\nx-amz-security-token: ABC\r\n\r\n";
REQUIRE(string_view(reinterpret_cast<char*>(dv->data()), dv->size()) == resultString);
dvResigned = aws.resignRequest(*dv.get(), putData.cdata(), putData.size());
REQUIRE(string_view(reinterpret_cast<char*>(dvResigned->data()), dvResigned->size()) == resultString);

dv = aws.deleteRequest("a/b/c.d");
resultString = "DELETE /a/b/c.d? HTTP/1.1\r\nAuthorization: AWS4-HMAC-SHA256 Credential=ABC/21000101/test/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-request-payer;x-amz-security-token, Signature=2240aba5140727498bd7bcea6f58e68a4c91ef2532b3273834a8d54983ae9319\r\nHost: test.s3.test.amazonaws.com\r\nx-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\r\nx-amz-date: ";
resultString += aws.fakeAMZTimestamp;
resultString += "\r\nx-amz-request-payer: requester\r\nx-amz-security-token: ABC\r\n\r\n";
REQUIRE(string_view(reinterpret_cast<char*>(dv->data()), dv->size()) == resultString);
dvResigned = aws.resignRequest(*dv.get());
REQUIRE(string_view(reinterpret_cast<char*>(dvResigned->data()), dvResigned->size()) == resultString);

auto vec = AWSInstance::getInstanceDetails();
REQUIRE(vec.size() > 0);
Expand Down

0 comments on commit d80f01c

Please sign in to comment.