Skip to content

Commit

Permalink
S3Express CreateSession Allowlist Headers (#492)
Browse files Browse the repository at this point in the history
  • Loading branch information
waahm7 authored Jan 27, 2025
1 parent 8feda6e commit aef075b
Show file tree
Hide file tree
Showing 19 changed files with 327 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ concurrency:
cancel-in-progress: true

env:
BUILDER_VERSION: v0.9.72
BUILDER_VERSION: v0.9.74
BUILDER_SOURCE: releases
BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net
PACKAGE_NAME: aws-c-s3
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:


env:
BUILDER_VERSION: v0.9.72
BUILDER_VERSION: v0.9.74
BUILDER_SOURCE: releases
BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net
PACKAGE_NAME: aws-c-s3
Expand All @@ -30,4 +30,4 @@ jobs:
run: |
python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')"
chmod a+x builder
./builder build -p ${{ env.PACKAGE_NAME }} --compiler=gcc-12 --cmake-extra=-DASSERT_LOCK_HELD=ON --coverage --coverage-exclude=source/s3_copy_object.c
./builder build -p ${{ env.PACKAGE_NAME }} --compiler=gcc --cmake-extra=-DASSERT_LOCK_HELD=ON --coverage --coverage-exclude=source/s3_copy_object.c
6 changes: 6 additions & 0 deletions include/aws/s3/private/s3_request_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ extern const size_t g_s3_complete_multipart_upload_excluded_headers_count;
AWS_S3_API
extern const struct aws_byte_cursor g_s3_abort_multipart_upload_excluded_headers[];

AWS_S3_API
extern const size_t g_s3_create_session_allowed_headers_count;

AWS_S3_API
extern const struct aws_byte_cursor g_s3_create_session_allowed_headers[];

AWS_S3_API
extern const size_t g_s3_abort_multipart_upload_excluded_headers_count;

Expand Down
13 changes: 10 additions & 3 deletions include/aws/s3/private/s3express_credentials_provider_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ struct aws_s3express_session {
/* The region and host of the session */
struct aws_string *region;
struct aws_string *host;

struct aws_http_headers *headers;
bool inactive;

/* Only used for mock tests */
Expand Down Expand Up @@ -105,14 +107,19 @@ struct aws_s3express_credentials_provider *aws_s3express_credentials_provider_ne
const struct aws_s3express_credentials_provider_default_options *options);

/**
* Encode the hash key to be [host_value][hash_of_credentials]
* hash_of_credentials is the sha256 of [access_key][secret_access_key]
* Encodes the hash key in the format: [host_value][hash_of_credentials_and_headers]
*
* The hash_of_credentials_and_headers is calculated as follows:
* 1. Concatenate: [access_key][secret_access_key][headers]
* where headers = ",header_name1:header_value1,header_name2:header_value2..."
* 2. Generates SHA256 hash of the concatenated string
*/
AWS_S3_API
struct aws_string *aws_encode_s3express_hash_key_new(
struct aws_allocator *allocator,
const struct aws_credentials *original_credentials,
struct aws_byte_cursor host_value);
struct aws_byte_cursor host_value,
struct aws_http_headers *headers);

AWS_EXTERN_C_END
#endif /* AWS_S3EXPRESS_CREDENTIALS_PROVIDER_IMPL_H */
4 changes: 4 additions & 0 deletions include/aws/s3/s3_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,10 @@ struct aws_s3_client_config {
* If set, client will invoke the factory to get the provider to use, when needed.
*
* If not set, client will create a default S3 Express provider under the hood.
*
* NOTE: THE FOLLOWING BEHAVIOR IS EXPERIMENTAL AND UNSTABLE
* Default S3 Express provider will pass the headers allowed in `g_s3_create_session_allowed_headers` to the
* CreateSession call.
*/
aws_s3express_provider_factory_fn *s3express_provider_override_factory;
void *factory_user_data;
Expand Down
2 changes: 2 additions & 0 deletions include/aws/s3/s3express_credentials_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ struct aws_credentials_properties_s3express {
* If empty, the region of the S3 client will be used.
*/
struct aws_byte_cursor region;

struct aws_http_headers *headers;
};

struct aws_s3express_credentials_provider_vtable {
Expand Down
1 change: 1 addition & 0 deletions source/s3_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,7 @@ struct aws_s3_meta_request *aws_s3_client_make_meta_request(
}

endpoint_host_name = aws_string_new_from_cursor(client->allocator, aws_uri_host_name(&host_uri));
port = aws_uri_port(&host_uri);
aws_uri_clean_up(&host_uri);
}

Expand Down
1 change: 1 addition & 0 deletions source/s3_meta_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ void aws_s3_meta_request_sign_request_default_impl(
context->user_data = user_data;
context->properties.host = aws_byte_cursor_from_string(meta_request->s3express_session_host);
context->properties.region = signing_config.region;
context->properties.headers = aws_http_message_get_headers(meta_request->initial_request_message);

if (signing_config.credentials) {
context->original_credentials = signing_config.credentials;
Expand Down
17 changes: 17 additions & 0 deletions source/s3_request_messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const struct aws_byte_cursor g_s3_create_multipart_upload_excluded_headers[] = {
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-sha1"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-sha256"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("if-none-match"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
};

const size_t g_s3_create_multipart_upload_excluded_headers_count =
Expand Down Expand Up @@ -62,6 +63,7 @@ const struct aws_byte_cursor g_s3_upload_part_excluded_headers[] = {
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-sha1"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-sha256"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("if-none-match"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
};

const size_t g_s3_upload_part_excluded_headers_count = AWS_ARRAY_SIZE(g_s3_upload_part_excluded_headers);
Expand Down Expand Up @@ -96,6 +98,7 @@ const struct aws_byte_cursor g_s3_complete_multipart_upload_excluded_headers[] =
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source-range"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-mp-object-size"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
};

const size_t g_s3_complete_multipart_upload_excluded_headers_count =
Expand Down Expand Up @@ -131,6 +134,7 @@ const struct aws_byte_cursor g_s3_complete_multipart_upload_with_checksum_exclud
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source-range"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-sdk-checksum-algorithm"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-mp-object-size"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
};

const struct aws_byte_cursor g_s3_list_parts_excluded_headers[] = {
Expand Down Expand Up @@ -162,6 +166,7 @@ const struct aws_byte_cursor g_s3_list_parts_excluded_headers[] = {
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-object-lock-legal-hold"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source-range"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
};

const size_t g_s3_list_parts_excluded_headers_count = AWS_ARRAY_SIZE(g_s3_list_parts_excluded_headers);
Expand Down Expand Up @@ -192,6 +197,7 @@ const struct aws_byte_cursor g_s3_list_parts_with_checksum_excluded_headers[] =
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-object-lock-legal-hold"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source-range"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
};

const size_t g_s3_list_parts_with_checksum_excluded_headers_count =
Expand Down Expand Up @@ -227,8 +233,19 @@ const struct aws_byte_cursor g_s3_abort_multipart_upload_excluded_headers[] = {
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source-range"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("if-none-match"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
};

const struct aws_byte_cursor g_s3_create_session_allowed_headers[] = {
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-server-side-encryption"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-server-side-encryption-aws-kms-key-id"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-server-side-encryption-context"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-server-side-encryption-bucket-key-enabled"),
};

const size_t g_s3_create_session_allowed_headers_count = AWS_ARRAY_SIZE(g_s3_create_session_allowed_headers);

static const struct aws_byte_cursor s_x_amz_meta_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-meta-");

static const struct aws_byte_cursor s_checksum_type_header =
Expand Down
Loading

0 comments on commit aef075b

Please sign in to comment.