in src/aws-cpp-sdk-core/source/auth/GeneralHTTPCredentialsProvider.cpp [63:148]
bool GeneralHTTPCredentialsProvider::ShouldCreateGeneralHTTPProvider(const Aws::String& relativeUri, const Aws::String& absoluteUri, const Aws::String authToken)
{
if (authToken.find("\r\n") != Aws::String::npos)
{
AWS_LOGSTREAM_WARN(GEN_HTTP_LOG_TAG, "Can't use General HTTP Provider: AWS_CONTAINER_AUTHORIZATION_TOKEN env value contains invalid characters (\\r\\n)");
return false;
}
if (!relativeUri.empty())
{
// The provider MAY choose to assert syntactical validity of the resulting URI
// perform very basic check here
if (relativeUri[0] != '/') {
AWS_LOGSTREAM_WARN(GEN_HTTP_LOG_TAG, "Can't use General HTTP Provider: AWS_CONTAINER_CREDENTIALS_RELATIVE_URI does not begin with /");
return false;
} else {
// full URI is not used in case of a relative one present
return true;
}
}
if (!absoluteUri.empty())
{
// If the resolved URI’s scheme is HTTPS, its hostname may be used in the request
if (Aws::Utils::StringUtils::ToLower(absoluteUri.c_str()).rfind(Aws::String("https://"), 0) == 0) // if starts_with
{
return true;
}
Aws::Http::URI absUri(absoluteUri);
const Aws::String& authority = absUri.GetAuthority();
// Otherwise, implementations MUST fail to resolve when the URI hostname does not satisfy any of the following conditions
if (IsAllowedIp(authority))
{
return true;
}
Aws::Crt::Io::HostResolver* pHostResolver = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultHostResolver();
if (pHostResolver)
{
bool shouldAllow = false;
bool hostResolved = false;
std::mutex hostResolverMutex;
std::condition_variable hostResolverCV;
auto onHostResolved = [&shouldAllow, &hostResolved, &hostResolverCV, &hostResolverMutex](Aws::Crt::Io::HostResolver &resolver, const Aws::Crt::Vector<Aws::Crt::Io::HostAddress> &addresses, int errorCode)
{
AWS_UNREFERENCED_PARAM(resolver);
if (AWS_ERROR_SUCCESS == errorCode)
{
for(const auto& address : addresses)
{
if (!IsAllowedIp(Aws::String((const char*) address.address->bytes, address.address->len)))
{
return;
}
}
std::unique_lock<std::mutex> lock(hostResolverMutex);
shouldAllow = !addresses.empty();
hostResolved = true;
hostResolverCV.notify_one();
}
else
{
std::unique_lock<std::mutex> lock(hostResolverMutex);
hostResolverCV.notify_one();
}
};
pHostResolver->ResolveHost(authority.c_str(), onHostResolved);
std::unique_lock<std::mutex> lock(hostResolverMutex);
if (!hostResolved) {
hostResolverCV.wait_for(lock, std::chrono::milliseconds(1000));
}
if (shouldAllow)
{
return true;
}
}
AWS_LOGSTREAM_WARN(GEN_HTTP_LOG_TAG, "Can't use General HTTP Provider: AWS_CONTAINER_CREDENTIALS_FULL_URI is not HTTPS and is not within loop back CIDR: " << authority);
return false;
}
// both relativeUri and absoluteUri are empty
return false;
}