Skip to content

Commit

Permalink
Shutdown callback support for all credentials providers (#26)
Browse files Browse the repository at this point in the history
shutdown callbacks to all providers
  • Loading branch information
bretambrose committed Nov 21, 2019
1 parent 024cd52 commit 57ba3ae
Show file tree
Hide file tree
Showing 24 changed files with 830 additions and 361 deletions.
1 change: 1 addition & 0 deletions include/aws/auth/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum aws_auth_errors {
AWS_AUTH_SIGNING_NO_CREDENTIALS,
AWS_AUTH_SIGNING_ILLEGAL_REQUEST_QUERY_PARAM,
AWS_AUTH_SIGNING_ILLEGAL_REQUEST_HEADER,
AWS_AUTH_SIGNING_INVALID_CONFIGURATION,

AWS_AUTH_ERROR_END_RANGE = 0x1BFF
};
Expand Down
64 changes: 42 additions & 22 deletions include/aws/auth/credentials.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,25 @@ typedef int(aws_credentials_provider_get_credentials_fn)(
struct aws_credentials_provider *provider,
aws_on_get_credentials_callback_fn callback,
void *user_data);
typedef void(aws_credentials_provider_clean_up_fn)(struct aws_credentials_provider *provider);
typedef void(aws_credentials_provider_shutdown_fn)(struct aws_credentials_provider *provider);
typedef void(aws_credentials_provider_destroy_fn)(struct aws_credentials_provider *provider);

struct aws_credentials_provider_vtable {
aws_credentials_provider_get_credentials_fn *get_credentials;
aws_credentials_provider_clean_up_fn *clean_up;
aws_credentials_provider_shutdown_fn *shutdown;
aws_credentials_provider_destroy_fn *destroy;
};

typedef void(aws_credentials_provider_shutdown_completed_fn)(void *user_data);

/*
* All credentials providers support an optional shutdown callback that
* gets invoked, with appropriate user data, when the resources used by the provider
* are no longer in use. For example, the imds provider uses this to
* signal when it is no longer using the client bootstrap used in its
* internal connection manager.
*/
struct aws_credentials_provider_shutdown_options {
aws_credentials_provider_shutdown_completed_fn *shutdown_callback;
void *shutdown_user_data;
};

/*
Expand All @@ -62,40 +74,56 @@ struct aws_credentials_provider_vtable {
struct aws_credentials_provider {
struct aws_credentials_provider_vtable *vtable;
struct aws_allocator *allocator;
struct aws_credentials_provider_shutdown_options shutdown_options;
void *impl;
struct aws_atomic_var shutting_down;
struct aws_atomic_var ref_count;
};

/*
* Config structs for creating all the different credentials providers
*/

struct aws_credentials_provider_static_options {
struct aws_credentials_provider_shutdown_options shutdown_options;
struct aws_byte_cursor access_key_id;
struct aws_byte_cursor secret_access_key;
struct aws_byte_cursor session_token;
};

struct aws_credentials_provider_environment_options {
struct aws_credentials_provider_shutdown_options shutdown_options;
};

struct aws_credentials_provider_profile_options {
struct aws_credentials_provider_shutdown_options shutdown_options;
struct aws_byte_cursor profile_name_override;
struct aws_byte_cursor config_file_name_override;
struct aws_byte_cursor credentials_file_name_override;
};

struct aws_credentials_provider_cached_options {
struct aws_credentials_provider_shutdown_options shutdown_options;
struct aws_credentials_provider *source;
uint64_t refresh_time_in_milliseconds;
aws_io_clock_fn *clock_fn;
};

struct aws_credentials_provider_chain_options {
struct aws_credentials_provider_shutdown_options shutdown_options;
struct aws_credentials_provider **providers;
size_t provider_count;
};

struct aws_credentials_provider_imds_options {
struct aws_credentials_provider_shutdown_options shutdown_options;
struct aws_client_bootstrap *bootstrap;

/* For mocking the http layer in tests, leave NULL otherwise */
struct aws_credentials_provider_imds_function_table *function_table;
};

struct aws_credentials_provider_chain_default_options {
struct aws_credentials_provider_shutdown_options shutdown_options;
struct aws_client_bootstrap *bootstrap;
};

Expand Down Expand Up @@ -129,14 +157,6 @@ void aws_credentials_destroy(struct aws_credentials *credentials);
* Credentials provider APIs
*/

/*
* Signal a provider (and all linked providers) to cancel pending queries and
* stop accepting new ones. Useful to hasten shutdown time if you know the provider
* is going away.
*/
AWS_AUTH_API
void aws_credentials_provider_shutdown(struct aws_credentials_provider *provider);

/*
* Release a reference to a credentials provider
*/
Expand Down Expand Up @@ -168,9 +188,7 @@ int aws_credentials_provider_get_credentials(
AWS_AUTH_API
struct aws_credentials_provider *aws_credentials_provider_new_static(
struct aws_allocator *allocator,
struct aws_byte_cursor access_key_id,
struct aws_byte_cursor secret_access_key,
struct aws_byte_cursor session_token);
const struct aws_credentials_provider_static_options *options);

/*
* A provider that returns credentials sourced from the environment variables:
Expand All @@ -180,7 +198,9 @@ struct aws_credentials_provider *aws_credentials_provider_new_static(
* AWS_SESSION_TOKEN
*/
AWS_AUTH_API
struct aws_credentials_provider *aws_credentials_provider_new_environment(struct aws_allocator *allocator);
struct aws_credentials_provider *aws_credentials_provider_new_environment(
struct aws_allocator *allocator,
const struct aws_credentials_provider_environment_options *options);

/*
* A provider that functions as a caching decorating of another provider.
Expand All @@ -194,7 +214,7 @@ struct aws_credentials_provider *aws_credentials_provider_new_environment(struct
AWS_AUTH_API
struct aws_credentials_provider *aws_credentials_provider_new_cached(
struct aws_allocator *allocator,
struct aws_credentials_provider_cached_options *options);
const struct aws_credentials_provider_cached_options *options);

/*
* A provider that sources credentials from key-value profiles loaded from the aws credentials
Expand All @@ -204,7 +224,7 @@ struct aws_credentials_provider *aws_credentials_provider_new_cached(
AWS_AUTH_API
struct aws_credentials_provider *aws_credentials_provider_new_profile(
struct aws_allocator *allocator,
struct aws_credentials_provider_profile_options *options);
const struct aws_credentials_provider_profile_options *options);

/*
* A provider that sources credentials from an ordered sequence of providers, with the overall result
Expand All @@ -215,15 +235,15 @@ struct aws_credentials_provider *aws_credentials_provider_new_profile(
AWS_AUTH_API
struct aws_credentials_provider *aws_credentials_provider_new_chain(
struct aws_allocator *allocator,
struct aws_credentials_provider_chain_options *options);
const struct aws_credentials_provider_chain_options *options);

/*
* A provider that sources credentials from the ec2 instance metadata service
*/
AWS_AUTH_API
struct aws_credentials_provider *aws_credentials_provider_new_imds(
struct aws_allocator *allocator,
struct aws_credentials_provider_imds_options *options);
const struct aws_credentials_provider_imds_options *options);

