diff --git a/src/flb_utils.c b/src/flb_utils.c index 56e6877d7bb..88ffe1bd327 100644 --- a/src/flb_utils.c +++ b/src/flb_utils.c @@ -1154,7 +1154,7 @@ static char *flb_utils_copy_host_sds(const char *string, int pos_init, int pos_e if (string[pos_end-1] != ']') { return NULL; } - return flb_sds_create_len(string + pos_init + 1, pos_end - 1); + return flb_sds_create_len(string + pos_init + 1, pos_end - 2); } else { return flb_sds_create_len(string + pos_init, pos_end); @@ -1171,6 +1171,7 @@ int flb_utils_url_split(const char *in_url, char **out_protocol, char *p; char *tmp; char *sep; + char *bracket = NULL; /* Protocol */ p = strstr(in_url, "://"); @@ -1192,7 +1193,14 @@ int flb_utils_url_split(const char *in_url, char **out_protocol, /* Check for first '/' */ sep = strchr(p, '/'); - tmp = strchr(p, ':'); + if (p[0] == '[') { + bracket = strchr(p, ']'); + } + if (bracket) { + tmp = strchr(bracket, ':'); + } else { + tmp = strchr(p, ':'); + } /* Validate port separator is found before the first slash */ if (sep && tmp) { @@ -1267,6 +1275,7 @@ int flb_utils_url_split_sds(const flb_sds_t in_url, flb_sds_t *out_protocol, char *p = NULL; char *tmp = NULL; char *sep = NULL; + char *bracket = NULL; /* Protocol */ p = strstr(in_url, "://"); @@ -1288,7 +1297,14 @@ int flb_utils_url_split_sds(const flb_sds_t in_url, flb_sds_t *out_protocol, /* Check for first '/' */ sep = strchr(p, '/'); - tmp = strchr(p, ':'); + if (p[0] == '[') { + bracket = strchr(p, ']'); + } + if (bracket) { + tmp = strchr(bracket, ':'); + } else { + tmp = strchr(p, ':'); + } /* Validate port separator is found before the first slash */ if (sep && tmp) { diff --git a/tests/internal/aws_credentials_http.c b/tests/internal/aws_credentials_http.c index f915f6acc17..9fbe84c5863 100644 --- a/tests/internal/aws_credentials_http.c +++ b/tests/internal/aws_credentials_http.c @@ -589,6 +589,80 @@ static void test_http_provider_eks_with_token_file() cleanup_test(provider, config); } +static void test_http_provider_eks_ipv6() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + struct flb_config *config; + int ret; + + /* tests validation of valid ipv6 local loopback IP */ + setenv("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://[fd00:ec2::23]/iam_credentials/pod1", 1); + setenv("AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE", TEST_AUTHORIZATION_TOKEN_FILE, 1); + + setup_test(FLB_AWS_CLIENT_MOCK( + response( + expect(URI, "/iam_credentials/pod1"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "Authorization", "local-http-credential-server-authorization-token"), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"XACCESSEKSXXX\",\n \"SecretAccessKey\"" + " : \"XSECRETEKSXXXXXXXXXXXXXX\",\n \"Token\" : \"XTOKENEKSXXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), + set(PAYLOAD_SIZE, 257) + ), + response( + expect(URI, "/iam_credentials/pod1"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "Authorization", "local-http-credential-server-authorization-token"), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"YACCESSEKSXXX\",\n \"SecretAccessKey\"" + " : \"YSECRETEKSXXXXXXXXXXXXXX\",\n \"Token\" : \"YTOKENEKSXXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), + set(PAYLOAD_SIZE, 257) + ) + ), &provider, &config); + + flb_time_msleep(1000); + + /* Repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEKSXXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEKSXXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEKSXXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Retrieve from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEKSXXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEKSXXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEKSXXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + /* Retrieve refreshed credentials from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("YACCESSEKSXXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("YSECRETEKSXXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("YTOKENEKSXXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Check we have exhausted our response list */ + TEST_CHECK(flb_aws_client_mock_generator_count_unused_requests() == 0); + + cleanup_test(provider, config); +} static void test_http_provider_https_endpoint() { @@ -766,5 +840,6 @@ TEST_LIST = { { "test_http_provider_server_failure", test_http_provider_server_failure}, { "test_http_validator_invalid_host", test_http_validator_invalid_host}, { "test_http_validator_invalid_port", test_http_validator_invalid_port}, + { "test_http_provider_eks_ipv6", test_http_provider_eks_ipv6}, { 0 } }; diff --git a/tests/internal/utils.c b/tests/internal/utils.c index 232e2461c0b..2144e05dec1 100644 --- a/tests/internal/utils.c +++ b/tests/internal/utils.c @@ -36,6 +36,8 @@ struct url_check url_checks[] = { {0, "https://fluentbit.io:1234/", "https", "fluentbit.io", "1234", "/"}, {0, "https://fluentbit.io:1234/v", "https", "fluentbit.io", "1234", "/v"}, {-1, "://", NULL, NULL, NULL, NULL}, + {0, "http://[fd00:ec2::23]/v1/credentials", "http", "fd00:ec2::23", "80", "/v1/credentials"}, + {0, "https://[::192.9.5.5]:1234/v", "https", "::192.9.5.5", "1234", "/v"} }; void test_url_split_sds()