/*
* Creates the default provider chain used by most AWS SDKs.
Expand All @@ -241,7 +261,7 @@ struct aws_credentials_provider *aws_credentials_provider_new_imds(
AWS_AUTH_API
struct aws_credentials_provider *aws_credentials_provider_new_chain_default(
struct aws_allocator *allocator,
struct aws_credentials_provider_chain_default_options *options);
const struct aws_credentials_provider_chain_default_options *options);

AWS_EXTERN_C_END

Expand Down
12 changes: 7 additions & 5 deletions include/aws/auth/private/aws_signing.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

#include <aws/auth/auth.h>
#include <aws/auth/signer.h>
#include <aws/auth/signing.h>

#include <aws/common/byte_buf.h>
#include <aws/common/hash_table.h>
Expand All @@ -41,10 +41,12 @@ struct aws_signing_state_aws {
struct aws_allocator *allocator;

const struct aws_signable *signable;
const struct aws_signing_config_aws *config;
aws_signer_signing_complete_fn *on_complete;
aws_signing_complete_fn *on_complete;
void *userdata;

struct aws_signing_config_aws config;
struct aws_byte_buf region_service_buffer;

struct aws_signing_result result;
struct aws_credentials *credentials;

Expand All @@ -67,9 +69,9 @@ AWS_EXTERN_C_BEGIN
AWS_AUTH_API
struct aws_signing_state_aws *aws_signing_state_new(
struct aws_allocator *allocator,
const struct aws_signing_config_aws *context,
const struct aws_signing_config_aws *config,
const struct aws_signable *signable,
aws_signer_signing_complete_fn *on_complete,
aws_signing_complete_fn *on_complete,
void *userdata);

AWS_AUTH_API
Expand Down
2 changes: 1 addition & 1 deletion include/aws/auth/private/credentials_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ AWS_AUTH_API
void aws_credentials_provider_destroy(struct aws_credentials_provider *provider);

AWS_AUTH_API
void aws_credentials_provider_shutdown_nil(struct aws_credentials_provider *provider);
void aws_credentials_provider_invoke_shutdown_callback(struct aws_credentials_provider *provider);

AWS_EXTERN_C_END

Expand Down
60 changes: 11 additions & 49 deletions include/aws/auth/signer.h → include/aws/auth/signing.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,66 +22,24 @@
#include <aws/auth/signing_result.h>

struct aws_signable;
struct aws_signer;

/**
* Gets called by the signer when the signing is complete.
* Gets called by the signing function when the signing is complete.
*
* Note that result will be destroyed after this function returns, so either copy it,
* or do all necessary adjustments inside the callback.
*/
typedef void(aws_signer_signing_complete_fn)(struct aws_signing_result *result, int error_code, void *userdata);

typedef int(aws_signer_sign_request_fn)(
struct aws_signer *signer,
const struct aws_signable *signable,
const struct aws_signing_config_base *base_config,
aws_signer_signing_complete_fn *on_complete,
void *userdata);
typedef void(aws_signer_clean_up_fn)(struct aws_signer *signer);

struct aws_signer_vtable {
aws_signer_sign_request_fn *sign_request;
aws_signer_clean_up_fn *clean_up;
};

/*
* An object that can take an http request and return a set of changes to the request (header/query param) necessary
* for the request to be authorized, according to an associated signing process.
*/
struct aws_signer {
struct aws_allocator *allocator;
struct aws_signer_vtable *vtable;
void *impl;
};
typedef void(aws_signing_complete_fn)(struct aws_signing_result *result, int error_code, void *userdata);

AWS_EXTERN_C_BEGIN

/*
* Destroys all resources associated with a signer
*/
AWS_AUTH_API
void aws_signer_destroy(struct aws_signer *signer);

/*
* Takes an http request and a per-signer-type configuration struct and computes the changes to the request necessary
* for compliance with the signer's signing algorithm.
*/
AWS_AUTH_API
int aws_signer_sign_request(
struct aws_signer *signer,
const struct aws_signable *signable,
const struct aws_signing_config_base *base_config,
aws_signer_signing_complete_fn *on_complete,
void *userdata);

/*
* Creates a new signer that performs AWS http request signing. Requires an instance of
* the aws_signing_config_aws struct when signing.
*
* This signer currently supports only the sigv4 algorithm.
* This signing function currently supports only the sigv4 algorithm.
*
* When using this signer to sign AWS http requests:
* When using this signing function to sign AWS http requests:
*
* (1) Do not add the following headers to requests before signing:
* x-amz-content-sha256,
Expand All @@ -98,11 +56,15 @@ int aws_signer_sign_request(
* In all cases, the signing result will tell exactly what header and/or query params to add to the request
* to become a fully-signed AWS http request.
*
* These restrictions can be relaxed, if necessary, in the future, but they don't unreasonable and
* relaxing them adds non-trivial complexity.
* These restrictions can be relaxed, if necessary, in the future.
*/
AWS_AUTH_API
struct aws_signer *aws_signer_new_aws(struct aws_allocator *allocator);
int aws_sign_request_aws(
struct aws_allocator *allocator,
const struct aws_signable *signable,
const struct aws_signing_config_base *base_config,
aws_signing_complete_fn *on_complete,
void *userdata);

AWS_EXTERN_C_END

Expand Down
3 changes: 3 additions & 0 deletions include/aws/auth/signing_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ AWS_EXTERN_C_BEGIN
AWS_AUTH_API
const char *aws_signing_algorithm_to_string(enum aws_signing_algorithm algorithm);

AWS_AUTH_API
int aws_validate_aws_signing_config_aws(const struct aws_signing_config_aws *config);

AWS_EXTERN_C_END

#endif /* AWS_AUTH_SIGNING_CONFIG_H */
4 changes: 3 additions & 1 deletion source/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ static struct aws_error_info s_errors[] = {
AWS_DEFINE_ERROR_INFO_AUTH(
AWS_AUTH_SIGNING_ILLEGAL_REQUEST_HEADER,
"Attempt to sign an http request that includes a header that signing may add"),

AWS_DEFINE_ERROR_INFO_AUTH(
AWS_AUTH_SIGNING_INVALID_CONFIGURATION,
"Attempt to sign an http request with an invalid signing configuration"),
};
/* clang-format on */

Expand Down
Loading

0 comments on commit 57ba3ae

Please sign in to comment.