remote: add aws auth sdk. Fixes #6808
RELNOTES: None
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonClientException.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonClientException.java
new file mode 100644
index 0000000..83a824f
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonClientException.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws;
+
+/**
+ * Base exception class for any errors that occur while attempting to use an AWS
+ * client from AWS SDK for Java to make service calls to Amazon Web Services.
+ *
+ * Error responses from services will be handled as AmazonServiceExceptions.
+ * This class is primarily for errors that occur when unable to get a response
+ * from a service, or when the client is unable to parse the response from a
+ * service. For example, if a caller tries to use a client to make a service
+ * call, but no network connection is present, an AmazonClientException will be
+ * thrown to indicate that the client wasn't able to successfully make the
+ * service call, and no information from the service is available.
+ *
+ * Note : If the SDK is able to parse the response; but doesn't recognize the
+ * error code from the service, an AmazonServiceException is thrown
+ *
+ * Callers should typically deal with exceptions through AmazonServiceException,
+ * which represent error responses returned by services. AmazonServiceException
+ * has much more information available for callers to appropriately deal with
+ * different types of errors that can occur.
+ *
+ * @see AmazonServiceException
+ */
+public class AmazonClientException extends SdkBaseException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creates a new AmazonClientException with the specified message, and root
+ * cause.
+ *
+ * @param message
+ * An error message describing why this exception was thrown.
+ * @param t
+ * The underlying cause of this exception.
+ */
+ public AmazonClientException(String message, Throwable t) {
+ super(message, t);
+ }
+
+ /**
+ * Creates a new AmazonClientException with the specified message.
+ *
+ * @param message
+ * An error message describing why this exception was thrown.
+ */
+ public AmazonClientException(String message) {
+ super(message);
+ }
+
+ public AmazonClientException(Throwable t) {
+ super(t);
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonServiceException.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonServiceException.java
new file mode 100644
index 0000000..c578ca9
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonServiceException.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws;
+
+/**
+ * Extension of SdkClientException that represents an error response returned
+ * by an Amazon web service. Receiving an exception of this type indicates that
+ * the caller's request was correctly transmitted to the service, but for some
+ * reason, the service was not able to process it, and returned an error
+ * response instead.
+ * <p>
+ * AmazonServiceException provides callers several pieces of
+ * information that can be used to obtain more information about the error and
+ * why it occurred. In particular, the errorType field can be used to determine
+ * if the caller's request was invalid, or the service encountered an error on
+ * the server side while processing it.
+ */
+public class AmazonServiceException extends SdkClientException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The unique AWS identifier for the service request the caller made. The
+ * AWS request ID can uniquely identify the AWS request, and is used for
+ * reporting an error to AWS support team.
+ */
+ private String requestId;
+
+ /**
+ * The AWS error code represented by this exception (ex:
+ * InvalidParameterValue).
+ */
+ private String errorCode;
+
+ /**
+ * The error message as returned by the service.
+ */
+ private String errorMessage;
+
+ /** The HTTP status code that was returned with this error */
+ private int statusCode;
+
+ /**
+ * The name of the Amazon service that sent this error response.
+ */
+ private String serviceName;
+
+ /**
+ * Constructs a new AmazonServiceException with the specified message.
+ *
+ * @param errorMessage
+ * An error message describing what went wrong.
+ */
+ public AmazonServiceException(String errorMessage) {
+ super((String)null);
+ this.errorMessage = errorMessage;
+ }
+
+ /**
+ * Constructs a new AmazonServiceException with the specified message and
+ * exception indicating the root cause.
+ *
+ * @param errorMessage
+ * An error message describing what went wrong.
+ * @param cause
+ * The root exception that caused this exception to be thrown.
+ */
+ public AmazonServiceException(String errorMessage, Exception cause) {
+ super(null, cause);
+ this.errorMessage = errorMessage;
+ }
+
+ /**
+ * Returns the AWS request ID that uniquely identifies the service request
+ * the caller made.
+ *
+ * @return The AWS request ID that uniquely identifies the service request
+ * the caller made.
+ */
+ public String getRequestId() {
+ return requestId;
+ }
+
+ /**
+ * Returns the name of the service that sent this error response.
+ *
+ * @return The name of the service that sent this error response.
+ */
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ /**
+ * Sets the AWS error code represented by this exception.
+ *
+ * @param errorCode
+ * The AWS error code represented by this exception.
+ */
+ public void setErrorCode(String errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * Returns the AWS error code represented by this exception.
+ *
+ * @return The AWS error code represented by this exception.
+ */
+ public String getErrorCode() {
+ return errorCode;
+ }
+
+ /**
+ * @return the human-readable error message provided by the service
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Sets the HTTP status code that was returned with this service exception.
+ *
+ * @param statusCode
+ * The HTTP status code that was returned with this service
+ * exception.
+ */
+ public void setStatusCode(int statusCode) {
+ this.statusCode = statusCode;
+ }
+
+ /**
+ * Returns the HTTP status code that was returned with this service
+ * exception.
+ *
+ * @return The HTTP status code that was returned with this service
+ * exception.
+ */
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ @Override
+ public String getMessage() {
+ return getErrorMessage()
+ + " (Service: " + getServiceName()
+ + "; Status Code: " + getStatusCode()
+ + "; Error Code: " + getErrorCode()
+ + "; Request ID: " + getRequestId() + ")";
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SDKGlobalConfiguration.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SDKGlobalConfiguration.java
new file mode 100644
index 0000000..7f3fd38
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SDKGlobalConfiguration.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws;
+
+/**
+ * SDKGlobalConfiguration is to configure any global settings
+ */
+public class SDKGlobalConfiguration {
+ /////////////////////// System Properties ///////////////////////
+
+ /** System property name for the AWS access key ID */
+ public static final String ACCESS_KEY_SYSTEM_PROPERTY = "aws.accessKeyId";
+
+ /** System property name for the AWS secret key */
+ public static final String SECRET_KEY_SYSTEM_PROPERTY = "aws.secretKey";
+
+ /**
+ * System property name for the AWS session token
+ */
+ public static final String SESSION_TOKEN_SYSTEM_PROPERTY = "aws.sessionToken";
+
+ /**
+ * System property for overriding the Amazon EC2 Instance Metadata Service
+ * endpoint.
+ */
+ public static final String EC2_METADATA_SERVICE_OVERRIDE_SYSTEM_PROPERTY =
+ "com.amazonaws.sdk.ec2MetadataServiceEndpointOverride";
+
+ /**
+ * By default, the AmazonS3Client will continue to use the legacy
+ * S3Signer to authenticate requests it makes to S3 in regions that
+ * support the older protocol. Setting this property to anything other
+ * than null will cause the client to upgrade to Signature Version 4
+ * whenever it has been configured with an explicit region (which is a
+ * required parameter for Signature Version 4). The client will continue
+ * to use the older signature protocol when not configured with a region
+ * to avoid breaking existing applications.
+ * <p>
+ * Signature Version 4 is more secure than the legacy S3Signer, but
+ * requires calculating a SHA-256 hash of the entire request body which
+ * can be expensive for large upload requests.
+ */
+ @Deprecated
+ public static final String ENABLE_S3_SIGV4_SYSTEM_PROPERTY =
+ "com.amazonaws.services.s3.enableV4";
+
+ /**
+ * Like {@link #ENABLE_S3_SIGV4_SYSTEM_PROPERTY}, but causes the client to
+ * always use Signature Version 4, assuming a region of
+ * "us-east-1" if no explicit region has been configured. This
+ * guarantees that the more secure authentication protocol will be used,
+ * but will cause authentication failures in code that accesses buckets in
+ * regions other than US Standard without explicitly configuring a region.
+ */
+ @Deprecated
+ public static final String ENFORCE_S3_SIGV4_SYSTEM_PROPERTY =
+ "com.amazonaws.services.s3.enforceV4";
+
+ /**
+ * @deprecated with {@link AmazonWebServiceRequest#getRequestClientOptions()}
+ * and {@link RequestClientOptions#setReadLimit(int)}.
+ * <p>
+ * The default size of the buffer when uploading data from a stream. A
+ * buffer of this size will be created and filled with the first bytes from
+ * a stream being uploaded so that any transmit errors that occur in that
+ * section of the data can be automatically retried without the caller's
+ * intervention.
+ * <p>
+ * If not set, the default value of 128 KB will be used.
+ */
+ @Deprecated
+ public static final String DEFAULT_S3_STREAM_BUFFER_SIZE =
+ "com.amazonaws.sdk.s3.defaultStreamBufferSize";
+
+ /**
+ * @deprecated by {@link #DEFAULT_METRICS_SYSTEM_PROPERTY}.
+ *
+ * Internal system property to enable timing info collection.
+ */
+ @Deprecated
+ public static final String PROFILING_SYSTEM_PROPERTY =
+ "com.amazonaws.sdk.enableRuntimeProfiling";
+
+ /////////////////////// Environment Variables ///////////////////////
+ /** Environment variable name for the AWS access key ID */
+ public static final String ACCESS_KEY_ENV_VAR = "AWS_ACCESS_KEY_ID";
+
+ /** Alternate environment variable name for the AWS access key ID */
+ public static final String ALTERNATE_ACCESS_KEY_ENV_VAR = "AWS_ACCESS_KEY";
+
+ /** Environment variable name for the AWS secret key */
+ public static final String SECRET_KEY_ENV_VAR = "AWS_SECRET_KEY";
+
+ /** Alternate environment variable name for the AWS secret key */
+ public static final String ALTERNATE_SECRET_KEY_ENV_VAR = "AWS_SECRET_ACCESS_KEY";
+
+ /** Environment variable name for the AWS session token */
+ public static final String AWS_SESSION_TOKEN_ENV_VAR = "AWS_SESSION_TOKEN";
+
+ /**
+ * Environment variable to set an alternate path to the shared config file (default path is
+ * ~/.aws/config).
+ */
+ public static final String AWS_CONFIG_FILE_ENV_VAR = "AWS_CONFIG_FILE";
+
+ /**
+ * Environment variable to disable loading credentials or regions from EC2 Metadata instance service.
+ */
+ public static final String AWS_EC2_METADATA_DISABLED_ENV_VAR = "AWS_EC2_METADATA_DISABLED";
+
+ /**
+ * System property to disable loading credentials or regions from EC2 Metadata instance service.
+ */
+ public static final String AWS_EC2_METADATA_DISABLED_SYSTEM_PROPERTY = "com.amazonaws.sdk.disableEc2Metadata";
+
+
+ /**
+ * @deprecated by {@link SDKGlobalTime#setGlobalTimeOffset(int)}
+ */
+ @Deprecated
+ public static void setGlobalTimeOffset(int timeOffset) {
+ SDKGlobalTime.setGlobalTimeOffset(timeOffset);
+ }
+
+ /**
+ * @deprecated by {@link SDKGlobalTime#getGlobalTimeOffset()}
+ */
+ @Deprecated
+ public static int getGlobalTimeOffset() {
+ return SDKGlobalTime.getGlobalTimeOffset();
+ }
+
+ public static boolean isEc2MetadataDisabled() {
+ return isPropertyTrue(System.getProperty(AWS_EC2_METADATA_DISABLED_SYSTEM_PROPERTY)) ||
+ isPropertyTrue(System.getenv(AWS_EC2_METADATA_DISABLED_ENV_VAR));
+ }
+
+ private static boolean isPropertyTrue(final String property) {
+ if (property != null && property.equalsIgnoreCase("true")) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SDKGlobalTime.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SDKGlobalTime.java
new file mode 100644
index 0000000..9868e6bc
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SDKGlobalTime.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws;
+
+/**
+ * Used for clock skew adjustment between the client JVM where the SDK is run,
+ * and the server side.
+ */
+public class SDKGlobalTime {
+ /**
+ * globalTimeOffset is a time difference in seconds between the running JVM
+ * and AWS. Used to globally adjust the client clock skew. Java SDK already
+ * provides timeOffset and accessor methods in <code>Request</code> class but
+ * those are used per request, whereas this variable will adjust clock skew
+ * globally. Java SDK detects clock skew errors and adjusts global clock
+ * skew automatically.
+ */
+ private static volatile int globalTimeOffset;
+
+ /**
+ * Sets the global time difference in seconds between the running JVM and
+ * AWS. If this value is set then all the subsequent instantiation of an
+ * <code>AmazonHttpClient</code> will start using this
+ * value to generate timestamps.
+ *
+ * @param timeOffset
+ * the time difference in seconds between the running JVM and AWS
+ */
+ public static void setGlobalTimeOffset(int timeOffset) {
+ globalTimeOffset = timeOffset;
+ }
+
+ /**
+ * Gets the global time difference in seconds between the running JVM and
+ * AWS. See <code>Request#getTimeOffset()</code> if global time offset is
+ * not set.
+ */
+ public static int getGlobalTimeOffset() {
+ return globalTimeOffset;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SdkBaseException.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SdkBaseException.java
new file mode 100644
index 0000000..bee9f60
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SdkBaseException.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws;
+
+/**
+ *
+ * Base class for all exceptions thrown by the SDK.
+ * Exception may be a client side exception or an unmarshalled service exception.
+ */
+public class SdkBaseException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creates a new SdkBaseException with the specified message, and root
+ * cause.
+ *
+ * @param message
+ * An error message describing why this exception was thrown.
+ * @param t
+ * The underlying cause of this exception.
+ */
+ public SdkBaseException(String message, Throwable t) {
+ super(message, t);
+ }
+
+ /**
+ * Creates a new SdkBaseException with the specified message.
+ *
+ * @param message
+ * An error message describing why this exception was thrown.
+ */
+ public SdkBaseException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new SdkBaseException with the root cause.
+ *
+ * @param t
+ * The underlying cause of this exception.
+ */
+ public SdkBaseException(Throwable t) {
+ super(t);
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SdkClientException.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SdkClientException.java
new file mode 100644
index 0000000..93f2b1f
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SdkClientException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws;
+
+/**
+ * Base type for all client exceptions thrown by the SDK.
+ *
+ * This exception is thrown when service could not be contacted for a response,
+ * or when client is unable to parse the response from service.
+ *
+ * @see AmazonClientException
+ */
+public class SdkClientException extends AmazonClientException {
+
+ /**
+ * Creates a new SdkClientException with the specified message, and root
+ * cause.
+ *
+ * @param message
+ * An error message describing why this exception was thrown.
+ * @param t
+ * The underlying cause of this exception.
+ */
+ public SdkClientException(String message, Throwable t) {
+ super(message, t);
+ }
+
+ /**
+ * Creates a new SdkClientException with the specified message.
+ *
+ * @param message
+ * An error message describing why this exception was thrown.
+ */
+ public SdkClientException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new SdkClientException with the root cause.
+ *
+ * @param t
+ * The underlying cause of this exception.
+ */
+ public SdkClientException(Throwable t) {
+ super(t);
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/Immutable.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/Immutable.java
new file mode 100644
index 0000000..e85cd6a
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/Immutable.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
+ * the License. A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ */
+package com.amazonaws.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Documenting annotation to indicate a class is immutable.
+ */
+@Documented
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface Immutable {
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/SdkInternalApi.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/SdkInternalApi.java
new file mode 100644
index 0000000..9c26ea3
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/SdkInternalApi.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
+ * the License. A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ */
+package com.amazonaws.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Marker interface for 'internal' APIs that should not be used outside the core module. Breaking
+ * changes can and will be introduced to elements marked as {@link SdkInternalApi}. Users of the SDK
+ * and the generated clients themselves should not depend on any packages, types, fields,
+ * constructors, or methods with this annotation.
+ */
+@Target({ ElementType.PACKAGE, ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD })
+public @interface SdkInternalApi {
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/SdkProtectedApi.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/SdkProtectedApi.java
new file mode 100644
index 0000000..8f00fd4
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/SdkProtectedApi.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
+ * the License. A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ */
+package com.amazonaws.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Marker for elements that should only be accessed by the generated clients and not users of the
+ * SDK. Do not make breaking changes to these APIs - they won't directly break customers, but
+ * they'll break old versions of generated clients.
+ * <p>
+ * TODO: Write a linter that makes sure generated code only depends on public or
+ * {@code @InternalApi} classes.
+ */
+@Target({ ElementType.PACKAGE, ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD })
+public @interface SdkProtectedApi {
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/ThreadSafe.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/ThreadSafe.java
new file mode 100644
index 0000000..e661dab
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/ThreadSafe.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
+ * the License. A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ */
+package com.amazonaws.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Documenting annotation to indicate a class is thread-safe and may be shared among multiple threads.
+ *
+ * @see NotThreadSafe
+ */
+@Documented
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface ThreadSafe {
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/package-info.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/package-info.java
new file mode 100644
index 0000000..a517bb5
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2015-2018 Amazon Technologies, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * AWS Java SDK annotations.
+ */
+package com.amazonaws.annotation;
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentials.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentials.java
new file mode 100644
index 0000000..eb4788c
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentials.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+/**
+ * Provides access to the AWS credentials used for accessing AWS services: AWS
+ * access key ID and secret access key. These credentials are used to securely
+ * sign requests to AWS services.
+ * <p>
+ * A basic implementation of this interface is provided in
+ * {@link BasicAWSCredentials}, but callers are free to provide their own
+ * implementation, for example, to load AWS credentials from an encrypted file.
+ * <p>
+ * For more details on AWS access keys, see: <a href="http://docs.amazonwebservices.com/AWSSecurityCredentials/1.0/AboutAWSCredentials.html#AccessKeys"
+ * >http://docs.amazonwebservices.com/AWSSecurityCredentials/1.0/
+ * AboutAWSCredentials.html#AccessKeys</a>
+ */
+public interface AWSCredentials {
+
+ /**
+ * Returns the AWS access key ID for this credentials object.
+ *
+ * @return The AWS access key ID for this credentials object.
+ */
+ public String getAWSAccessKeyId();
+
+ /**
+ * Returns the AWS secret access key for this credentials object.
+ *
+ * @return The AWS secret access key for this credentials object.
+ */
+ public String getAWSSecretKey();
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentialsProvider.java
new file mode 100644
index 0000000..7c8a5df
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentialsProvider.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+/**
+ * Interface for providing AWS credentials. Implementations are free to use any
+ * strategy for providing AWS credentials, such as simply providing static
+ * credentials that don't change, or more complicated implementations, such as
+ * integrating with existing key management systems.
+ */
+public interface AWSCredentialsProvider {
+
+ /**
+ * Returns AWSCredentials which the caller can use to authorize an AWS request.
+ * Each implementation of AWSCredentialsProvider can chose its own strategy for
+ * loading credentials. For example, an implementation might load credentials
+ * from an existing key management system, or load new credentials when
+ * credentials are rotated.
+ *
+ * @return AWSCredentials which the caller can use to authorize an AWS request.
+ */
+ public AWSCredentials getCredentials();
+
+ /**
+ * Forces this credentials provider to refresh its credentials. For many
+ * implementations of credentials provider, this method may simply be a
+ * no-op, such as any credentials provider implementation that vends
+ * static/non-changing credentials. For other implementations that vend
+ * different credentials through out their lifetime, this method should
+ * force the credentials provider to refresh its credentials.
+ */
+ public void refresh();
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentialsProviderChain.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentialsProviderChain.java
new file mode 100644
index 0000000..6cf8bf5
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSCredentialsProviderChain.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.amazonaws.SdkClientException;
+
+/**
+ * {@link AWSCredentialsProvider} implementation that chains together multiple
+ * credentials providers. When a caller first requests credentials from this provider,
+ * it calls all the providers in the chain, in the original order specified,
+ * until one can provide credentials, and then returns those credentials. If all
+ * of the credential providers in the chain have been called, and none of them
+ * can provide credentials, then this class will throw an exception indicated
+ * that no credentials are available.
+ * <p>
+ * By default, this class will remember the first credentials provider in the chain
+ * that was able to provide credentials, and will continue to use that provider when
+ * credentials are requested in the future, instead of traversing the chain each time.
+ * This behavior can be controlled through the {@link #setReuseLastProvider(boolean)} method.
+ */
+public class AWSCredentialsProviderChain implements AWSCredentialsProvider {
+
+ private static final Log log = LogFactory.getLog(AWSCredentialsProviderChain.class);
+
+ private final List<AWSCredentialsProvider> credentialsProviders =
+ new LinkedList<AWSCredentialsProvider>();
+
+ private boolean reuseLastProvider = true;
+ private AWSCredentialsProvider lastUsedProvider;
+
+ /**
+ * Constructs a new AWSCredentialsProviderChain with the specified credential providers. When
+ * credentials are requested from this provider, it will call each of these credential providers
+ * in the same order specified here until one of them returns AWS security credentials.
+ *
+ * @param credentialsProviders
+ * The chain of credentials providers.
+ */
+ public AWSCredentialsProviderChain(List<? extends AWSCredentialsProvider> credentialsProviders) {
+ if (credentialsProviders == null || credentialsProviders.size() == 0) {
+ throw new IllegalArgumentException("No credential providers specified");
+ }
+ this.credentialsProviders.addAll(credentialsProviders);
+ }
+
+ /**
+ * Constructs a new AWSCredentialsProviderChain with the specified credential providers. When
+ * credentials are requested from this provider, it will call each of these credential providers
+ * in the same order specified here until one of them returns AWS security credentials.
+ *
+ * @param credentialsProviders
+ * The chain of credentials providers.
+ */
+ public AWSCredentialsProviderChain(AWSCredentialsProvider... credentialsProviders) {
+ if (credentialsProviders == null || credentialsProviders.length == 0) {
+ throw new IllegalArgumentException("No credential providers specified");
+ }
+
+ for (AWSCredentialsProvider provider : credentialsProviders) {
+ this.credentialsProviders.add(provider);
+ }
+ }
+
+ /**
+ * Returns true if this chain will reuse the last successful credentials
+ * provider for future credentials requests, otherwise, false if it will
+ * search through the chain each time.
+ *
+ * @return True if this chain will reuse the last successful credentials
+ * provider for future credentials requests.
+ */
+ public boolean getReuseLastProvider() {
+ return reuseLastProvider;
+ }
+
+ /**
+ * Enables or disables caching of the last successful credentials provider
+ * in this chain. Reusing the last successful credentials provider will
+ * typically return credentials faster than searching through the chain.
+ *
+ * @param b
+ * Whether to enable or disable reusing the last successful
+ * credentials provider for future credentials requests instead
+ * of searching through the whole chain.
+ */
+ public void setReuseLastProvider(boolean b) {
+ this.reuseLastProvider = b;
+ }
+
+ public AWSCredentials getCredentials() {
+ if (reuseLastProvider && lastUsedProvider != null) {
+ return lastUsedProvider.getCredentials();
+ }
+
+ for (AWSCredentialsProvider provider : credentialsProviders) {
+ try {
+ AWSCredentials credentials = provider.getCredentials();
+
+ if (credentials.getAWSAccessKeyId() != null &&
+ credentials.getAWSSecretKey() != null) {
+ log.debug("Loading credentials from " + provider.toString());
+
+ lastUsedProvider = provider;
+ return credentials;
+ }
+ } catch (Exception e) {
+ // Ignore any exceptions and move onto the next provider
+ log.debug("Unable to load credentials from " + provider.toString() +
+ ": " + e.getMessage());
+ }
+ }
+
+ throw new SdkClientException("Unable to load AWS credentials from any provider in the chain");
+ }
+
+ public void refresh() {
+ for (AWSCredentialsProvider provider : credentialsProviders) {
+ provider.refresh();
+ }
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSRefreshableSessionCredentials.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSRefreshableSessionCredentials.java
new file mode 100644
index 0000000..11ff8de
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSRefreshableSessionCredentials.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+/**
+ * Session credentials that can be refreshed upon request.
+ */
+public interface AWSRefreshableSessionCredentials extends AWSSessionCredentials {
+
+ /**
+ * Forces a refresh of these session credentials.
+ */
+ public void refreshCredentials();
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSSessionCredentials.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSSessionCredentials.java
new file mode 100644
index 0000000..0161e04
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSSessionCredentials.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2011-2018 Amazon Technologies, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.auth;
+
+/**
+ * AWS session credentials object.
+ */
+public interface AWSSessionCredentials extends AWSCredentials {
+
+ /**
+ * Returns the session token for this session.
+ */
+ public String getSessionToken();
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSSessionCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSSessionCredentialsProvider.java
new file mode 100644
index 0000000..82c8fee
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSSessionCredentialsProvider.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2011-2018 Amazon Technologies, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.auth;
+
+public interface AWSSessionCredentialsProvider extends AWSCredentialsProvider {
+
+ @Override
+ public AWSSessionCredentials getCredentials();
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSStaticCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSStaticCredentialsProvider.java
new file mode 100644
index 0000000..b439326
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWSStaticCredentialsProvider.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Simple implementation of AWSCredentialsProvider that just wraps static AWSCredentials.
+ */
+public class AWSStaticCredentialsProvider implements AWSCredentialsProvider {
+
+ private final AWSCredentials credentials;
+
+ public AWSStaticCredentialsProvider(AWSCredentials credentials) {
+ this.credentials = Preconditions.checkNotNull(credentials, "%s cannot be null", "credentials");
+ }
+
+ public AWSCredentials getCredentials() {
+ return credentials;
+ }
+
+ public void refresh() {
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AnonymousAWSCredentials.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AnonymousAWSCredentials.java
new file mode 100644
index 0000000..67ba06a9
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AnonymousAWSCredentials.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+
+/**
+ * Basic implementation of the AWSCredentials interface that allows use of "anonymous"
+ * credentials. Using anonymous credentials will result in requests not being signed
+ * before sending to the service. Any service that does not accept unsigned requests
+ * will return a service exception in this case.
+ */
+public class AnonymousAWSCredentials implements AWSCredentials {
+
+ /* (non-Javadoc)
+ * @see com.amazonaws.auth.AWSCredentials#getAWSAccessKeyId()
+ */
+ public String getAWSAccessKeyId() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see com.amazonaws.auth.AWSCredentials#getAWSSecretKey()
+ */
+ public String getAWSSecretKey() {
+ return null;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/BasicAWSCredentials.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/BasicAWSCredentials.java
new file mode 100644
index 0000000..00f704c8
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/BasicAWSCredentials.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+/**
+ * Basic implementation of the AWSCredentials interface that allows callers to
+ * pass in the AWS access key and secret access in the constructor.
+ */
+public class BasicAWSCredentials implements AWSCredentials {
+
+ private final String accessKey;
+ private final String secretKey;
+
+ /**
+ * Constructs a new BasicAWSCredentials object, with the specified AWS
+ * access key and AWS secret key.
+ *
+ * @param accessKey
+ * The AWS access key.
+ * @param secretKey
+ * The AWS secret access key.
+ */
+ public BasicAWSCredentials(String accessKey, String secretKey) {
+ if (accessKey == null) {
+ throw new IllegalArgumentException("Access key cannot be null.");
+ }
+ if (secretKey == null) {
+ throw new IllegalArgumentException("Secret key cannot be null.");
+ }
+
+ this.accessKey = accessKey;
+ this.secretKey = secretKey;
+ }
+
+ /* (non-Javadoc)
+ * @see com.amazonaws.auth.AWSCredentials#getAWSAccessKeyId()
+ */
+ public String getAWSAccessKeyId() {
+ return accessKey;
+ }
+
+ /* (non-Javadoc)
+ * @see com.amazonaws.auth.AWSCredentials#getAWSSecretKey()
+ */
+ public String getAWSSecretKey() {
+ return secretKey;
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/BasicSessionCredentials.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/BasicSessionCredentials.java
new file mode 100644
index 0000000..fa690a6
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/BasicSessionCredentials.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011-2018 Amazon Technologies, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.auth;
+
+/**
+ * Simple session credentials with keys and session token.
+ */
+public class BasicSessionCredentials implements AWSSessionCredentials {
+
+ private final String awsAccessKey;
+ private final String awsSecretKey;
+ private final String sessionToken;
+
+ public BasicSessionCredentials(String awsAccessKey, String awsSecretKey, String sessionToken) {
+ this.awsAccessKey = awsAccessKey;
+ this.awsSecretKey = awsSecretKey;
+ this.sessionToken = sessionToken;
+ }
+
+ public String getAWSAccessKeyId() {
+ return awsAccessKey;
+ }
+
+ public String getAWSSecretKey() {
+ return awsSecretKey;
+ }
+
+ public String getSessionToken() {
+ return sessionToken;
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ClasspathPropertiesFileCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ClasspathPropertiesFileCredentialsProvider.java
new file mode 100644
index 0000000..c7eb794
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ClasspathPropertiesFileCredentialsProvider.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.amazonaws.SdkClientException;
+
+/**
+ * {@link AWSCredentialsProvider} implementation that loads AWS security
+ * credentials from a properties file on the classpath. The default
+ * constructor creates a credentials provider that loads the credentials
+ * from a file named <code>AwsCredentials.properties</code> on the
+ * classpath, but which file to use from the classpath can also be controled
+ * through the one-argument constructor.
+ * <p>
+ * The AWS access key ID is expected to be in the <code>accessKey</code>
+ * property and the AWS secret key is expected to be in the
+ * <code>secretKey</code> property.
+ */
+public class ClasspathPropertiesFileCredentialsProvider implements AWSCredentialsProvider {
+
+ /** The name of the properties file to check for credentials */
+ private static String DEFAULT_PROPERTIES_FILE = "AwsCredentials.properties";
+
+ private final String credentialsFilePath;
+
+ /**
+ * Creates a new ClasspathPropertiesFileCredentialsProvider that will
+ * attempt to load the <code>AwsCredentials.properties</code> file from
+ * the classpath to read AWS security credentials.
+ */
+ public ClasspathPropertiesFileCredentialsProvider() {
+ this(DEFAULT_PROPERTIES_FILE);
+ }
+
+ /**
+ * Creates a new ClasspathPropertiesFileCredentialsProvider that will
+ * attempt to load a custom file from the classpath to read AWS security
+ * credentials.
+ *
+ * @param credentialsFilePath
+ * The custom classpath resource path to a properties file
+ * from which the AWS security credentials should be loaded.
+ *
+ * For example,
+ * <ul>
+ * <li>com/mycompany/credentials.properties</li>
+ * <li>beta-credentials.properties</li>
+ * <li>AwsCredentials.properties</li>
+ * </ul>
+ */
+ public ClasspathPropertiesFileCredentialsProvider(String credentialsFilePath) {
+ if (credentialsFilePath == null)
+ throw new IllegalArgumentException("Credentials file path cannot be null");
+
+ // Make sure the path is absolute
+ if (!credentialsFilePath.startsWith("/")) {
+ this.credentialsFilePath = "/" + credentialsFilePath;
+ } else {
+ this.credentialsFilePath = credentialsFilePath;
+ }
+ }
+
+ public AWSCredentials getCredentials() {
+ InputStream inputStream = getClass().getResourceAsStream(credentialsFilePath);
+ if (inputStream == null) {
+ throw new SdkClientException("Unable to load AWS credentials from the " + credentialsFilePath + " file on the classpath");
+ }
+
+ try {
+ return new PropertiesCredentials(inputStream);
+ } catch (IOException e) {
+ throw new SdkClientException("Unable to load AWS credentials from the " + credentialsFilePath + " file on the classpath", e);
+ }
+ }
+
+ public void refresh() {}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "(" + credentialsFilePath + ")";
+ }
+}
\ No newline at end of file
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ContainerCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ContainerCredentialsProvider.java
new file mode 100644
index 0000000..7e14c1a
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ContainerCredentialsProvider.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.internal.CredentialsEndpointProvider;
+import com.amazonaws.retry.internal.CredentialsEndpointRetryPolicy;
+import com.amazonaws.util.CollectionUtils;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * <p>
+ * {@link AWSCredentialsProvider} implementation that loads credentials
+ * from an Amazon Elastic Container.
+ * </p>
+ * <p>
+ * By default, the URI path is retrieved from the environment variable
+ * "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" in the container's environment.
+ * </p>
+ */
+public class ContainerCredentialsProvider implements AWSCredentialsProvider {
+
+ /** Environment variable to get the Amazon ECS credentials resource path. */
+ static final String ECS_CONTAINER_CREDENTIALS_PATH = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
+
+ /** Environment variable to get the full URI for a credentials path */
+ static final String CONTAINER_CREDENTIALS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
+
+ static final String CONTAINER_AUTHORIZATION_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN";
+
+ private static final Set<String> ALLOWED_FULL_URI_HOSTS = allowedHosts();
+
+ /** Default endpoint to retreive the Amazon ECS Credentials. */
+ private static final String ECS_CREDENTIALS_ENDPOINT = "http://169.254.170.2";
+
+ private final EC2CredentialsFetcher credentialsFetcher;
+
+ /**
+ * @deprecated use {@link #ContainerCredentialsProvider(CredentialsEndpointProvider)}
+ */
+ @Deprecated
+ public ContainerCredentialsProvider() {
+ this(new ECSCredentialsEndpointProvider());
+ }
+
+ public ContainerCredentialsProvider(CredentialsEndpointProvider credentialsEndpointProvider) {
+ this.credentialsFetcher = new EC2CredentialsFetcher(credentialsEndpointProvider);
+ }
+
+ @Override
+ public AWSCredentials getCredentials() {
+ return credentialsFetcher.getCredentials();
+ }
+
+ @Override
+ public void refresh() {
+ credentialsFetcher.refresh();
+ }
+
+ public Date getCredentialsExpiration() {
+ return credentialsFetcher.getCredentialsExpiration();
+ }
+
+
+ static class ECSCredentialsEndpointProvider extends CredentialsEndpointProvider {
+ @Override
+ public URI getCredentialsEndpoint() throws URISyntaxException {
+ String path = System.getenv(ECS_CONTAINER_CREDENTIALS_PATH);
+ if (path == null) {
+ throw new SdkClientException(
+ "The environment variable " + ECS_CONTAINER_CREDENTIALS_PATH + " is empty");
+ }
+
+ return new URI(ECS_CREDENTIALS_ENDPOINT + path);
+ }
+ @Override
+ public CredentialsEndpointRetryPolicy getRetryPolicy() {
+ return ContainerCredentialsRetryPolicy.getInstance();
+ }
+
+ }
+
+ /**
+ * A URI resolver that uses environment variable {@value CONTAINER_CREDENTIALS_FULL_URI} as the URI
+ * for the metadata service.
+ * Optionally an authorization token can be provided using the {@value CONTAINER_AUTHORIZATION_TOKEN} environment variable.
+ */
+ static class FullUriCredentialsEndpointProvider extends CredentialsEndpointProvider {
+
+ @Override
+ public URI getCredentialsEndpoint() throws URISyntaxException {
+ String fullUri = System.getenv(CONTAINER_CREDENTIALS_FULL_URI);
+ if (fullUri == null || fullUri.length() == 0) {
+ throw new SdkClientException("The environment variable " + CONTAINER_CREDENTIALS_FULL_URI + " is empty");
+ }
+
+ URI uri = new URI(fullUri);
+
+ if (!ALLOWED_FULL_URI_HOSTS.contains(uri.getHost())) {
+ throw new SdkClientException("The full URI (" + uri + ") contained withing environment variable " +
+ CONTAINER_CREDENTIALS_FULL_URI + " has an invalid host. Host can only be one of [" +
+ CollectionUtils.join(ALLOWED_FULL_URI_HOSTS, ", ") + "]");
+ }
+
+ return uri;
+ }
+
+ @Override
+ public Map<String, String> getHeaders() {
+ if (System.getenv(CONTAINER_AUTHORIZATION_TOKEN) != null) {
+ return Collections.singletonMap("Authorization", System.getenv(CONTAINER_AUTHORIZATION_TOKEN));
+ }
+ return new HashMap<String, String>();
+ }
+ }
+
+ private static Set<String> allowedHosts() {
+ HashSet<String> hosts = new HashSet<String>();
+ hosts.add("127.0.0.1");
+ hosts.add("localhost");
+ return Collections.unmodifiableSet(hosts);
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ContainerCredentialsRetryPolicy.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ContainerCredentialsRetryPolicy.java
new file mode 100644
index 0000000..689ff34
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ContainerCredentialsRetryPolicy.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import java.io.IOException;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.retry.internal.CredentialsEndpointRetryParameters;
+import com.amazonaws.retry.internal.CredentialsEndpointRetryPolicy;
+
+@SdkInternalApi
+class ContainerCredentialsRetryPolicy implements CredentialsEndpointRetryPolicy {
+
+ /** Max number of times a request is retried before failing. */
+ private static final int MAX_RETRIES = 5;
+
+ private static ContainerCredentialsRetryPolicy instance;
+
+ private ContainerCredentialsRetryPolicy() {
+
+ }
+
+ public static ContainerCredentialsRetryPolicy getInstance() {
+ if (instance == null) {
+ instance = new ContainerCredentialsRetryPolicy();
+ }
+ return instance;
+ }
+
+ @Override
+ public boolean shouldRetry(int retriesAttempted, CredentialsEndpointRetryParameters retryParams) {
+ if (retriesAttempted >= MAX_RETRIES) {
+ return false;
+ }
+
+ Integer statusCode = retryParams.getStatusCode();
+ if (statusCode != null && statusCode >= 500 && statusCode < 600) {
+ return true;
+ }
+
+ if (retryParams.getException() != null && retryParams.getException() instanceof IOException) {
+ return true;
+ }
+
+ return false;
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.java
new file mode 100644
index 0000000..9b42bac
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import com.amazonaws.auth.profile.ProfileCredentialsProvider;
+
+/**
+ * AWS credentials provider chain that looks for credentials in this order:
+ * <ul>
+ * <li>Environment Variables -
+ * <code>AWS_ACCESS_KEY_ID</code> and <code>AWS_SECRET_ACCESS_KEY</code>
+ * (RECOMMENDED since they are recognized by all the AWS SDKs and CLI except for .NET),
+ * or <code>AWS_ACCESS_KEY</code> and <code>AWS_SECRET_KEY</code> (only recognized by Java SDK)
+ * </li>
+ * <li>Java System Properties - aws.accessKeyId and aws.secretKey</li>
+ * <li>Credential profiles file at the default location (~/.aws/credentials) shared by all AWS SDKs and the AWS CLI</li>
+ * <li>Credentials delivered through the Amazon EC2 container service if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" environment variable is set
+ * and security manager has permission to access the variable,</li>
+ * <li>Instance profile credentials delivered through the Amazon EC2 metadata service</li>
+ * </ul>
+ *
+ * @see EnvironmentVariableCredentialsProvider
+ * @see SystemPropertiesCredentialsProvider
+ * @see ProfileCredentialsProvider
+ * @see EC2ContainerCredentialsProviderWrapper
+ */
+public class DefaultAWSCredentialsProviderChain extends AWSCredentialsProviderChain {
+
+ private static final DefaultAWSCredentialsProviderChain INSTANCE
+ = new DefaultAWSCredentialsProviderChain();
+
+ public DefaultAWSCredentialsProviderChain() {
+ super(new EnvironmentVariableCredentialsProvider(),
+ new SystemPropertiesCredentialsProvider(),
+ new ProfileCredentialsProvider(),
+ new EC2ContainerCredentialsProviderWrapper());
+ }
+
+ public static DefaultAWSCredentialsProviderChain getInstance() {
+ return INSTANCE;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EC2ContainerCredentialsProviderWrapper.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EC2ContainerCredentialsProviderWrapper.java
new file mode 100644
index 0000000..5c18ac0
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EC2ContainerCredentialsProviderWrapper.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import static com.amazonaws.auth.ContainerCredentialsProvider.CONTAINER_CREDENTIALS_FULL_URI;
+import static com.amazonaws.auth.ContainerCredentialsProvider.ECS_CONTAINER_CREDENTIALS_PATH;
+
+import com.amazonaws.auth.ContainerCredentialsProvider.ECSCredentialsEndpointProvider;
+import com.amazonaws.auth.ContainerCredentialsProvider.FullUriCredentialsEndpointProvider;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * <p>
+ * {@link AWSCredentialsProvider} that loads credentials from an Amazon Container (e.g. EC2)
+ *
+ * Credentials are solved in the following order:
+ * <ol>
+ * <li>
+ * If environment variable "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" is
+ * set (typically on EC2) it is used to hit the metadata service at the following endpoint: http://169.254.170.2
+ * </li>
+ * <li>
+ * If environment variable "AWS_CONTAINER_CREDENTIALS_FULL_URI" is
+ * set it is used to hit a metadata service at that URI. <br/> Optionally an authorization token can be included
+ * in the "Authorization" header of the request by setting the "AWS_CONTAINER_AUTHORIZATION_TOKEN" environment variable.
+ * </li>
+ * <li>
+ * If neither of the above environment variables are specified credentials are attempted to be loaded from Amazon EC2
+ * Instance Metadata Service using the {@link InstanceProfileCredentialsProvider}.
+ * </li>
+ * </ol>
+ */
+public class EC2ContainerCredentialsProviderWrapper implements AWSCredentialsProvider {
+
+ private static final Log LOG = LogFactory.getLog(EC2ContainerCredentialsProviderWrapper.class);
+
+ private final AWSCredentialsProvider provider;
+
+ public EC2ContainerCredentialsProviderWrapper() {
+ provider = initializeProvider();
+ }
+
+ private AWSCredentialsProvider initializeProvider() {
+ try {
+ if (System.getenv(ECS_CONTAINER_CREDENTIALS_PATH) != null) {
+ return new ContainerCredentialsProvider(new ECSCredentialsEndpointProvider());
+ }
+ if (System.getenv(CONTAINER_CREDENTIALS_FULL_URI) != null) {
+ return new ContainerCredentialsProvider(new FullUriCredentialsEndpointProvider());
+ }
+ return InstanceProfileCredentialsProvider.getInstance();
+ } catch (SecurityException securityException) {
+ LOG.debug("Security manager did not allow access to the ECS credentials environment variable " + ECS_CONTAINER_CREDENTIALS_PATH +
+ "or the container full URI environment variable " + CONTAINER_CREDENTIALS_FULL_URI
+ + ". Please provide access to this environment variable if you want to load credentials from ECS Container.");
+ return InstanceProfileCredentialsProvider.getInstance();
+ }
+ }
+
+ @Override
+ public AWSCredentials getCredentials() {
+ return provider.getCredentials();
+ }
+
+ @Override
+ public void refresh() {
+ provider.refresh();
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EC2CredentialsFetcher.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EC2CredentialsFetcher.java
new file mode 100644
index 0000000..4435f41
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EC2CredentialsFetcher.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Date;
+
+import com.google.gson.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.internal.CredentialsEndpointProvider;
+import com.amazonaws.internal.EC2CredentialsUtils;
+import com.amazonaws.util.DateUtils;
+
+/**
+ * Helper class that contains the common behavior of the
+ * CredentialsProviders that loads the credentials from a
+ * local endpoint on an EC2 instance.
+ */
+@SdkInternalApi
+class EC2CredentialsFetcher {
+
+ private static final Log LOG = LogFactory.getLog(EC2CredentialsFetcher.class);
+
+ /**
+ * The threshold after the last attempt to load credentials (in
+ * milliseconds) at which credentials are attempted to be refreshed.
+ */
+ private static final int REFRESH_THRESHOLD = 1000 * 60 * 60;
+
+ /**
+ * The threshold before credentials expire (in milliseconds) at which
+ * this class will attempt to load new credentials.
+ */
+ private static final int EXPIRATION_THRESHOLD = 1000 * 60 * 15;
+
+ /** The name of the Json Object that contains the access key.*/
+ private static final String ACCESS_KEY_ID = "AccessKeyId";
+
+ /** The name of the Json Object that contains the secret access key.*/
+ private static final String SECRET_ACCESS_KEY = "SecretAccessKey";
+
+ /** The name of the Json Object that contains the token.*/
+ private static final String TOKEN = "Token";
+
+ /** The current instance profile credentials */
+ private volatile AWSCredentials credentials;
+
+ /** The expiration for the current instance profile credentials */
+ private volatile Date credentialsExpiration;
+
+ /** The time of the last attempt to check for new credentials */
+ protected volatile Date lastInstanceProfileCheck;
+
+ /** Used to load the endpoint where the credentials are stored. */
+ private final CredentialsEndpointProvider credentialsEndpointProvider;
+
+ public EC2CredentialsFetcher(CredentialsEndpointProvider credentialsEndpointProvider) {
+ this.credentialsEndpointProvider = credentialsEndpointProvider;
+ }
+
+ public AWSCredentials getCredentials() {
+ if (needsToLoadCredentials())
+ fetchCredentials();
+ if (expired()) {
+ throw new SdkClientException(
+ "The credentials received have been expired");
+ }
+ return credentials;
+ }
+
+ /**
+ * Returns true if credentials are null, credentials are within expiration or
+ * if the last attempt to refresh credentials is beyond the refresh threshold.
+ */
+ protected boolean needsToLoadCredentials() {
+ if (credentials == null) return true;
+
+ if (credentialsExpiration != null) {
+ if (isWithinExpirationThreshold()) return true;
+ }
+
+ if (lastInstanceProfileCheck != null) {
+ if (isPastRefreshThreshold()) return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Fetches the credentials from the endpoint.
+ */
+ private synchronized void fetchCredentials() {
+ if (!needsToLoadCredentials()) return;
+
+ JsonElement accessKey;
+ JsonElement secretKey;
+ JsonObject node;
+ JsonElement token;
+ try {
+ lastInstanceProfileCheck = new Date();
+
+ String credentialsResponse = EC2CredentialsUtils.getInstance().readResource(
+ credentialsEndpointProvider.getCredentialsEndpoint(),
+ credentialsEndpointProvider.getRetryPolicy(),
+ credentialsEndpointProvider.getHeaders());
+
+ JsonParser parser = new JsonParser();
+
+ node = parser.parse(credentialsResponse).getAsJsonObject();
+ accessKey = node.get(ACCESS_KEY_ID);
+ secretKey = node.get(SECRET_ACCESS_KEY);
+ token = node.get(TOKEN);
+
+ if (null == accessKey || null == secretKey) {
+ throw new SdkClientException("Unable to load credentials.");
+ }
+
+ if (null != token) {
+ credentials = new BasicSessionCredentials(accessKey.getAsString(),
+ secretKey.getAsString(), token.getAsString());
+ } else {
+ credentials = new BasicAWSCredentials(accessKey.getAsString(),
+ secretKey.getAsString());
+ }
+
+ JsonElement expirationJsonNode = node.get("Expiration");
+ if (null != expirationJsonNode) {
+ /*
+ * TODO: The expiration string comes in a different format
+ * than what we deal with in other parts of the SDK, so we
+ * have to convert it to the ISO8601 syntax we expect.
+ */
+ String expiration = expirationJsonNode.getAsString();
+ expiration = expiration.replaceAll("\\+0000$", "Z");
+
+ try {
+ credentialsExpiration = DateUtils.parseISO8601Date(expiration);
+ } catch(Exception ex) {
+ handleError("Unable to parse credentials expiration date from Amazon EC2 instance", ex);
+ }
+ }
+ } catch (JsonSyntaxException e) {
+ handleError("Unable to parse response returned from service endpoint", e);
+ } catch (IOException e) {
+ handleError("Unable to load credentials from service endpoint", e);
+ } catch (URISyntaxException e) {
+ handleError("Unable to load credentials from service endpoint", e);
+ }
+ }
+
+ /**
+ * Handles reporting or throwing an error encountered while requesting
+ * credentials from the Amazon EC2 endpoint. The Service could be
+ * briefly unavailable for a number of reasons, so
+ * we need to gracefully handle falling back to valid credentials if they're
+ * available, and only throw exceptions if we really can't recover.
+ *
+ * @param errorMessage
+ * A human readable description of the error.
+ * @param e
+ * The error that occurred.
+ */
+ private void handleError(String errorMessage, Exception e) {
+ // If we don't have any valid credentials to fall back on, then throw an exception
+ if (credentials == null || expired())
+ throw new SdkClientException(errorMessage, e);
+
+ // Otherwise, just log the error and continuing using the current credentials
+ LOG.debug(errorMessage, e);
+ }
+
+ public void refresh() {
+ credentials = null;
+ }
+
+ /**
+ * Returns true if the current credentials are within the expiration
+ * threshold, and therefore, should be refreshed.
+ */
+ private boolean isWithinExpirationThreshold() {
+ return (credentialsExpiration.getTime() - System.currentTimeMillis()) < EXPIRATION_THRESHOLD;
+ }
+
+ /**
+ * Returns true if the last attempt to refresh credentials is beyond the
+ * refresh threshold, and therefore the credentials should attempt to be
+ * refreshed.
+ */
+ private boolean isPastRefreshThreshold() {
+ return (System.currentTimeMillis() - lastInstanceProfileCheck.getTime()) > REFRESH_THRESHOLD;
+ }
+
+ private boolean expired() {
+ if (credentialsExpiration != null) {
+ if (credentialsExpiration.getTime() < System.currentTimeMillis()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public Date getCredentialsExpiration() {
+ return credentialsExpiration;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName();
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EnvironmentVariableCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EnvironmentVariableCredentialsProvider.java
new file mode 100644
index 0000000..92c3ee1
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EnvironmentVariableCredentialsProvider.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import static com.amazonaws.SDKGlobalConfiguration.ACCESS_KEY_ENV_VAR;
+import static com.amazonaws.SDKGlobalConfiguration.ALTERNATE_ACCESS_KEY_ENV_VAR;
+import static com.amazonaws.SDKGlobalConfiguration.ALTERNATE_SECRET_KEY_ENV_VAR;
+import static com.amazonaws.SDKGlobalConfiguration.AWS_SESSION_TOKEN_ENV_VAR;
+import static com.amazonaws.SDKGlobalConfiguration.SECRET_KEY_ENV_VAR;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.util.StringUtils;
+
+/**
+ * {@link AWSCredentialsProvider} implementation that provides credentials by looking at the: <code>AWS_ACCESS_KEY_ID</code> (or
+ * <code>AWS_ACCESS_KEY</code>) and <code>AWS_SECRET_KEY</code> (or <code>AWS_SECRET_ACCESS_KEY</code>) environment variables. If
+ * the <code>AWS_SESSION_TOKEN</code> environment variable is also set then temporary credentials will be used.
+ */
+public class EnvironmentVariableCredentialsProvider implements AWSCredentialsProvider {
+ @Override
+ public AWSCredentials getCredentials() {
+ String accessKey = System.getenv(ACCESS_KEY_ENV_VAR);
+ if (accessKey == null) {
+ accessKey = System.getenv(ALTERNATE_ACCESS_KEY_ENV_VAR);
+ }
+
+ String secretKey = System.getenv(SECRET_KEY_ENV_VAR);
+ if (secretKey == null) {
+ secretKey = System.getenv(ALTERNATE_SECRET_KEY_ENV_VAR);
+ }
+
+ accessKey = StringUtils.trim(accessKey);
+ secretKey = StringUtils.trim(secretKey);
+ String sessionToken = StringUtils.trim(System.getenv(AWS_SESSION_TOKEN_ENV_VAR));
+
+ if (StringUtils.isNullOrEmpty(accessKey) || StringUtils.isNullOrEmpty(secretKey)) {
+
+ throw new SdkClientException(
+ "Unable to load AWS credentials from environment variables " +
+ "(" + ACCESS_KEY_ENV_VAR + " (or " + ALTERNATE_ACCESS_KEY_ENV_VAR + ") and " +
+ SECRET_KEY_ENV_VAR + " (or " + ALTERNATE_SECRET_KEY_ENV_VAR + "))");
+ }
+
+ return sessionToken == null ?
+ new BasicAWSCredentials(accessKey, secretKey)
+ :
+ new BasicSessionCredentials(accessKey, secretKey, sessionToken);
+ }
+
+ @Override
+ public void refresh() {
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName();
+ }
+}
\ No newline at end of file
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/InstanceProfileCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/InstanceProfileCredentialsProvider.java
new file mode 100644
index 0000000..762acff
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/InstanceProfileCredentialsProvider.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import com.amazonaws.AmazonClientException;
+import com.amazonaws.SDKGlobalConfiguration;
+import com.amazonaws.SdkClientException;
+import com.amazonaws.internal.CredentialsEndpointProvider;
+import com.amazonaws.internal.EC2CredentialsUtils;
+import com.amazonaws.util.EC2MetadataUtils;
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Credentials provider implementation that loads credentials from the Amazon EC2 Instance Metadata Service.
+ *
+ * <p>When using {@link InstanceProfileCredentialsProvider} with asynchronous refreshing it is
+ * <b>strongly</b> recommended to explicitly call {@link #close()} to release the async thread.</p>
+ */
+public class InstanceProfileCredentialsProvider implements AWSCredentialsProvider, Closeable {
+
+ private static final Log LOG = LogFactory.getLog(InstanceProfileCredentialsProvider.class);
+
+ /**
+ * The wait time, after which the background thread initiates a refresh to
+ * load latest credentials if needed.
+ */
+ private static final int ASYNC_REFRESH_INTERVAL_TIME_MINUTES = 1;
+
+ /**
+ * The default InstanceProfileCredentialsProvider that can be shared by
+ * multiple CredentialsProvider instance threads to shrink the amount of
+ * requests to EC2 metadata service.
+ */
+ private static final InstanceProfileCredentialsProvider INSTANCE = new InstanceProfileCredentialsProvider();
+
+ private final EC2CredentialsFetcher credentialsFetcher;
+
+ /**
+ * The executor service used for refreshing the credentials in the
+ * background.
+ */
+ private volatile ScheduledExecutorService executor;
+
+ private volatile boolean shouldRefresh = false;
+
+ /**
+ * @deprecated for the singleton method {@link #getInstance()}.
+ */
+ @Deprecated
+ public InstanceProfileCredentialsProvider() {
+ this(false);
+ }
+
+ /**
+ * Spins up a new thread to refresh the credentials asynchronously if
+ * refreshCredentialsAsync is set to true, otherwise the credentials will be
+ * refreshed from the instance metadata service synchronously,
+ *
+ * <p>It is <b>strongly</b> recommended to reuse instances of this credentials provider, especially
+ * when async refreshing is used since a background thread is created.</p>
+ *
+ * @param refreshCredentialsAsync
+ * true if credentials needs to be refreshed asynchronously else
+ * false.
+ */
+ public InstanceProfileCredentialsProvider(boolean refreshCredentialsAsync) {
+ this(refreshCredentialsAsync, true);
+ }
+
+ /**
+ * Spins up a new thread to refresh the credentials asynchronously.
+ *
+ * <p>It is <b>strongly</b> recommended to reuse instances of this credentials provider, especially
+ * when async refreshing is used since a background thread is created.</p>
+ *
+ * @param eagerlyRefreshCredentialsAsync
+ * when set to false will not attempt to refresh credentials asynchronously
+ * until after a call has been made to {@link #getCredentials()} - ensures that
+ * {@link EC2CredentialsFetcher#getCredentials()} is only hit when this CredentialProvider is actually required
+ */
+ public static InstanceProfileCredentialsProvider createAsyncRefreshingProvider(final boolean eagerlyRefreshCredentialsAsync) {
+ return new InstanceProfileCredentialsProvider(true, eagerlyRefreshCredentialsAsync);
+ }
+
+ private InstanceProfileCredentialsProvider(boolean refreshCredentialsAsync, final boolean eagerlyRefreshCredentialsAsync) {
+
+ credentialsFetcher = new EC2CredentialsFetcher(new InstanceMetadataCredentialsEndpointProvider());
+
+ if (!SDKGlobalConfiguration.isEc2MetadataDisabled()) {
+ if (refreshCredentialsAsync) {
+ executor = Executors.newScheduledThreadPool(1);
+ executor.scheduleWithFixedDelay(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ if (shouldRefresh) credentialsFetcher.getCredentials();
+ } catch (AmazonClientException ace) {
+ handleError(ace);
+ } catch (RuntimeException re) {
+ handleError(re);
+ }
+ }
+ }, 0, ASYNC_REFRESH_INTERVAL_TIME_MINUTES, TimeUnit.MINUTES);
+ }
+ }
+ }
+
+ /**
+ * Returns a singleton {@link InstanceProfileCredentialsProvider} that does not refresh credentials asynchronously.
+ *
+ * <p>
+ * See {@link #InstanceProfileCredentialsProvider(boolean)} or {@link #createAsyncRefreshingProvider(boolean)} for
+ * asynchronous credentials refreshing.
+ * </p>
+ */
+ public static InstanceProfileCredentialsProvider getInstance() {
+ return INSTANCE;
+ }
+
+ private void handleError(Throwable t) {
+ refresh();
+ LOG.error(t.getMessage(), t);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ if (executor != null) {
+ executor.shutdownNow();
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws AmazonClientException if {@link SDKGlobalConfiguration#isEc2MetadataDisabled()} is true
+ */
+ @Override
+ public AWSCredentials getCredentials() {
+ if (SDKGlobalConfiguration.isEc2MetadataDisabled()) {
+ throw new AmazonClientException("AWS_EC2_METADATA_DISABLED is set to true, not loading credentials from EC2 Instance "
+ + "Metadata service");
+ }
+ AWSCredentials creds = credentialsFetcher.getCredentials();
+ shouldRefresh = true;
+ return creds;
+ }
+
+ @Override
+ public void refresh() {
+ if (credentialsFetcher != null) {
+ credentialsFetcher.refresh();
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (executor != null) {
+ executor.shutdownNow();
+ executor = null;
+ }
+ }
+
+ private static class InstanceMetadataCredentialsEndpointProvider extends CredentialsEndpointProvider {
+ @Override
+ public URI getCredentialsEndpoint() throws URISyntaxException, IOException {
+ String host = EC2MetadataUtils.getHostAddressForEC2MetadataService();
+
+ String securityCredentialsList = EC2CredentialsUtils.getInstance().readResource(new URI(host + EC2MetadataUtils.SECURITY_CREDENTIALS_RESOURCE));
+ String[] securityCredentials = securityCredentialsList.trim().split("\n");
+ if (securityCredentials.length == 0) {
+ throw new SdkClientException("Unable to load credentials path");
+ }
+
+ return new URI(host + EC2MetadataUtils.SECURITY_CREDENTIALS_RESOURCE + securityCredentials[0]);
+ }
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/PropertiesCredentials.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/PropertiesCredentials.java
new file mode 100644
index 0000000..1adede4
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/PropertiesCredentials.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * Simple implementation AWSCredentials that reads in AWS access keys from a
+ * properties file. The AWS access key is expected to be in the "accessKey"
+ * property and the AWS secret key id is expected to be in the "secretKey"
+ * property.
+ */
+public class PropertiesCredentials implements AWSCredentials {
+
+ private final String accessKey;
+ private final String secretAccessKey;
+
+ /**
+ * Reads the specified file as a Java properties file and extracts the
+ * AWS access key from the "accessKey" property and AWS secret access
+ * key from the "secretKey" property. If the specified file doesn't
+ * contain the AWS access keys an IOException will be thrown.
+ *
+ * @param file
+ * The file from which to read the AWS credentials
+ * properties.
+ *
+ * @throws FileNotFoundException
+ * If the specified file isn't found.
+ * @throws IOException
+ * If any problems are encountered reading the AWS access
+ * keys from the specified file.
+ * @throws IllegalArgumentException
+ * If the specified properties file does not contain the
+ * required keys.
+ */
+ public PropertiesCredentials(File file) throws FileNotFoundException, IOException, IllegalArgumentException {
+ if (!file.exists()) {
+ throw new FileNotFoundException("File doesn't exist: "
+ + file.getAbsolutePath());
+ }
+
+ FileInputStream stream = new FileInputStream(file);
+ try {
+
+ Properties accountProperties = new Properties();
+ accountProperties.load(stream);
+
+ if (accountProperties.getProperty("accessKey") == null ||
+ accountProperties.getProperty("secretKey") == null) {
+ throw new IllegalArgumentException(
+ "The specified file (" + file.getAbsolutePath()
+ + ") doesn't contain the expected properties 'accessKey' "
+ + "and 'secretKey'."
+ );
+ }
+
+ accessKey = accountProperties.getProperty("accessKey");
+ secretAccessKey = accountProperties.getProperty("secretKey");
+
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * Reads the specified input stream as a stream of Java properties file
+ * content and extracts the AWS access key ID and secret access key from the
+ * properties.
+ *
+ * @param inputStream
+ * The input stream containing the AWS credential properties.
+ *
+ * @throws IOException
+ * If any problems occur while reading from the input stream.
+ */
+ public PropertiesCredentials(InputStream inputStream) throws IOException {
+ Properties accountProperties = new Properties();
+ try {
+ accountProperties.load(inputStream);
+ } finally {
+ try {inputStream.close();} catch (Exception e) {}
+ }
+
+ if (accountProperties.getProperty("accessKey") == null ||
+ accountProperties.getProperty("secretKey") == null) {
+ throw new IllegalArgumentException("The specified properties data " +
+ "doesn't contain the expected properties 'accessKey' and 'secretKey'.");
+ }
+
+ accessKey = accountProperties.getProperty("accessKey");
+ secretAccessKey = accountProperties.getProperty("secretKey");
+ }
+
+ /* (non-Javadoc)
+ * @see com.amazonaws.auth.AWSCredentials#getAWSAccessKeyId()
+ */
+ public String getAWSAccessKeyId() {
+ return accessKey;
+ }
+
+ /* (non-Javadoc)
+ * @see com.amazonaws.auth.AWSCredentials#getAWSSecretKey()
+ */
+ public String getAWSSecretKey() {
+ return secretAccessKey;
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/PropertiesFileCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/PropertiesFileCredentialsProvider.java
new file mode 100644
index 0000000..d7023bd
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/PropertiesFileCredentialsProvider.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import com.amazonaws.SdkClientException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * {@link AWSCredentialsProvider} implementation that loads AWS security
+ * credentials from a properties file provided on initialization.
+ * <p>
+ * The AWS access key ID is expected to be in the <code>accessKey</code>
+ * property and the AWS secret key is expected to be in the
+ * <code>secretKey</code> property.
+ */
+public class PropertiesFileCredentialsProvider implements
+ AWSCredentialsProvider {
+
+ private final String credentialsFilePath;
+
+ /**
+ * Creates a new PropertiesFileCredentialsProvider that will attempt to load
+ * a custom file from the path specified to read AWS security credentials.
+ *
+ * @param credentialsFilePath
+ * The custom classpath resource path to a properties file from
+ * which the AWS security credentials should be loaded.
+ *
+ * For example,
+ * <ul>
+ * <li>/etc/somewhere/credentials.properties</li>
+ * </ul>
+ */
+ public PropertiesFileCredentialsProvider(String credentialsFilePath) {
+ if (credentialsFilePath == null)
+ throw new IllegalArgumentException(
+ "Credentials file path cannot be null");
+ this.credentialsFilePath = credentialsFilePath;
+ }
+
+ public AWSCredentials getCredentials() {
+ try {
+ return new PropertiesCredentials(new File(this.credentialsFilePath));
+ } catch (IOException e) {
+ throw new SdkClientException(
+ "Unable to load AWS credentials from the "
+ + credentialsFilePath + " file", e);
+ }
+ }
+
+ public void refresh() {
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "(" + credentialsFilePath + ")";
+ }
+}
\ No newline at end of file
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SystemPropertiesCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SystemPropertiesCredentialsProvider.java
new file mode 100644
index 0000000..63d6a19
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SystemPropertiesCredentialsProvider.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth;
+
+import static com.amazonaws.SDKGlobalConfiguration.ACCESS_KEY_SYSTEM_PROPERTY;
+import static com.amazonaws.SDKGlobalConfiguration.SECRET_KEY_SYSTEM_PROPERTY;
+import static com.amazonaws.SDKGlobalConfiguration.SESSION_TOKEN_SYSTEM_PROPERTY;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.util.StringUtils;
+
+/**
+ * {@link AWSCredentialsProvider} implementation that provides credentials by
+ * looking at the <code>aws.accessKeyId</code> and <code>aws.secretKey</code>
+ * Java system properties.
+ */
+public class SystemPropertiesCredentialsProvider implements AWSCredentialsProvider {
+
+ @Override
+ public AWSCredentials getCredentials() {
+ String accessKey = StringUtils.trim(System.getProperty(ACCESS_KEY_SYSTEM_PROPERTY));
+ String secretKey = StringUtils.trim(System.getProperty(SECRET_KEY_SYSTEM_PROPERTY));
+ String sessionToken = StringUtils.trim(System.getProperty(SESSION_TOKEN_SYSTEM_PROPERTY));
+
+ if (StringUtils.isNullOrEmpty(accessKey) || StringUtils.isNullOrEmpty(secretKey)) {
+ throw new SdkClientException(
+ "Unable to load AWS credentials from Java system "
+ + "properties (" + ACCESS_KEY_SYSTEM_PROPERTY + " and "
+ + SECRET_KEY_SYSTEM_PROPERTY + ")");
+ }
+ if (StringUtils.isNullOrEmpty(sessionToken)) {
+ return new BasicAWSCredentials(accessKey, secretKey);
+ } else {
+ return new BasicSessionCredentials(accessKey, secretKey, sessionToken);
+ }
+ }
+
+ @Override
+ public void refresh() {
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName();
+ }
+}
\ No newline at end of file
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfileCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfileCredentialsProvider.java
new file mode 100644
index 0000000..310a951
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfileCredentialsProvider.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.profile.internal.AwsProfileNameLoader;
+
+import java.util.concurrent.Semaphore;
+
+/**
+ * Credentials provider based on AWS configuration profiles. This provider vends AWSCredentials from
+ * the profile configuration file for the default profile, or for a specific, named profile. <p> AWS
+ * credential profiles allow you to share multiple sets of AWS security credentials between
+ * different tools like the AWS SDK for Java and the AWS CLI. <p> See
+ * http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
+ *
+ * @see ProfilesConfigFile
+ */
+public class ProfileCredentialsProvider implements AWSCredentialsProvider {
+
+ /**
+ * Default refresh interval
+ */
+ private static final long DEFAULT_REFRESH_INTERVAL_NANOS = 5 * 60 * 1000 * 1000 * 1000L;
+
+ /**
+ * Default force reload interval
+ */
+ private static final long DEFAULT_FORCE_RELOAD_INTERVAL_NANOS =
+ 2 * DEFAULT_REFRESH_INTERVAL_NANOS;
+
+ /**
+ * The credential profiles file from which this provider loads the security credentials. Lazily
+ * loaded by the double-check idiom.
+ */
+ private volatile ProfilesConfigFile profilesConfigFile;
+
+ /**
+ * When the profiles file was last refreshed.
+ */
+ private volatile long lastRefreshed;
+
+ /**
+ * The name of the credential profile
+ */
+ private final String profileName;
+
+ /**
+ * Used to have only one thread block on refresh, for applications making at least one call
+ * every REFRESH_INTERVAL_NANOS.
+ */
+ private final Semaphore refreshSemaphore = new Semaphore(1);
+
+ /**
+ * Refresh interval. Defaults to {@link #DEFAULT_REFRESH_INTERVAL_NANOS}
+ */
+ private long refreshIntervalNanos = DEFAULT_REFRESH_INTERVAL_NANOS;
+
+ /**
+ * Force reload interval. Defaults to {@link #DEFAULT_FORCE_RELOAD_INTERVAL_NANOS}
+ */
+ private long refreshForceIntervalNanos = DEFAULT_FORCE_RELOAD_INTERVAL_NANOS;
+
+ /**
+ * Creates a new profile credentials provider that returns the AWS security credentials
+ * configured for the default profile. Loading the credential file is deferred until the
+ * getCredentials() method is called.
+ */
+ public ProfileCredentialsProvider() {
+ this(null);
+ }
+
+ /**
+ * Creates a new profile credentials provider that returns the AWS security credentials
+ * configured for the named profile. Loading the credential file is deferred until the
+ * getCredentials() method is called.
+ *
+ * @param profileName The name of a local configuration profile.
+ */
+ public ProfileCredentialsProvider(String profileName) {
+ this((ProfilesConfigFile) null, profileName);
+ }
+
+ /**
+ * Creates a new profile credentials provider that returns the AWS security credentials for the
+ * specified profiles configuration file and profile name.
+ *
+ * @param profilesConfigFilePath The file path where the profile configuration file is located.
+ * @param profileName The name of a configuration profile in the specified
+ * configuration file.
+ */
+ public ProfileCredentialsProvider(String profilesConfigFilePath, String profileName) {
+ this(new ProfilesConfigFile(profilesConfigFilePath), profileName);
+ }
+
+ /**
+ * Creates a new profile credentials provider that returns the AWS security credentials for the
+ * specified profiles configuration file and profile name.
+ *
+ * @param profilesConfigFile The profile configuration file containing the profiles used by this
+ * credentials provider or null to defer load to first use.
+ * @param profileName The name of a configuration profile in the specified configuration
+ * file.
+ */
+ public ProfileCredentialsProvider(ProfilesConfigFile profilesConfigFile, String profileName) {
+ this.profilesConfigFile = profilesConfigFile;
+ if (this.profilesConfigFile != null) {
+ this.lastRefreshed = System.nanoTime();
+ }
+ if (profileName == null) {
+ this.profileName = AwsProfileNameLoader.INSTANCE.loadProfileName();
+ } else {
+ this.profileName = profileName;
+ }
+ }
+
+ @Override
+ public AWSCredentials getCredentials() {
+ if (profilesConfigFile == null) {
+ synchronized (this) {
+ if (profilesConfigFile == null) {
+ profilesConfigFile = new ProfilesConfigFile();
+ lastRefreshed = System.nanoTime();
+ }
+ }
+ }
+
+ // Periodically check if the file on disk has been modified
+ // since we last read it.
+ //
+ // For active applications, only have one thread block.
+ // For applications that use this method in bursts, ensure the
+ // credentials are never too stale.
+ long now = System.nanoTime();
+ long age = now - lastRefreshed;
+ if (age > refreshForceIntervalNanos) {
+ refresh();
+ } else if (age > refreshIntervalNanos) {
+ if (refreshSemaphore.tryAcquire()) {
+ try {
+ refresh();
+ } finally {
+ refreshSemaphore.release();
+ }
+ }
+ }
+
+ return profilesConfigFile.getCredentials(profileName);
+ }
+
+ @Override
+ public void refresh() {
+ if (profilesConfigFile != null) {
+ profilesConfigFile.refresh();
+ lastRefreshed = System.nanoTime();
+ }
+ }
+
+ /**
+ * Gets the refresh interval in nanoseconds.
+ *
+ * @return nanoseconds
+ */
+ public long getRefreshIntervalNanos() {
+ return refreshIntervalNanos;
+ }
+
+ /**
+ * Sets the refresh interval in nanoseconds.
+ *
+ * @param refreshIntervalNanos nanoseconds
+ */
+ public void setRefreshIntervalNanos(long refreshIntervalNanos) {
+ this.refreshIntervalNanos = refreshIntervalNanos;
+ }
+
+ /**
+ * Gets the forced refresh interval in nanoseconds.
+ *
+ * @return nanoseconds
+ */
+ public long getRefreshForceIntervalNanos() {
+ return refreshForceIntervalNanos;
+ }
+
+ /**
+ * Sets the forced refresh interval in nanoseconds.
+ */
+ public void setRefreshForceIntervalNanos(long refreshForceIntervalNanos) {
+ this.refreshForceIntervalNanos = refreshForceIntervalNanos;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfilesConfigFile.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfilesConfigFile.java
new file mode 100644
index 0000000..abaf0053
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfilesConfigFile.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.profile.internal.AllProfiles;
+import com.amazonaws.auth.profile.internal.AwsProfileNameLoader;
+import com.amazonaws.auth.profile.internal.BasicProfile;
+import com.amazonaws.auth.profile.internal.BasicProfileConfigLoader;
+import com.amazonaws.auth.profile.internal.Profile;
+import com.amazonaws.auth.profile.internal.ProfileAssumeRoleCredentialsProvider;
+import com.amazonaws.auth.profile.internal.ProfileStaticCredentialsProvider;
+import com.amazonaws.auth.profile.internal.securitytoken.ProfileCredentialsService;
+import com.amazonaws.auth.profile.internal.securitytoken.STSProfileCredentialsServiceLoader;
+import com.amazonaws.internal.StaticCredentialsProvider;
+import com.amazonaws.profile.path.AwsProfileFileLocationProvider;
+import com.google.common.base.Preconditions;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Loads the local AWS credential profiles from the standard location (~/.aws/credentials), which
+ * can be easily overridden through the <code>AWS_CREDENTIAL_PROFILES_FILE</code> environment
+ * variable or by specifying an alternate credentials file location through this class' constructor.
+ * <p> The AWS credentials file format allows you to specify multiple profiles, each with their own
+ * set of AWS security credentials:
+ * <pre>
+ * [default]
+ * aws_access_key_id=testAccessKey
+ * aws_secret_access_key=testSecretKey
+ * aws_session_token=testSessionToken
+ *
+ * [test-user]
+ * aws_access_key_id=testAccessKey
+ * aws_secret_access_key=testSecretKey
+ * aws_session_token=testSessionToken
+ * </pre>
+ *
+ * <p> These credential profiles allow you to share multiple sets of AWS security credentails
+ * between different tools such as the AWS SDK for Java and the AWS CLI.
+ *
+ * <p> For more information on setting up AWS credential profiles, see:
+ * http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
+ *
+ * @see ProfileCredentialsProvider
+ */
+public class ProfilesConfigFile {
+
+ /**
+ * Environment variable name for overriding the default AWS profile
+ */
+ @Deprecated
+ public static final String AWS_PROFILE_ENVIRONMENT_VARIABLE = AwsProfileNameLoader.AWS_PROFILE_ENVIRONMENT_VARIABLE;
+
+ /**
+ * System property name for overriding the default AWS profile
+ */
+ @Deprecated
+ public static final String AWS_PROFILE_SYSTEM_PROPERTY = AwsProfileNameLoader.AWS_PROFILE_SYSTEM_PROPERTY;
+
+ /**
+ * Name of the default profile as specified in the configuration file.
+ */
+ @Deprecated
+ public static final String DEFAULT_PROFILE_NAME = AwsProfileNameLoader.DEFAULT_PROFILE_NAME;
+
+ private final File profileFile;
+ private final ProfileCredentialsService profileCredentialsService;
+ /**
+ * Cache credential providers as credentials from profiles are requested. Doesn't really make a
+ * difference for basic credentials but for assume role it's more efficient as each assume role
+ * provider has it's own async refresh logic.
+ */
+ private final ConcurrentHashMap<String, AWSCredentialsProvider> credentialProviderCache = new ConcurrentHashMap<String, AWSCredentialsProvider>();
+ private volatile AllProfiles allProfiles;
+ private volatile long profileFileLastModified;
+
+ /**
+ * Loads the AWS credential profiles file from the default location (~/.aws/credentials) or from
+ * an alternate location if <code>AWS_CREDENTIAL_PROFILES_FILE</code> is set.
+ */
+ public ProfilesConfigFile() throws SdkClientException {
+ this(getCredentialProfilesFile());
+ }
+
+ /**
+ * Loads the AWS credential profiles from the file. The path of the file is specified as a
+ * parameter to the constructor.
+ */
+ public ProfilesConfigFile(String filePath) {
+ this(new File(validateFilePath(filePath)));
+ }
+
+ /**
+ * Loads the AWS credential profiles from the file. The path of the file is specified as a
+ * parameter to the constructor.
+ */
+ public ProfilesConfigFile(String filePath, ProfileCredentialsService credentialsService) throws
+ SdkClientException {
+ this(new File(validateFilePath(filePath)), credentialsService);
+ }
+
+ private static String validateFilePath(String filePath) {
+ if (filePath == null) {
+ throw new IllegalArgumentException(
+ "Unable to load AWS profiles: specified file path is null.");
+ }
+ return filePath;
+ }
+
+ /**
+ * Loads the AWS credential profiles from the file. The reference to the file is specified as a
+ * parameter to the constructor.
+ */
+ public ProfilesConfigFile(File file) throws SdkClientException {
+ this(file, STSProfileCredentialsServiceLoader.getInstance());
+ }
+
+ /**
+ * Loads the AWS credential profiles from the file. The reference to the file is specified as a
+ * parameter to the constructor.
+ */
+ public ProfilesConfigFile(File file, ProfileCredentialsService credentialsService) throws
+ SdkClientException {
+ profileFile = Preconditions.checkNotNull(file, "%s cannot be null", "profile file");
+ profileCredentialsService = credentialsService;
+ profileFileLastModified = file.lastModified();
+ allProfiles = loadProfiles(profileFile);
+ }
+
+ /**
+ * Returns the AWS credentials for the specified profile.
+ */
+ public AWSCredentials getCredentials(String profileName) {
+ final AWSCredentialsProvider provider = credentialProviderCache.get(profileName);
+ if (provider != null) {
+ return provider.getCredentials();
+ } else {
+ BasicProfile profile = allProfiles.getProfile(profileName);
+ if (profile == null) {
+ throw new IllegalArgumentException("No AWS profile named '" + profileName + "'");
+ }
+ final AWSCredentialsProvider newProvider = fromProfile(profile);
+ credentialProviderCache.put(profileName, newProvider);
+ return newProvider.getCredentials();
+ }
+ }
+
+ /**
+ * Reread data from disk.
+ */
+ public void refresh() {
+ if (profileFile.lastModified() > profileFileLastModified) {
+ profileFileLastModified = profileFile.lastModified();
+ allProfiles = loadProfiles(profileFile);
+ }
+ credentialProviderCache.clear();
+ }
+
+ public Map<String, BasicProfile> getAllBasicProfiles() {
+ return allProfiles.getProfiles();
+ }
+
+ @Deprecated
+ public Map<String, Profile> getAllProfiles() {
+ Map<String, Profile> legacyProfiles = new HashMap<String, Profile>();
+ for (Map.Entry<String, BasicProfile> entry : getAllBasicProfiles().entrySet()) {
+ final String profileName = entry.getKey();
+ legacyProfiles.put(profileName,
+ new Profile(profileName, entry.getValue().getProperties(),
+ new StaticCredentialsProvider(
+ getCredentials(profileName))));
+ }
+ return legacyProfiles;
+ }
+
+ private static File getCredentialProfilesFile() {
+ return AwsProfileFileLocationProvider.DEFAULT_CREDENTIALS_LOCATION_PROVIDER.getLocation();
+ }
+
+ private static AllProfiles loadProfiles(File file) {
+ return BasicProfileConfigLoader.INSTANCE.loadProfiles(file);
+ }
+
+ private AWSCredentialsProvider fromProfile(BasicProfile profile) {
+ if (profile.isRoleBasedProfile()) {
+ return new ProfileAssumeRoleCredentialsProvider(profileCredentialsService, allProfiles,
+ profile);
+ } else {
+ return new ProfileStaticCredentialsProvider(profile);
+ }
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfilesConfigFileWriter.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfilesConfigFileWriter.java
new file mode 100644
index 0000000..81b0336
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/ProfilesConfigFileWriter.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.auth.profile.internal.AbstractProfilesConfigFileScanner;
+import com.amazonaws.auth.profile.internal.Profile;
+import com.amazonaws.auth.profile.internal.ProfileKeyConstants;
+import com.amazonaws.util.StringUtils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * The class for creating and modifying the credential profiles file.
+ */
+public class ProfilesConfigFileWriter {
+
+ private static final Log LOG = LogFactory.getLog(ProfilesConfigFileWriter.class);
+
+ /**
+ * Write all the credential profiles to a file. Note that this method will
+ * clobber the existing content in the destination file if it's in the
+ * overwrite mode. Use {@link #modifyOrInsertProfiles(File, Profile...)}
+ * instead, if you want to perform in-place modification on your existing
+ * credentials file.
+ *
+ * @param destination
+ * The destination file where the credentials will be written to.
+ * @param overwrite
+ * If true, this method If false, this method will throw
+ * exception if the file already exists.
+ * @param profiles
+ * All the credential profiles to be written.
+ */
+ public static void dumpToFile(File destination, boolean overwrite, Profile... profiles) {
+ if (destination.exists() && !overwrite) {
+ throw new SdkClientException(
+ "The destination file already exists. " +
+ "Set overwrite=true if you want to clobber the existing " +
+ "content and completely re-write the file.");
+ }
+
+ OutputStreamWriter writer;
+ try {
+ writer = new OutputStreamWriter(new FileOutputStream(destination, false), StringUtils.UTF8);
+
+ } catch (IOException ioe) {
+ throw new SdkClientException(
+ "Unable to open the destination file.", ioe);
+ }
+
+ try {
+ final Map<String, Profile> modifications = new LinkedHashMap<String, Profile>();
+ for (Profile profile : profiles) {
+ modifications.put(profile.getProfileName(), profile);
+ }
+ ProfilesConfigFileWriterHelper writerHelper = new ProfilesConfigFileWriterHelper(writer, modifications);
+
+ writerHelper.writeWithoutExistingContent();
+ } finally {
+ try { writer.close(); } catch (IOException ioe) {}
+ }
+
+ }
+
+ /**
+ * Modify or insert new profiles into an existing credentials file by
+ * in-place modification. Only the properties of the affected profiles will
+ * be modified; all the unaffected profiles and comment lines will remain
+ * the same. This method does not support renaming a profile.
+ *
+ * @param destination
+ * The destination file to modify
+ * @param profiles
+ * All the credential profiles to be written.
+ */
+ public static void modifyOrInsertProfiles(File destination, Profile... profiles) {
+ final Map<String, Profile> modifications = new LinkedHashMap<String, Profile>();
+ for (Profile profile : profiles) {
+ modifications.put(profile.getProfileName(), profile);
+ }
+
+ modifyProfiles(destination, modifications);
+ }
+
+ /**
+ * Modify one profile in the existing credentials file by in-place
+ * modification. This method will rename the existing profile if the
+ * specified Profile has a different name.
+ *
+ * @param destination
+ * The destination file to modify
+ * @param profileName
+ * The name of the existing profile to be modified
+ * @param newProfile
+ * The new Profile object.
+ */
+ public static void modifyOneProfile(File destination, String profileName, Profile newProfile) {
+ final Map<String, Profile> modifications = Collections.singletonMap(profileName, newProfile);
+
+ modifyProfiles(destination, modifications);
+ }
+
+ /**
+ * Remove one or more profiles from the existing credentials file by
+ * in-place modification.
+ *
+ * @param destination
+ * The destination file to modify
+ * @param profileNames
+ * The names of all the profiles to be deleted.
+ */
+ public static void deleteProfiles(File destination, String... profileNames) {
+ final Map<String, Profile> modifications = new LinkedHashMap<String, Profile>();
+ for (String profileName : profileNames) {
+ modifications.put(profileName, null); // null value indicates a deletion
+ }
+
+ modifyProfiles(destination, modifications);
+ }
+
+ /**
+ * A package-private method that supports all kinds of profile modification,
+ * including renaming or deleting one or more profiles.
+ *
+ * @param modifications
+ * Use null key value to indicate a profile that is to be
+ * deleted.
+ */
+ static void modifyProfiles(File destination, Map<String, Profile> modifications) {
+ final boolean inPlaceModify = destination.exists();
+ File stashLocation = null;
+
+ // Stash the original file, before we apply the changes
+ if (inPlaceModify) {
+ boolean stashed = false;
+
+ try {
+ // We can't use File.createTempFile, since it will always create
+ // that file no matter what, and File.reNameTo does not allow
+ // the destination to be an existing file
+ stashLocation = new File(destination.getParentFile(),
+ destination.getName() + ".bak."
+ + UUID.randomUUID().toString());
+ stashed = destination.renameTo(stashLocation);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String
+ .format("The original credentials file is stashed to loaction (%s).",
+ stashLocation.getAbsolutePath()));
+ }
+
+ } finally {
+ if (!stashed) {
+ throw new SdkClientException(
+ "Failed to stash the existing credentials file " +
+ "before applying the changes.");
+ }
+ }
+ }
+
+ OutputStreamWriter writer = null;
+ try {
+ writer = new OutputStreamWriter(new FileOutputStream(destination), StringUtils.UTF8);
+ ProfilesConfigFileWriterHelper writerHelper = new ProfilesConfigFileWriterHelper(writer, modifications);
+
+ if (inPlaceModify) {
+ Scanner existingContent = new Scanner(stashLocation, StringUtils.UTF8.name());
+ writerHelper.writeWithExistingContent(existingContent);
+ } else {
+ writerHelper.writeWithoutExistingContent();
+ }
+
+ // Make sure the output is valid and can be loaded by the loader
+ new ProfilesConfigFile(destination);
+
+ if ( inPlaceModify && !stashLocation.delete() ) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String
+ .format("Successfully modified the credentials file. But failed to " +
+ "delete the stashed copy of the original file (%s).",
+ stashLocation.getAbsolutePath()));
+ }
+ }
+
+ } catch (Exception e) {
+ // Restore the stashed file
+ if (inPlaceModify) {
+ boolean restored = false;
+
+ try {
+ // We don't really care about what destination.delete()
+ // returns, since the file might not have been created when
+ // the error occurred.
+ if ( !destination.delete() ) {
+ LOG.debug("Unable to remove the credentials file "
+ + "before restoring the original one.");
+ }
+ restored = stashLocation.renameTo(destination);
+ } finally {
+ if (!restored) {
+ throw new SdkClientException(
+ "Unable to restore the original credentials file. " +
+ "File content stashed in " + stashLocation.getAbsolutePath());
+ }
+ }
+ }
+
+ throw new SdkClientException(
+ "Unable to modify the credentials file. " +
+ "(The original file has been restored.)",
+ e);
+
+ } finally {
+ try {
+ if (writer != null) writer.close();
+ } catch (IOException e) {}
+ }
+ }
+
+ /**
+ * Implementation of AbstractProfilesConfigFileScanner, which reads the
+ * content from an existing credentials file (if any) and then modifies some
+ * of the profile properties in place.
+ */
+ private static class ProfilesConfigFileWriterHelper extends AbstractProfilesConfigFileScanner {
+
+ /** The writer where the modified profiles will be output to */
+ private final Writer writer;
+
+ /** Map of all the profiles to be modified, keyed by profile names */
+ private final Map<String, Profile> newProfiles = new LinkedHashMap<String, Profile>();
+
+ /** Map of the names of all the profiles to be deleted */
+ private final Set<String> deletedProfiles= new HashSet<String>();
+
+ private final StringBuilder buffer = new StringBuilder();
+ private final Map<String, Set<String>> existingProfileProperties = new HashMap<String, Set<String>>();
+
+ /**
+ * Creates ProfilesConfigFileWriterHelper with the specified new
+ * profiles.
+ *
+ * @param writer
+ * The writer where the modified content is output to.
+ * @param modifications
+ * A map of all the new profiles, keyed by the profile name.
+ * If a profile name is associated with a null value, it's
+ * profile content will be removed.
+ */
+ public ProfilesConfigFileWriterHelper(Writer writer, Map<String, Profile> modifications) {
+ this.writer = writer;
+
+ for (Entry<String, Profile> entry : modifications.entrySet()) {
+ String profileName = entry.getKey();
+ Profile profile = entry.getValue();
+
+ if (profile == null) {
+ deletedProfiles.add(profileName);
+ } else {
+ newProfiles.put(profileName, profile);
+ }
+ }
+ }
+
+ /**
+ * Append the new profiles to the writer, by reading from empty content.
+ */
+ public void writeWithoutExistingContent() {
+ buffer.setLength(0);
+ existingProfileProperties.clear();
+
+ // Use empty String as input, since we are bootstrapping a new file.
+ run(new Scanner(""));
+ }
+
+ /**
+ * Read the existing content of a credentials file, and then make
+ * in-place modification according to the new profiles specified in this
+ * class.
+ */
+ public void writeWithExistingContent(Scanner existingContent) {
+ buffer.setLength(0);
+ existingProfileProperties.clear();
+
+ run(existingContent);
+ }
+
+ @Override
+ protected void onEmptyOrCommentLine(String profileName, String line) {
+ /*
+ * Buffer the line until we reach the next property line or the end
+ * of the profile. We do this so that new properties could be
+ * inserted at more appropriate location. For example:
+ *
+ * [default]
+ * # access key
+ * aws_access_key_id=aaa
+ * # secret key
+ * aws_secret_access_key=sss
+ * # We want new properties to be inserted before this line
+ * # instead of after the following empty line
+ *
+ * [next profile]
+ * ...
+ */
+ if (profileName == null || !deletedProfiles.contains(profileName)) {
+ buffer(line);
+ }
+ }
+
+ @Override
+ protected void onProfileStartingLine(String profileName, String line) {
+ existingProfileProperties.put(profileName, new HashSet<String>());
+
+ // Copy the line after flush the buffer
+ flush();
+
+ if (deletedProfiles.contains(profileName))
+ return;
+
+ // If the profile name is changed
+ if (newProfiles.get(profileName) != null) {
+ String newProfileName = newProfiles.get(profileName).getProfileName();
+ if ( !newProfileName.equals(profileName) ) {
+ line = "[" + newProfileName + "]";
+ }
+ }
+
+ writeLine(line);
+ }
+
+ @Override
+ protected void onProfileEndingLine(String prevProfileName) {
+ // Check whether we need to insert new properties into this profile
+ Profile modifiedProfile = newProfiles.get(prevProfileName);
+ if (modifiedProfile != null) {
+ for (Entry<String, String> entry : modifiedProfile.getProperties().entrySet()) {
+ String propertyKey = entry.getKey();
+ String propertyValue = entry.getValue();
+ if ( !existingProfileProperties.get(prevProfileName).contains(propertyKey) ) {
+ writeProperty(propertyKey, propertyValue);
+ }
+ }
+ }
+
+ // flush all the buffered comments and empty lines
+ flush();
+ }
+
+ @Override
+ protected void onProfileProperty(String profileName,
+ String propertyKey, String propertyValue,
+ boolean isSupportedProperty, String line) {
+ // Record that this property key has been declared for this profile
+ if (existingProfileProperties.get(profileName) == null) {
+ existingProfileProperties.put(profileName, new HashSet<String>());
+ }
+ existingProfileProperties.get(profileName).add(propertyKey);
+
+ if (deletedProfiles.contains(profileName))
+ return;
+
+ // Keep the unsupported properties
+ if ( !isSupportedProperty ) {
+ writeLine(line);
+ return;
+ }
+
+ // flush all the buffered comments and empty lines before this property line
+ flush();
+
+ // Modify the property value
+ if (newProfiles.containsKey(profileName)) {
+ String newValue = newProfiles.get(profileName)
+ .getPropertyValue(propertyKey);
+ if (newValue != null) {
+ writeProperty(propertyKey, newValue);
+ }
+ // else remove that line
+ } else {
+ writeLine(line);
+ }
+
+ }
+
+ @Override
+ protected void onEndOfFile() {
+ // Append profiles that don't exist in the original file
+ for (Entry<String, Profile> entry : newProfiles.entrySet()) {
+ String profileName = entry.getKey();
+ Profile profile = entry.getValue();
+
+ if ( !existingProfileProperties.containsKey(profileName) ) {
+ // The profile name is not found in the file
+ // Append the profile properties
+ writeProfile(profile);
+ writeLine("");
+ }
+ }
+
+ // Flush the "real" writer
+ try {
+ writer.flush();
+ } catch (IOException ioe) {
+ throw new SdkClientException(
+ "Unable to write to the target file to persist the profile credentials.",
+ ioe);
+ }
+ }
+
+ /**
+ * ProfilesConfigFileWriter still deals with legacy {@link Profile} interface so it can only
+ * modify credential related properties. All other properties should be preserved when
+ * modifying profiles.
+ */
+ @Override
+ protected boolean isSupportedProperty(String propertyName) {
+ return ProfileKeyConstants.AWS_ACCESS_KEY_ID.equals(propertyName) ||
+ ProfileKeyConstants.AWS_SECRET_ACCESS_KEY.equals(propertyName) ||
+ ProfileKeyConstants.AWS_SESSION_TOKEN.equals(propertyName) ||
+ ProfileKeyConstants.EXTERNAL_ID.equals(propertyName) ||
+ ProfileKeyConstants.ROLE_ARN.equals(propertyName) ||
+ ProfileKeyConstants.ROLE_SESSION_NAME.equals(propertyName) ||
+ ProfileKeyConstants.SOURCE_PROFILE.equals(propertyName);
+ }
+
+ /* Private interface */
+
+ private void writeProfile(Profile profile) {
+ writeProfileName(profile.getProfileName());
+
+ for (Entry<String, String> entry : profile.getProperties().entrySet()) {
+ writeProperty(entry.getKey(), entry.getValue());
+ }
+ }
+
+ private void writeProfileName(String profileName) {
+ writeLine(String.format("[%s]", profileName));
+ }
+
+ private void writeProperty(String propertyKey, String propertyValue) {
+ writeLine(String.format("%s=%s", propertyKey, propertyValue));
+ }
+
+ private void writeLine(String line) {
+ append(String.format("%s%n", line));
+ }
+
+ /**
+ * This method handles IOException that occurs when calling the append
+ * method on the writer.
+ */
+ private void append(String str) {
+ try {
+ writer.append(str);
+ } catch (IOException ioe) {
+ throw new SdkClientException(
+ "Unable to write to the target file to persist the profile credentials.",
+ ioe);
+ }
+ }
+
+ private void flush() {
+ if (buffer.length() != 0) {
+ append(buffer.toString());
+ buffer.setLength(0);
+ }
+ }
+
+ private void buffer(String line) {
+ buffer.append(String.format("%s%n", line));
+ }
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AbstractProfilesConfigFileScanner.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AbstractProfilesConfigFileScanner.java
new file mode 100644
index 0000000..32997a3
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AbstractProfilesConfigFileScanner.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import java.util.AbstractMap;
+import java.util.Map.Entry;
+import java.util.Scanner;
+
+/**
+ * An abstract template class for the generic operation that involves scanning
+ * through a profile configuration file. Subclass should implement the abstract
+ * methods to define the actions when different components of the profiles file
+ * are detected.
+ */
+public abstract class AbstractProfilesConfigFileScanner {
+
+ /**
+ * Action to be performed when an empty or comment line is detected
+ */
+ protected abstract void onEmptyOrCommentLine(String profileName, String line);
+
+ /**
+ * Action to be performed when the starting line of a new profile is detected
+ */
+ protected abstract void onProfileStartingLine(String newProfileName, String line);
+
+ /**
+ * Action to be performed when the scanner reaches the end of a profile
+ * section. This method is invoked either at the start of a new profile
+ * section, or at the end of the file.
+ */
+ protected abstract void onProfileEndingLine(String prevProfileName);
+
+ /**
+ * Action to be performed when the scanner reaches the end of the
+ * credentials file.
+ */
+ protected abstract void onEndOfFile();
+
+ /**
+ * Action to be performed when a property declaration is detected inside a
+ * profile section.
+ *
+ * @param profileName
+ * The name of the profile where this property is declared.
+ * @param propertyName
+ * The name of the property.
+ * @param propertyValue
+ * The value of the property.
+ * @param isSupportedProperty
+ * Whether this is a supported property according to the
+ * specification of credential profiles file.
+ * @param line
+ * The original line of text where the property is declared.
+ */
+ protected abstract void onProfileProperty(String profileName,
+ String propertyName,
+ String propertyValue,
+ boolean isSupportedProperty,
+ String line);
+
+ /**
+ * Hook to allow subclasses to determine which properties are supported and which aren't.
+ *
+ * @return True if property is supported by scanner implementation, false otherwise.
+ */
+ protected boolean isSupportedProperty(String propertyName) {
+ return true;
+ }
+
+ /**
+ * Scan through the given input, and perform the defined actions.
+ *
+ * @param scanner
+ * The scanner for the credentials file input.
+ */
+ protected void run(Scanner scanner) {
+ String currentProfileName = null;
+
+ try {
+ while(scanner.hasNextLine()) {
+ String line = scanner.nextLine().trim();
+
+ // Empty or comment lines
+ if (line.isEmpty() || line.startsWith("#")) {
+ onEmptyOrCommentLine(currentProfileName, line);
+ continue;
+ }
+
+ // parseGroupName returns null if this line does not
+ // indicate a new property group.
+ String newProfileName = parseProfileName(line);
+ boolean atNewProfileStartingLine = newProfileName != null;
+
+ if (atNewProfileStartingLine) {
+ if (currentProfileName != null) {
+ onProfileEndingLine(currentProfileName);
+ }
+ onProfileStartingLine(newProfileName, line);
+
+ // Start the new profile
+ currentProfileName = newProfileName;
+ } else {
+ // Parse the property line
+ Entry<String, String> property = parsePropertyLine(line);
+
+ if (currentProfileName == null) {
+ throw new IllegalArgumentException(
+ "Property is defined without a preceding profile name. "
+ + "Current line: " + line);
+ }
+
+ onProfileProperty(currentProfileName,
+ property.getKey(),
+ property.getValue(),
+ isSupportedProperty(property.getKey()),
+ line);
+ }
+ }
+
+ // EOF
+ if (currentProfileName != null) {
+ onProfileEndingLine(currentProfileName);
+ }
+
+ onEndOfFile();
+
+ } finally {
+ scanner.close();
+ }
+ }
+
+
+ /**
+ * Returns the profile name if this line indicates the beginning of a new
+ * profile section. Otherwise, returns null.
+ */
+ private static String parseProfileName(String trimmedLine) {
+ if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
+ String profileName = trimmedLine.substring(1, trimmedLine.length() - 1);
+ return profileName.trim();
+ }
+ return null;
+ }
+
+ private static Entry<String, String> parsePropertyLine(String propertyLine) {
+ String[] pair = propertyLine.split("=", 2);
+ if (pair.length != 2) {
+ throw new IllegalArgumentException(
+ "Invalid property format: no '=' character is found in the line ["
+ + propertyLine + "].");
+ }
+
+ String propertyKey = pair[0].trim();
+ String propertyValue = pair[1].trim();
+
+ return new AbstractMap.SimpleImmutableEntry<String, String>(propertyKey, propertyValue);
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AllProfiles.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AllProfiles.java
new file mode 100644
index 0000000..a18e43b
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AllProfiles.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import com.amazonaws.annotation.Immutable;
+import com.amazonaws.annotation.SdkInternalApi;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Simple wrapper around a map of profiles.
+ */
+@Immutable
+@SdkInternalApi
+public class AllProfiles {
+
+ private final Map<String, BasicProfile> profiles;
+
+ public AllProfiles(Map<String, BasicProfile> profiles) {
+ this.profiles = profiles;
+ }
+
+ public Map<String, BasicProfile> getProfiles() {
+ return Collections.unmodifiableMap(profiles);
+ }
+
+ public BasicProfile getProfile(String profileName) {
+ return profiles.get(profileName);
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AwsProfileNameLoader.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AwsProfileNameLoader.java
new file mode 100644
index 0000000..994ebbe
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/AwsProfileNameLoader.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import com.amazonaws.annotation.Immutable;
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.util.StringUtils;
+
+/**
+ * Loads profile name from the usual places or uses the default profile name.
+ */
+@SdkInternalApi
+@Immutable
+public class AwsProfileNameLoader {
+
+ /**
+ * Name of the default profile as specified in the configuration file.
+ */
+ public static final String DEFAULT_PROFILE_NAME = "default";
+
+ /**
+ * Environment variable name for overriding the default AWS profile
+ */
+ public static final String AWS_PROFILE_ENVIRONMENT_VARIABLE = "AWS_PROFILE";
+
+ /**
+ * System property name for overriding the default AWS profile
+ */
+ public static final String AWS_PROFILE_SYSTEM_PROPERTY = "aws.profile";
+
+ public static final AwsProfileNameLoader INSTANCE = new AwsProfileNameLoader();
+
+ private AwsProfileNameLoader() {
+ }
+
+ /**
+ * TODO The order would make more sense as System Property, Environment Variable, Default
+ * Profile name but we have to keep the current order for backwards compatiblity. Consider
+ * changing this in a future major version.
+ */
+ public final String loadProfileName() {
+ final String profileEnvVarOverride = getEnvProfileName();
+ if (!StringUtils.isNullOrEmpty(profileEnvVarOverride)) {
+ return profileEnvVarOverride;
+ } else {
+ final String profileSysPropOverride = getSysPropertyProfileName();
+ if (!StringUtils.isNullOrEmpty(profileSysPropOverride)) {
+ return profileSysPropOverride;
+ } else {
+ return DEFAULT_PROFILE_NAME;
+ }
+ }
+ }
+
+ private String getSysPropertyProfileName() {
+ return StringUtils.trim(System.getProperty(AWS_PROFILE_SYSTEM_PROPERTY));
+ }
+
+ private String getEnvProfileName() {
+ return StringUtils.trim(System.getenv(AWS_PROFILE_ENVIRONMENT_VARIABLE));
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/BasicProfile.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/BasicProfile.java
new file mode 100644
index 0000000..3f9d7e4
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/BasicProfile.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import com.amazonaws.annotation.Immutable;
+import com.amazonaws.annotation.SdkInternalApi;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Represents a CLI style config profile with a name and simple properties. Provides convenient
+ * access to the properties the Java SDK deals with and also raw access to all properties.
+ */
+@Immutable
+@SdkInternalApi
+public class BasicProfile {
+
+
+ private final String profileName;
+ private final Map<String, String> properties;
+
+ public BasicProfile(String profileName,
+ Map<String, String> properties) {
+ this.profileName = profileName;
+ this.properties = properties;
+ }
+
+ /**
+ * @return The name of this profile.
+ */
+ public String getProfileName() {
+ return profileName;
+ }
+
+ /**
+ * Returns a map of profile properties included in this Profile instance. The returned
+ * properties corresponds to how this profile is described in the credential profiles file,
+ * i.e., profiles with basic credentials consist of two properties {"aws_access_key_id",
+ * "aws_secret_access_key"} and profiles with session credentials have three properties, with an
+ * additional "aws_session_token" property.
+ */
+ public Map<String, String> getProperties() {
+ return Collections.unmodifiableMap(properties);
+ }
+
+ /**
+ * Returns the value of a specific property that is included in this Profile instance.
+ *
+ * @see BasicProfile#getProperties()
+ */
+ public String getPropertyValue(String propertyName) {
+ return getProperties().get(propertyName);
+ }
+
+ public String getAwsAccessIdKey() {
+ return getPropertyValue(ProfileKeyConstants.AWS_ACCESS_KEY_ID);
+ }
+
+ public String getAwsSecretAccessKey() {
+ return getPropertyValue(ProfileKeyConstants.AWS_SECRET_ACCESS_KEY);
+ }
+
+ public String getAwsSessionToken() {
+ return getPropertyValue(ProfileKeyConstants.AWS_SESSION_TOKEN);
+ }
+
+ public String getRoleArn() {
+ return getPropertyValue(ProfileKeyConstants.ROLE_ARN);
+ }
+
+ public String getRoleSourceProfile() {
+ return getPropertyValue(ProfileKeyConstants.SOURCE_PROFILE);
+ }
+
+ public String getRoleSessionName() {
+ return getPropertyValue(ProfileKeyConstants.ROLE_SESSION_NAME);
+ }
+
+ public String getRoleExternalId() {
+ return getPropertyValue(ProfileKeyConstants.EXTERNAL_ID);
+ }
+
+ public String getRegion() {
+ return getPropertyValue(ProfileKeyConstants.REGION);
+ }
+
+ public boolean isRoleBasedProfile() {
+ return getRoleArn() != null;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/BasicProfileConfigLoader.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/BasicProfileConfigLoader.java
new file mode 100644
index 0000000..8f8d2f5
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/BasicProfileConfigLoader.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.util.StringUtils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Scanner;
+
+/**
+ * Class to load a CLI style config or credentials file. Performs only basic validation on
+ * properties and profiles.
+ */
+@SdkInternalApi
+public class BasicProfileConfigLoader {
+
+ private static final Log LOG = LogFactory.getLog(BasicProfileConfigLoader.class);
+
+ public static final BasicProfileConfigLoader INSTANCE = new BasicProfileConfigLoader();
+
+ private BasicProfileConfigLoader() {
+ }
+
+ public AllProfiles loadProfiles(File file) {
+ if (file == null) {
+ throw new IllegalArgumentException(
+ "Unable to load AWS profiles: specified file is null.");
+ }
+
+ if (!file.exists() || !file.isFile()) {
+ throw new IllegalArgumentException(
+ "AWS credential profiles file not found in the given path: " +
+ file.getAbsolutePath());
+ }
+
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(file);
+ return loadProfiles(fis);
+ } catch (IOException ioe) {
+ throw new SdkClientException(
+ "Unable to load AWS credential profiles file at: " + file.getAbsolutePath(),
+ ioe);
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (IOException ioe) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Loads the credential profiles from the given input stream.
+ *
+ * @param is input stream from where the profile details are read.
+ */
+ private AllProfiles loadProfiles(InputStream is) throws IOException {
+ ProfilesConfigFileLoaderHelper helper = new ProfilesConfigFileLoaderHelper();
+ Map<String, Map<String, String>> allProfileProperties = helper
+ .parseProfileProperties(new Scanner(is, StringUtils.UTF8.name()));
+
+ // Convert the loaded property map to credential objects
+ Map<String, BasicProfile> profilesByName = new LinkedHashMap<String, BasicProfile>();
+
+ for (Entry<String, Map<String, String>> entry : allProfileProperties.entrySet()) {
+ String profileName = entry.getKey();
+ Map<String, String> properties = entry.getValue();
+
+ if (profileName.startsWith("profile ")) {
+ LOG.warn(
+ "The legacy profile format requires the 'profile ' prefix before the profile name. " +
+ "The latest code does not require such prefix, and will consider it as part of the profile name. " +
+ "Please remove the prefix if you are seeing this warning.");
+ }
+
+ assertParameterNotEmpty(profileName,
+ "Unable to load properties from profile: Profile name is empty.");
+ profilesByName.put(profileName, new BasicProfile(profileName, properties));
+ }
+
+ return new AllProfiles(profilesByName);
+ }
+
+ /**
+ * <p> Asserts that the specified parameter value is neither <code>empty</code> nor null, and if
+ * it is, throws a <code>SdkClientException</code> with the specified error message. </p>
+ *
+ * @param parameterValue The parameter value being checked.
+ * @param errorMessage The error message to include in the SdkClientException if the
+ * specified parameter value is empty.
+ */
+ private void assertParameterNotEmpty(String parameterValue, String errorMessage) {
+ if (StringUtils.isNullOrEmpty(parameterValue)) {
+ throw new SdkClientException(errorMessage);
+ }
+ }
+
+ /**
+ * Implementation of AbstractProfilesConfigFileScanner that groups profile properties into a map
+ * while scanning through the credentials profile.
+ */
+ private static class ProfilesConfigFileLoaderHelper extends AbstractProfilesConfigFileScanner {
+
+ /**
+ * Map from the parsed profile name to the map of all the property values included the
+ * specific profile
+ */
+ protected final Map<String, Map<String, String>> allProfileProperties = new LinkedHashMap<String, Map<String, String>>();
+
+ /**
+ * Parses the input and returns a map of all the profile properties.
+ */
+ public Map<String, Map<String, String>> parseProfileProperties(Scanner scanner) {
+ allProfileProperties.clear();
+ run(scanner);
+ return new LinkedHashMap<String, Map<String, String>>(allProfileProperties);
+ }
+
+ @Override
+ protected void onEmptyOrCommentLine(String profileName, String line) {
+ // Ignore empty or comment line
+ }
+
+ @Override
+ protected void onProfileStartingLine(String newProfileName, String line) {
+ // If the same profile name has already been declared, clobber the
+ // previous one
+ allProfileProperties.put(newProfileName, new HashMap<String, String>());
+ }
+
+ @Override
+ protected void onProfileEndingLine(String prevProfileName) {
+ // No-op
+ }
+
+ @Override
+ protected void onProfileProperty(String profileName, String propertyKey,
+ String propertyValue, boolean isSupportedProperty,
+ String line) {
+ Map<String, String> properties = allProfileProperties.get(profileName);
+
+ if (properties.containsKey(propertyKey)) {
+ throw new IllegalArgumentException(
+ "Duplicate property values for [" + propertyKey + "].");
+ }
+
+ properties.put(propertyKey, propertyValue);
+ }
+
+ @Override
+ protected void onEndOfFile() {
+ // No-op
+ }
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/Profile.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/Profile.java
new file mode 100644
index 0000000..b8a6942
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/Profile.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.amazonaws.annotation.Immutable;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.AWSSessionCredentials;
+import com.amazonaws.auth.profile.internal.securitytoken.RoleInfo;
+import com.amazonaws.internal.StaticCredentialsProvider;
+
+/**
+ * Contains the information stored in an AWS profile, such as AWS security
+ * credentials.
+ */
+@Immutable
+@Deprecated
+public class Profile {
+
+ /** The name of this profile */
+ private final String profileName;
+
+ /** Profile properties */
+ private final Map<String, String> properties;
+
+ /** Holds the AWS Credentials for the profile. */
+ private final AWSCredentialsProvider awsCredentials;
+
+ public Profile(String profileName, AWSCredentials awsCredentials) {
+ Map<String, String> properties = new LinkedHashMap<String, String>();
+ properties.put(ProfileKeyConstants.AWS_ACCESS_KEY_ID, awsCredentials.getAWSAccessKeyId());
+ properties.put(ProfileKeyConstants.AWS_SECRET_ACCESS_KEY, awsCredentials.getAWSSecretKey());
+
+ if (awsCredentials instanceof AWSSessionCredentials) {
+ AWSSessionCredentials sessionCred = (AWSSessionCredentials)awsCredentials;
+ properties.put(ProfileKeyConstants.AWS_SESSION_TOKEN, sessionCred.getSessionToken());
+ }
+
+ this.profileName = profileName;
+ this.properties = properties;
+ this.awsCredentials = new StaticCredentialsProvider(awsCredentials);
+ }
+
+ public Profile(String profileName, String sourceProfile, AWSCredentialsProvider awsCredentials, RoleInfo roleInfo) {
+ Map<String, String> properties = new LinkedHashMap<String, String>();
+ properties.put(ProfileKeyConstants.SOURCE_PROFILE, sourceProfile);
+ properties.put(ProfileKeyConstants.ROLE_ARN, roleInfo.getRoleArn());
+
+ if (roleInfo.getRoleSessionName() != null) {
+ properties.put(ProfileKeyConstants.ROLE_SESSION_NAME, roleInfo.getRoleSessionName());
+ }
+
+ if (roleInfo.getExternalId() != null) {
+ properties.put(ProfileKeyConstants.EXTERNAL_ID, roleInfo.getExternalId());
+ }
+
+ this.profileName = profileName;
+ this.properties = properties;
+ this.awsCredentials = awsCredentials;
+ }
+
+ public Profile(String profileName, Map<String, String> properties,
+ AWSCredentialsProvider awsCredentials) {
+ this.profileName = profileName;
+ this.properties = properties;
+ this.awsCredentials = awsCredentials;
+ }
+
+ public String getProfileName() {
+ return profileName;
+ }
+
+ public AWSCredentials getCredentials() {
+ return awsCredentials.getCredentials();
+ }
+
+ /**
+ * Returns a map of profile properties included in this Profile instance.
+ * The returned properties corresponds to how this profile is described in
+ * the credential profiles file, i.e., profiles with basic credentials
+ * consist of two properties {"aws_access_key_id", "aws_secret_access_key"}
+ * and profiles with session credentials have three properties, with an
+ * additional "aws_session_token" property.
+ */
+ public Map<String, String> getProperties() {
+ return new LinkedHashMap<String, String>(properties);
+ }
+
+ /**
+ * Returns the value of a specific property that is included in this Profile instance.
+ * @see Profile#getProperties()
+ */
+ public String getPropertyValue(String propertyName) {
+ return getProperties().get(propertyName);
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileAssumeRoleCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileAssumeRoleCredentialsProvider.java
new file mode 100644
index 0000000..a841ac0
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileAssumeRoleCredentialsProvider.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.annotation.Immutable;
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.profile.internal.securitytoken.ProfileCredentialsService;
+import com.amazonaws.auth.profile.internal.securitytoken.RoleInfo;
+import com.amazonaws.util.StringUtils;
+
+/**
+ * Serves assume role credentials defined in a {@link BasicProfile}. If a profile defines the
+ * role_arn property then the profile is treated as an assume role profile. Does basic validation
+ * that the role exists and the source (long lived) credentials are valid.
+ */
+@SdkInternalApi
+@Immutable
+public class ProfileAssumeRoleCredentialsProvider implements AWSCredentialsProvider {
+
+
+ private final AllProfiles allProfiles;
+ private final BasicProfile profile;
+ private final ProfileCredentialsService profileCredentialsService;
+ private final AWSCredentialsProvider assumeRoleCredentialsProvider;
+
+ public ProfileAssumeRoleCredentialsProvider(ProfileCredentialsService profileCredentialsService,
+ AllProfiles allProfiles, BasicProfile profile) {
+ this.allProfiles = allProfiles;
+ this.profile = profile;
+ this.profileCredentialsService = profileCredentialsService;
+ this.assumeRoleCredentialsProvider = fromAssumeRole();
+ }
+
+ @Override
+ public AWSCredentials getCredentials() {
+ return assumeRoleCredentialsProvider.getCredentials();
+ }
+
+ @Override
+ public void refresh() {
+ }
+
+ private AWSCredentialsProvider fromAssumeRole() {
+ if (StringUtils.isNullOrEmpty(profile.getRoleSourceProfile())) {
+ throw new SdkClientException(String.format(
+ "Unable to load credentials from profile [%s]: Source profile name is not specified",
+ profile.getProfileName()));
+ }
+
+ final BasicProfile sourceProfile = allProfiles
+ .getProfile(this.profile.getRoleSourceProfile());
+ if (sourceProfile == null) {
+ throw new SdkClientException(String.format(
+ "Unable to load source profile [%s]: Source profile was not found [%s]",
+ profile.getProfileName(), profile.getRoleSourceProfile()));
+ }
+ AWSCredentials sourceCredentials = new ProfileStaticCredentialsProvider(sourceProfile)
+ .getCredentials();
+
+
+ final String roleSessionName = (this.profile.getRoleSessionName() == null) ?
+ "aws-sdk-java-" + System.currentTimeMillis() : this.profile.getRoleSessionName();
+
+ RoleInfo roleInfo = new RoleInfo().withRoleArn(this.profile.getRoleArn())
+ .withRoleSessionName(roleSessionName)
+ .withExternalId(this.profile.getRoleExternalId())
+ .withLongLivedCredentials(sourceCredentials);
+ return profileCredentialsService.getAssumeRoleCredentialsProvider(roleInfo);
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileKeyConstants.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileKeyConstants.java
new file mode 100644
index 0000000..c816912
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileKeyConstants.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import com.amazonaws.annotation.SdkInternalApi;
+
+/**
+ * Keys the Java SDK uses in the CLI credentials and config files.
+ */
+@SdkInternalApi
+public class ProfileKeyConstants {
+
+ /**
+ * Property name for specifying the Amazon AWS Access Key
+ */
+ public static final String AWS_ACCESS_KEY_ID = "aws_access_key_id";
+
+ /**
+ * Property name for specifying the Amazon AWS Secret Access Key
+ */
+ public static final String AWS_SECRET_ACCESS_KEY = "aws_secret_access_key";
+
+ /**
+ * Property name for specifying the Amazon AWS Session Token
+ */
+ public static final String AWS_SESSION_TOKEN = "aws_session_token";
+
+ /**
+ * Property name for specifying the IAM role to assume
+ */
+ public static final String ROLE_ARN = "role_arn";
+
+ /**
+ * Property name for specifying the IAM role session name
+ */
+ public static final String ROLE_SESSION_NAME = "role_session_name";
+
+ /**
+ * Property name for specifying the IAM role external id
+ */
+ public static final String EXTERNAL_ID = "external_id";
+
+ /**
+ * Property name for specifying the profile credentials to use when assuming a role
+ */
+ public static final String SOURCE_PROFILE = "source_profile";
+
+ /**
+ * AWS Region to use when creating clients.
+ */
+ public static final String REGION = "region";
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileStaticCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileStaticCredentialsProvider.java
new file mode 100644
index 0000000..fb96abb
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/ProfileStaticCredentialsProvider.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.annotation.Immutable;
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.auth.BasicSessionCredentials;
+import com.amazonaws.internal.StaticCredentialsProvider;
+import com.amazonaws.util.StringUtils;
+
+/**
+ * Serves credentials defined in a {@link BasicProfile}. Does validation that both access key and
+ * secret key exists and are non empty.
+ */
+@SdkInternalApi
+@Immutable
+public class ProfileStaticCredentialsProvider implements AWSCredentialsProvider {
+
+ private final BasicProfile profile;
+ private final AWSCredentialsProvider credentialsProvider;
+
+ public ProfileStaticCredentialsProvider(BasicProfile profile) {
+ this.profile = profile;
+ this.credentialsProvider = new StaticCredentialsProvider(fromStaticCredentials());
+ }
+
+ @Override
+ public AWSCredentials getCredentials() {
+ return credentialsProvider.getCredentials();
+ }
+
+ @Override
+ public void refresh() {
+ // No Op
+ }
+
+ private AWSCredentials fromStaticCredentials() {
+ if (StringUtils.isNullOrEmpty(profile.getAwsAccessIdKey())) {
+ throw new SdkClientException(String.format(
+ "Unable to load credentials into profile [%s]: AWS Access Key ID is not specified.",
+ profile.getProfileName()));
+ }
+ if (StringUtils.isNullOrEmpty(profile.getAwsSecretAccessKey())) {
+ throw new SdkClientException(String.format(
+ "Unable to load credentials into profile [%s]: AWS Secret Access Key is not specified.",
+ profile.getAwsSecretAccessKey()));
+ }
+
+ if (profile.getAwsSessionToken() == null) {
+ return new BasicAWSCredentials(profile.getAwsAccessIdKey(),
+ profile.getAwsSecretAccessKey());
+ } else {
+ if (profile.getAwsSessionToken().isEmpty()) {
+ throw new SdkClientException(String.format(
+ "Unable to load credentials into profile [%s]: AWS Session Token is empty.",
+ profile.getProfileName()));
+ }
+
+ return new BasicSessionCredentials(profile.getAwsAccessIdKey(),
+ profile.getAwsSecretAccessKey(),
+ profile.getAwsSessionToken());
+ }
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/ProfileCredentialsService.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/ProfileCredentialsService.java
new file mode 100644
index 0000000..1c96c95
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/ProfileCredentialsService.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal.securitytoken;
+
+import com.amazonaws.annotation.SdkProtectedApi;
+import com.amazonaws.auth.AWSCredentialsProvider;
+
+@SdkProtectedApi
+public interface ProfileCredentialsService {
+ AWSCredentialsProvider getAssumeRoleCredentialsProvider(RoleInfo targetRoleInfo);
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/RoleInfo.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/RoleInfo.java
new file mode 100644
index 0000000..7fa4877
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/RoleInfo.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal.securitytoken;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.annotation.SdkProtectedApi;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.internal.StaticCredentialsProvider;
+
+@SdkProtectedApi
+public class RoleInfo implements Cloneable {
+ /**
+ * <p>
+ * The Amazon Resource Name (ARN) of the role to assume.
+ * </p>
+ */
+ private String roleArn;
+
+ /**
+ * <p>
+ * An identifier for the assumed role session.
+ * </p>
+ * <p>
+ * Use the role session name to uniquely identify a session when the same
+ * role is assumed by different principals or for different reasons. In
+ * cross-account scenarios, the role session name is visible to, and can be
+ * logged by the account that owns the role. The role session name is also
+ * used in the ARN of the assumed role principal. This means that subsequent
+ * cross-account API requests using the temporary security credentials will
+ * expose the role session name to the external account in their CloudTrail
+ * logs.
+ * </p>
+ */
+ private String roleSessionName;
+
+ /**
+ * <p>
+ * A unique identifier that is used by third parties when assuming roles in
+ * their customers' accounts. For each role that the third party can assume,
+ * they should instruct their customers to ensure the role's trust policy
+ * checks for the external ID that the third party generated. Each time the
+ * third party assumes the role, they should pass the customer's external
+ * ID. The external ID is useful in order to help third parties bind a role
+ * to the customer who created it. For more information about the external
+ * ID, see <a href=
+ * "http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html"
+ * >How to Use an External ID When Granting Access to Your AWS Resources to
+ * a Third Party</a> in the <i>Using IAM</i>.
+ * </p>
+ */
+ private String externalId;
+
+ /**
+ * <p>
+ * Provides the credentials that are used to assume the role.
+ * </p>
+ */
+ private AWSCredentialsProvider longLivedCredentialsProvider;
+
+ /**
+ * Default constructor for RoleInfo object. Callers should use the setter
+ * or fluent setter (with...) methods to initialize the object after
+ * creating it.
+ */
+ public RoleInfo() {
+ }
+
+ /**
+ * <p>
+ * The Amazon Resource Name (ARN) of the role to assume.
+ * </p>
+ *
+ * @param roleArn
+ * The Amazon Resource Name (ARN) of the role to assume.
+ */
+ public void setRoleArn(String roleArn) {
+ this.roleArn = roleArn;
+ }
+
+ /**
+ * <p>
+ * The Amazon Resource Name (ARN) of the role to assume.
+ * </p>
+ *
+ * @return The Amazon Resource Name (ARN) of the role to assume.
+ */
+ public String getRoleArn() {
+ return this.roleArn;
+ }
+
+ /**
+ * <p>
+ * The Amazon Resource Name (ARN) of the role to assume.
+ * </p>
+ *
+ * @param roleArn
+ * The Amazon Resource Name (ARN) of the role to assume.
+ * @return Returns a reference to this object so that method calls can be
+ * chained together.
+ */
+ public RoleInfo withRoleArn(String roleArn) {
+ setRoleArn(roleArn);
+ return this;
+ }
+
+ /**
+ * <p>
+ * An identifier for the assumed role session.
+ * </p>
+ * <p>
+ * Use the role session name to uniquely identify a session when the same
+ * role is assumed by different principals or for different reasons. In
+ * cross-account scenarios, the role session name is visible to, and can be
+ * logged by the account that owns the role. The role session name is also
+ * used in the ARN of the assumed role principal. This means that subsequent
+ * cross-account API requests using the temporary security credentials will
+ * expose the role session name to the external account in their CloudTrail
+ * logs.
+ * </p>
+ *
+ * @param roleSessionName
+ * An identifier for the assumed role session. </p>
+ * <p>
+ * Use the role session name to uniquely identify a session when the
+ * same role is assumed by different principals or for different
+ * reasons. In cross-account scenarios, the role session name is
+ * visible to, and can be logged by the account that owns the role.
+ * The role session name is also used in the ARN of the assumed role
+ * principal. This means that subsequent cross-account API requests
+ * using the temporary security credentials will expose the role
+ * session name to the external account in their CloudTrail logs.
+ */
+ public void setRoleSessionName(String roleSessionName) {
+ this.roleSessionName = roleSessionName;
+ }
+
+ /**
+ * <p>
+ * An identifier for the assumed role session.
+ * </p>
+ * <p>
+ * Use the role session name to uniquely identify a session when the same
+ * role is assumed by different principals or for different reasons. In
+ * cross-account scenarios, the role session name is visible to, and can be
+ * logged by the account that owns the role. The role session name is also
+ * used in the ARN of the assumed role principal. This means that subsequent
+ * cross-account API requests using the temporary security credentials will
+ * expose the role session name to the external account in their CloudTrail
+ * logs.
+ * </p>
+ *
+ * @return An identifier for the assumed role session. </p>
+ * <p>
+ * Use the role session name to uniquely identify a session when the
+ * same role is assumed by different principals or for different
+ * reasons. In cross-account scenarios, the role session name is
+ * visible to, and can be logged by the account that owns the role.
+ * The role session name is also used in the ARN of the assumed role
+ * principal. This means that subsequent cross-account API requests
+ * using the temporary security credentials will expose the role
+ * session name to the external account in their CloudTrail logs.
+ */
+ public String getRoleSessionName() {
+ return this.roleSessionName;
+ }
+
+ /**
+ * <p>
+ * An identifier for the assumed role session.
+ * </p>
+ * <p>
+ * Use the role session name to uniquely identify a session when the same
+ * role is assumed by different principals or for different reasons. In
+ * cross-account scenarios, the role session name is visible to, and can be
+ * logged by the account that owns the role. The role session name is also
+ * used in the ARN of the assumed role principal. This means that subsequent
+ * cross-account API requests using the temporary security credentials will
+ * expose the role session name to the external account in their CloudTrail
+ * logs.
+ * </p>
+ *
+ * @param roleSessionName
+ * An identifier for the assumed role session. </p>
+ * <p>
+ * Use the role session name to uniquely identify a session when the
+ * same role is assumed by different principals or for different
+ * reasons. In cross-account scenarios, the role session name is
+ * visible to, and can be logged by the account that owns the role.
+ * The role session name is also used in the ARN of the assumed role
+ * principal. This means that subsequent cross-account API requests
+ * using the temporary security credentials will expose the role
+ * session name to the external account in their CloudTrail logs.
+ * @return Returns a reference to this object so that method calls can be
+ * chained together.
+ */
+ public RoleInfo withRoleSessionName(String roleSessionName) {
+ setRoleSessionName(roleSessionName);
+ return this;
+ }
+
+ /**
+ * <p>
+ * A unique identifier that is used by third parties when assuming roles in
+ * their customers' accounts. For each role that the third party can assume,
+ * they should instruct their customers to ensure the role's trust policy
+ * checks for the external ID that the third party generated. Each time the
+ * third party assumes the role, they should pass the customer's external
+ * ID. The external ID is useful in order to help third parties bind a role
+ * to the customer who created it. For more information about the external
+ * ID, see <a href=
+ * "http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html"
+ * >How to Use an External ID When Granting Access to Your AWS Resources to
+ * a Third Party</a> in the <i>Using IAM</i>.
+ * </p>
+ *
+ * @param externalId
+ * A unique identifier that is used by third parties when assuming
+ * roles in their customers' accounts. For each role that the third
+ * party can assume, they should instruct their customers to ensure
+ * the role's trust policy checks for the external ID that the third
+ * party generated. Each time the third party assumes the role, they
+ * should pass the customer's external ID. The external ID is useful
+ * in order to help third parties bind a role to the customer who
+ * created it. For more information about the external ID, see <a
+ * href=
+ * "http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html"
+ * >How to Use an External ID When Granting Access to Your AWS
+ * Resources to a Third Party</a> in the <i>Using IAM</i>.
+ */
+ public void setExternalId(String externalId) {
+ this.externalId = externalId;
+ }
+
+ /**
+ * <p>
+ * A unique identifier that is used by third parties when assuming roles in
+ * their customers' accounts. For each role that the third party can assume,
+ * they should instruct their customers to ensure the role's trust policy
+ * checks for the external ID that the third party generated. Each time the
+ * third party assumes the role, they should pass the customer's external
+ * ID. The external ID is useful in order to help third parties bind a role
+ * to the customer who created it. For more information about the external
+ * ID, see <a href=
+ * "http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html"
+ * >How to Use an External ID When Granting Access to Your AWS Resources to
+ * a Third Party</a> in the <i>Using IAM</i>.
+ * </p>
+ *
+ * @return A unique identifier that is used by third parties when assuming
+ * roles in their customers' accounts. For each role that the third
+ * party can assume, they should instruct their customers to ensure
+ * the role's trust policy checks for the external ID that the third
+ * party generated. Each time the third party assumes the role, they
+ * should pass the customer's external ID. The external ID is useful
+ * in order to help third parties bind a role to the customer who
+ * created it. For more information about the external ID, see <a
+ * href=
+ * "http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html"
+ * >How to Use an External ID When Granting Access to Your AWS
+ * Resources to a Third Party</a> in the <i>Using IAM</i>.
+ */
+ public String getExternalId() {
+ return this.externalId;
+ }
+
+ /**
+ * <p>
+ * A unique identifier that is used by third parties when assuming roles in
+ * their customers' accounts. For each role that the third party can assume,
+ * they should instruct their customers to ensure the role's trust policy
+ * checks for the external ID that the third party generated. Each time the
+ * third party assumes the role, they should pass the customer's external
+ * ID. The external ID is useful in order to help third parties bind a role
+ * to the customer who created it. For more information about the external
+ * ID, see <a href=
+ * "http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html"
+ * >How to Use an External ID When Granting Access to Your AWS Resources to
+ * a Third Party</a> in the <i>Using IAM</i>.
+ * </p>
+ *
+ * @param externalId
+ * A unique identifier that is used by third parties when assuming
+ * roles in their customers' accounts. For each role that the third
+ * party can assume, they should instruct their customers to ensure
+ * the role's trust policy checks for the external ID that the third
+ * party generated. Each time the third party assumes the role, they
+ * should pass the customer's external ID. The external ID is useful
+ * in order to help third parties bind a role to the customer who
+ * created it. For more information about the external ID, see <a
+ * href=
+ * "http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html"
+ * >How to Use an External ID When Granting Access to Your AWS
+ * Resources to a Third Party</a> in the <i>Using IAM</i>.
+ * @return Returns a reference to this object so that method calls can be
+ * chained together.
+ */
+ public RoleInfo withExternalId(String externalId) {
+ setExternalId(externalId);
+ return this;
+ }
+
+ /**
+ * <p>
+ * Provides the credentials that are used to assume the role.
+ * </p>
+ * @param longLivedCredentialsProvider long lived credentials provider
+ */
+ public void setLongLivedCredentialsProvider(AWSCredentialsProvider longLivedCredentialsProvider) {
+ this.longLivedCredentialsProvider = longLivedCredentialsProvider;
+ }
+
+ /**
+ * <p>
+ * Provides the credentials that are used to assume the role.
+ * </p>
+ * @return long lived credentials provider
+ */
+ public AWSCredentialsProvider getLongLivedCredentialsProvider() {
+ return this.longLivedCredentialsProvider;
+ }
+
+ /**
+ * <p>
+ * Provides the credentials that are used to assume the role.
+ * </p>
+ * @param longLivedCredentialsProvider long lived credentials provider
+ * @return Returns a reference to this object so that method calls can be
+ * chained together.
+ */
+ public RoleInfo withLongLivedCredentialsProvider(AWSCredentialsProvider longLivedCredentialsProvider) {
+ setLongLivedCredentialsProvider(longLivedCredentialsProvider);
+ return this;
+ }
+
+ /**
+ * <p>
+ * Provides the credentials that are used to assume the role.
+ * </p>
+ * @param longLivedCredentials long lived credentials
+ * @return Returns a reference to this object so that method calls can be
+ * chained together.
+ */
+ public RoleInfo withLongLivedCredentials(AWSCredentials longLivedCredentials) {
+ setLongLivedCredentialsProvider(new StaticCredentialsProvider(longLivedCredentials));
+ return this;
+ }
+
+ /**
+ * Returns a string representation of this object; useful for testing and
+ * debugging.
+ *
+ * @return A string representation of this object.
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ if (getRoleArn() != null)
+ sb.append("RoleArn: " + getRoleArn() + ",");
+ if (getRoleSessionName() != null)
+ sb.append("RoleSessionName: " + getRoleSessionName() + ",");
+ if (getExternalId() != null)
+ sb.append("ExternalId: " + getExternalId() + ",");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+
+ if (obj instanceof RoleInfo == false)
+ return false;
+
+ RoleInfo other = (RoleInfo) obj;
+ if (other.getRoleArn() == null ^ this.getRoleArn() == null)
+ return false;
+ if (other.getRoleArn() != null
+ && other.getRoleArn().equals(this.getRoleArn()) == false)
+ return false;
+ if (other.getRoleSessionName() == null
+ ^ this.getRoleSessionName() == null)
+ return false;
+ if (other.getRoleSessionName() != null
+ && other.getRoleSessionName().equals(this.getRoleSessionName()) == false)
+ return false;
+ if (other.getExternalId() == null ^ this.getExternalId() == null)
+ return false;
+ if (other.getExternalId() != null
+ && other.getExternalId().equals(this.getExternalId()) == false)
+ return false;
+ if (other.getLongLivedCredentialsProvider() != this.getLongLivedCredentialsProvider())
+ return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int hashCode = 1;
+
+ hashCode = prime * hashCode
+ + ((getRoleArn() == null) ? 0 : getRoleArn().hashCode());
+ hashCode = prime
+ * hashCode
+ + ((getRoleSessionName() == null) ? 0 : getRoleSessionName()
+ .hashCode());
+ hashCode = prime * hashCode
+ + ((getExternalId() == null) ? 0 : getExternalId().hashCode());
+ hashCode = prime * hashCode
+ + ((getLongLivedCredentialsProvider() == null) ? 0 : getLongLivedCredentialsProvider().hashCode());
+ return hashCode;
+ }
+
+ @Override
+ public RoleInfo clone() {
+ try {
+ return (RoleInfo) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException(
+ "Got a CloneNotSupportedException from Object.clone() "
+ + "even though we're Cloneable!", e);
+ }
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/STSProfileCredentialsServiceLoader.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/STSProfileCredentialsServiceLoader.java
new file mode 100644
index 0000000..86715e3
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/STSProfileCredentialsServiceLoader.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal.securitytoken;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.auth.AWSCredentialsProvider;
+
+/**
+ * Loads <code>com.amazonaws.services.securitytoken.internal.STSProfileCredentialsService</code>
+ * from the STS SDK module, if the module is on the current classpath.
+ */
+@SdkInternalApi
+public class STSProfileCredentialsServiceLoader implements ProfileCredentialsService {
+ private static final STSProfileCredentialsServiceLoader INSTANCE = new STSProfileCredentialsServiceLoader();
+
+ private STSProfileCredentialsServiceLoader() {
+ }
+
+ @Override
+ public AWSCredentialsProvider getAssumeRoleCredentialsProvider(RoleInfo targetRoleInfo) {
+ return new STSProfileCredentialsServiceProvider(targetRoleInfo);
+ }
+
+ public static STSProfileCredentialsServiceLoader getInstance() {
+ return INSTANCE;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/STSProfileCredentialsServiceProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/STSProfileCredentialsServiceProvider.java
new file mode 100644
index 0000000..ca34999
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/internal/securitytoken/STSProfileCredentialsServiceProvider.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.auth.profile.internal.securitytoken;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.annotation.ThreadSafe;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+
+@ThreadSafe
+public class STSProfileCredentialsServiceProvider implements AWSCredentialsProvider {
+ private static final String CLASS_NAME = "com.amazonaws.services.securitytoken.internal.STSProfileCredentialsService";
+ private static volatile ProfileCredentialsService STS_CREDENTIALS_SERVICE;
+
+ private final RoleInfo roleInfo;
+ private volatile AWSCredentialsProvider profileCredentialsProvider;
+
+ public STSProfileCredentialsServiceProvider(RoleInfo roleInfo) {
+ this.roleInfo = roleInfo;
+ }
+
+ private AWSCredentialsProvider getProfileCredentialsProvider() {
+ if (this.profileCredentialsProvider == null) {
+ synchronized (STSProfileCredentialsServiceProvider.class) {
+ if (this.profileCredentialsProvider == null) {
+ this.profileCredentialsProvider = getProfileCredentialService()
+ .getAssumeRoleCredentialsProvider(roleInfo);
+ }
+ }
+ }
+ return this.profileCredentialsProvider;
+ }
+
+ /**
+ * Only called once per creation of each profile credential provider so we don't bother with any
+ * double checked locking.
+ */
+ private static synchronized ProfileCredentialsService getProfileCredentialService() {
+ if (STS_CREDENTIALS_SERVICE == null) {
+ try {
+ STS_CREDENTIALS_SERVICE = (ProfileCredentialsService) Class.forName(CLASS_NAME)
+ .newInstance();
+ } catch (ClassNotFoundException ex) {
+ throw new SdkClientException(
+ "To use assume role profiles the aws-java-sdk-sts module must be on the class path.",
+ ex);
+ } catch (InstantiationException ex) {
+ throw new SdkClientException("Failed to instantiate " + CLASS_NAME, ex);
+ } catch (IllegalAccessException ex) {
+ throw new SdkClientException("Failed to instantiate " + CLASS_NAME, ex);
+ }
+ }
+ return STS_CREDENTIALS_SERVICE;
+ }
+
+
+ @Override
+ public AWSCredentials getCredentials() {
+ return getProfileCredentialsProvider().getCredentials();
+ }
+
+ @Override
+ public void refresh() {
+ getProfileCredentialsProvider().refresh();
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/package-info.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/package-info.java
new file mode 100644
index 0000000..09bcff8
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/profile/package-info.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+/**
+ * AWS configuration profiles allow you to share multiple sets of AWS
+ * security credentials between different tools such as the AWS SDK for Java
+ * and the AWS CLI.
+ * <p>
+ * In addition to the required <code>default</code> profile, you can specify as
+ * many additional named profiles as you need:
+ * <pre>
+ * [default]
+ * aws_access_key_id=AKIAXXXXXXXXXX
+ * aws_secret_access_key=abc01234567890
+ *
+ * [profile test]
+ * aws_access_key_id=AKIAZZZZZZZZZZ
+ * aws_secret_access_key=xyz01234567890
+ * </pre>
+ * <p>
+ * Role assumption is also supported for cross account access. The source profile credentials are
+ * used to assume the given role when the <pre>test</pre> profile is used. One requirement to use
+ * assume role profiles is that the STS SDK module be on the class path.
+ * <pre>
+ * [default]
+ * aws_access_key_id=AKIAXXXXXXXXXX
+ * aws_secret_access_key=abc01234567890
+ *
+ * [profile test]
+ * role_arn=arn:aws:iam::123456789012:role/role-name
+ * source_profile=default
+ * # Optionally, provide a session name
+ * # role_session_name=mysession
+ * # Optionally, provide an external id
+ * # external_id=abc01234567890
+ * </pre>
+ *
+ *
+ * <p>
+ * You can use {@link com.amazonaws.auth.profile.ProfileCredentialsProvider} to
+ * access your AWS configuration profiles and supply your credentials to code
+ * using the AWS SDK for Java.
+ *
+ * <p>
+ * The same profiles are used by the AWS CLI.
+ *
+ * <p>
+ * For more information on setting up AWS configuration profiles, see:
+ * http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
+ */
+package com.amazonaws.auth.profile;
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ConnectionUtils.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ConnectionUtils.java
new file mode 100644
index 0000000..189b522
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ConnectionUtils.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.internal;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.Proxy;
+import java.net.URI;
+import java.util.Map;
+
+import com.amazonaws.annotation.SdkInternalApi;
+
+@SdkInternalApi
+public class ConnectionUtils {
+
+ private static ConnectionUtils instance;
+
+ private ConnectionUtils() {
+
+ }
+
+ public static ConnectionUtils getInstance() {
+ if (instance == null) {
+ instance = new ConnectionUtils();
+ }
+ return instance;
+ }
+
+ public HttpURLConnection connectToEndpoint(URI endpoint, Map<String, String> headers) throws IOException {
+ HttpURLConnection connection = (HttpURLConnection) endpoint.toURL().openConnection(Proxy.NO_PROXY);
+ connection.setConnectTimeout(1000 * 2);
+ connection.setReadTimeout(1000 * 5);
+ connection.setRequestMethod("GET");
+ connection.setDoOutput(true);
+
+ for (Map.Entry<String, String> header : headers.entrySet()) {
+ connection.addRequestProperty(header.getKey(), header.getValue());
+ }
+
+ // TODO should we autoredirect 3xx
+ // connection.setInstanceFollowRedirects(false);
+ connection.connect();
+
+ return connection;
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/CredentialsEndpointProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/CredentialsEndpointProvider.java
new file mode 100644
index 0000000..e18c5dc
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/CredentialsEndpointProvider.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.internal;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.retry.internal.CredentialsEndpointRetryPolicy;
+
+/**
+ * <p>
+ * Abstract class to return an endpoint URI from which the credentials can be loaded.
+ * </p>
+ * <p>
+ * By default, the request won't be retried if the request fails while computing endpoint.
+ * </p>
+ */
+@SdkInternalApi
+public abstract class CredentialsEndpointProvider {
+ /**
+ * Returns the URI that contains the credentials.
+ * @return
+ * URI to retrieve the credentials.
+ *
+ * @throws URISyntaxException
+ * If the endpoint string could not be parsed as a URI reference.
+ *
+ * @throws IOException
+ * If any problems are encountered while connecting to the
+ * service to retrieve the endpoint.
+ */
+ public abstract URI getCredentialsEndpoint() throws URISyntaxException, IOException;
+
+ /**
+ * Allows the extending class to provide a custom retry policy.
+ * The default behavior is not to retry.
+ */
+ public CredentialsEndpointRetryPolicy getRetryPolicy() {
+ return CredentialsEndpointRetryPolicy.NO_RETRY;
+ }
+
+ /**
+ * Allows passing additional headers to the request
+ */
+ public Map<String, String> getHeaders() {
+ return new HashMap<String, String>();
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/EC2CredentialsUtils.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/EC2CredentialsUtils.java
new file mode 100644
index 0000000..4cf990d
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/EC2CredentialsUtils.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.CharStreams;
+import com.google.common.io.Closeables;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.retry.internal.CredentialsEndpointRetryParameters;
+import com.amazonaws.retry.internal.CredentialsEndpointRetryPolicy;
+
+@SdkInternalApi
+public final class EC2CredentialsUtils {
+
+ private static final Log LOG = LogFactory.getLog(EC2CredentialsUtils.class);
+
+ private static EC2CredentialsUtils instance;
+
+ private final ConnectionUtils connectionUtils;
+
+ private EC2CredentialsUtils() {
+ this(ConnectionUtils.getInstance());
+ }
+
+ EC2CredentialsUtils(ConnectionUtils connectionUtils) {
+ this.connectionUtils = connectionUtils;
+ }
+
+ public static EC2CredentialsUtils getInstance() {
+ if (instance == null) {
+ instance = new EC2CredentialsUtils();
+ }
+ return instance;
+ }
+
+ /**
+ * Connects to the given endpoint to read the resource
+ * and returns the text contents.
+ *
+ * If the connection fails, the request will not be retried.
+ *
+ * @param endpoint
+ * The service endpoint to connect to.
+ *
+ * @return The text payload returned from the Amazon EC2 endpoint
+ * service for the specified resource path.
+ *
+ * @throws IOException
+ * If any problems were encountered while connecting to the
+ * service for the requested resource path.
+ * @throws SdkClientException
+ * If the requested service is not found.
+ */
+ public String readResource(URI endpoint) throws IOException {
+ return readResource(endpoint, CredentialsEndpointRetryPolicy.NO_RETRY, new HashMap<String, String>());
+ }
+
+ /**
+ * Connects to the given endpoint to read the resource
+ * and returns the text contents.
+ *
+ * @param endpoint
+ * The service endpoint to connect to.
+ *
+ * @param retryPolicy
+ * The custom retry policy that determines whether a
+ * failed request should be retried or not.
+ *
+ * @return The text payload returned from the Amazon EC2 endpoint
+ * service for the specified resource path.
+ *
+ * @throws IOException
+ * If any problems were encountered while connecting to the
+ * service for the requested resource path.
+ * @throws SdkClientException
+ * If the requested service is not found.
+ */
+ public String readResource(URI endpoint, CredentialsEndpointRetryPolicy retryPolicy, Map<String, String> headers) throws IOException {
+ int retriesAttempted = 0;
+ InputStream inputStream = null;
+
+ while (true) {
+ try {
+ HttpURLConnection connection = connectionUtils.connectToEndpoint(endpoint, headers);
+
+ int statusCode = connection.getResponseCode();
+
+ if (statusCode == HttpURLConnection.HTTP_OK) {
+ inputStream = connection.getInputStream();
+ try (Reader successReader = new InputStreamReader(inputStream, Charsets.UTF_8)) {
+ return CharStreams.toString(successReader);
+ }
+ } else if (statusCode == HttpURLConnection.HTTP_NOT_FOUND) {
+ // This is to preserve existing behavior of EC2 Instance metadata service.
+ throw new SdkClientException("The requested metadata is not found at " + connection.getURL());
+ } else {
+ if (!retryPolicy.shouldRetry(retriesAttempted++, CredentialsEndpointRetryParameters.builder().withStatusCode(statusCode).build())) {
+ inputStream = connection.getErrorStream();
+ handleErrorResponse(inputStream, statusCode, connection.getResponseMessage());
+ }
+ }
+ } catch (IOException ioException) {
+ if (!retryPolicy.shouldRetry(retriesAttempted++, CredentialsEndpointRetryParameters.builder().withException(ioException).build())) {
+ throw ioException;
+ }
+ LOG.debug("An IOException occured when connecting to service endpoint: " + endpoint + "\n Retrying to connect again.");
+ } finally {
+ Closeables.closeQuietly(inputStream);
+ }
+ }
+
+ }
+
+ private void handleErrorResponse(InputStream errorStream, int statusCode, String responseMessage) throws IOException {
+ String errorCode = null;
+
+ // Parse the error stream returned from the service.
+ if(errorStream != null) {
+ try (Reader errorReader = new InputStreamReader(errorStream, Charsets.UTF_8)) {
+ String errorResponse = CharStreams.toString(errorReader);
+ JsonParser parser = new JsonParser();
+
+ JsonObject node = parser.parse(errorResponse).getAsJsonObject();
+ JsonElement code = node.get("code");
+ JsonElement message = node.get("message");
+ if (code != null && message != null) {
+ errorCode = code.getAsString();
+ responseMessage = message.getAsString();
+ }
+ } catch (Exception exception) {
+ LOG.debug("Unable to parse error stream");
+ }
+ }
+
+ AmazonServiceException ase = new AmazonServiceException(responseMessage);
+ ase.setStatusCode(statusCode);
+ ase.setErrorCode(errorCode);
+ throw ase;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/StaticCredentialsProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/StaticCredentialsProvider.java
new file mode 100644
index 0000000..f31295d
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/StaticCredentialsProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.internal;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+
+/**
+ * Simple implementation of AWSCredentialsProvider that just wraps static AWSCredentials.
+ *
+ * @deprecated By {@link com.amazonaws.auth.AWSStaticCredentialsProvider}
+ */
+@Deprecated
+public class StaticCredentialsProvider implements AWSCredentialsProvider {
+
+ private final AWSCredentials credentials;
+
+ public StaticCredentialsProvider(AWSCredentials credentials) {
+ this.credentials = credentials;
+ }
+
+ public AWSCredentials getCredentials() {
+ return credentials;
+ }
+
+ public void refresh() {
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/CommonsLog.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/CommonsLog.java
new file mode 100644
index 0000000..8e58cb9
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/CommonsLog.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.log;
+
+import org.apache.commons.logging.Log;
+
+/**
+ * Used to delegate internal logging of the signers and core classes to Jakarta
+ * Commons Logging.
+ */
+public class CommonsLog implements com.amazonaws.log.InternalLogApi {
+
+ private final org.apache.commons.logging.Log log;
+
+ CommonsLog(Log log) {
+ this.log = log;
+ }
+
+ @Override
+ public void debug(Object message) {
+ log.debug(message);
+ }
+
+ @Override
+ public void debug(Object message, Throwable t) {
+ log.debug(message, t);
+ }
+
+ @Override
+ public void error(Object message) {
+ log.error(message);
+ }
+
+ @Override
+ public void error(Object message, Throwable t) {
+ log.error(message, t);
+ }
+
+ @Override
+ public void fatal(Object message) {
+ log.fatal(message);
+ }
+
+ @Override
+ public void fatal(Object message, Throwable t) {
+ log.fatal(message, t);
+ }
+
+ @Override
+ public void info(Object message) {
+ log.info(message);
+ }
+
+ @Override
+ public void info(Object message, Throwable t) {
+ log.info(message, t);
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return log.isDebugEnabled();
+ }
+
+ @Override
+ public boolean isErrorEnabled() {
+ return log.isErrorEnabled();
+ }
+
+ @Override
+ public boolean isFatalEnabled() {
+ return log.isFatalEnabled();
+ }
+
+ @Override
+ public boolean isInfoEnabled() {
+ return log.isInfoEnabled();
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return log.isTraceEnabled();
+ }
+
+ @Override
+ public boolean isWarnEnabled() {
+ return log.isWarnEnabled();
+ }
+
+ @Override
+ public void trace(Object message) {
+ log.trace(message);
+ }
+
+ @Override
+ public void trace(Object message, Throwable t) {
+ log.trace(message, t);
+ }
+
+ @Override
+ public void warn(Object message) {
+ log.warn(message);
+ }
+
+ @Override
+ public void warn(Object message, Throwable t) {
+ log.warn(message, t);
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/CommonsLogFactory.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/CommonsLogFactory.java
new file mode 100644
index 0000000..0b3b5f5
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/CommonsLogFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.log;
+
+/**
+ * Internal logging factory for the signers and core classes based on Jakarta
+ * Commons Logging.
+ */
+public final class CommonsLogFactory extends InternalLogFactory {
+ @Override
+ protected InternalLogApi doGetLog(Class<?> clazz) {
+ return new CommonsLog(
+ org.apache.commons.logging.LogFactory.getLog(clazz));
+ }
+
+ @Override
+ protected InternalLogApi doGetLog(String name) {
+ return new CommonsLog(
+ org.apache.commons.logging.LogFactory.getLog(name));
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLog.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLog.java
new file mode 100644
index 0000000..ff43f9c
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLog.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.log;
+
+/**
+ * Used to delegate internal logging of the signers and core classes to the
+ * currently configured default logging framework of the SDK.
+ *
+ * @see InternalLogFactory
+ */
+class InternalLog implements InternalLogApi {
+ private final String name;
+
+ InternalLog(String name) {
+ this.name = name;
+ }
+
+ private InternalLogApi logger() {
+ return InternalLogFactory.getFactory().doGetLog(name);
+ }
+
+ @Override
+ public void debug(Object message) {
+ logger().debug(message);
+ }
+
+ @Override
+ public void debug(Object message, Throwable t) {
+ logger().debug(message, t);
+ }
+
+ @Override
+ public void error(Object message) {
+ logger().error(message);
+ }
+
+ @Override
+ public void error(Object message, Throwable t) {
+ logger().error(message, t);
+ }
+
+ @Override
+ public void fatal(Object message) {
+ logger().fatal(message);
+ }
+
+ @Override
+ public void fatal(Object message, Throwable t) {
+ logger().fatal(message, t);
+ }
+
+ @Override
+ public void info(Object message) {
+ logger().info(message);
+ }
+
+ @Override
+ public void info(Object message, Throwable t) {
+ logger().info(message, t);
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return logger().isDebugEnabled();
+ }
+
+ @Override
+ public boolean isErrorEnabled() {
+ return logger().isErrorEnabled();
+ }
+
+ @Override
+ public boolean isFatalEnabled() {
+ return logger().isFatalEnabled();
+ }
+
+ @Override
+ public boolean isInfoEnabled() {
+ return logger().isInfoEnabled();
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return logger().isTraceEnabled();
+ }
+
+ @Override
+ public boolean isWarnEnabled() {
+ return logger().isWarnEnabled();
+ }
+
+ @Override
+ public void trace(Object message) {
+ logger().trace(message);
+ }
+
+ @Override
+ public void trace(Object message, Throwable t) {
+ logger().trace(message, t);
+ }
+
+ @Override
+ public void warn(Object message) {
+ logger().warn(message);
+ }
+
+ @Override
+ public void warn(Object message, Throwable t) {
+ logger().warn(message, t);
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLogApi.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLogApi.java
new file mode 100644
index 0000000..3bb6eac
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLogApi.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.log;
+
+/**
+ * An SDK internal logging API, not intended for general use. This logging API
+ * allows a minimal set of signer related classes to make use of logging without
+ * direct dependency on any third party library.
+ *
+ * @see InternalLogFactory
+ */
+public interface InternalLogApi {
+
+ /**
+ * Logs a message with debug log level.
+ *
+ * @param message
+ * log this message
+ */
+ void debug(Object message);
+
+ /**
+ * Logs an error with debug log level.
+ *
+ * @param message
+ * log this message
+ * @param t
+ * log this cause
+ */
+ void debug(Object message, Throwable t);
+
+ /**
+ * Logs a message with error log level.
+ *
+ * @param message
+ * log this message
+ */
+ void error(Object message);
+
+ /**
+ * Logs an error with error log level.
+ *
+ * @param message
+ * log this message
+ * @param t
+ * log this cause
+ */
+ void error(Object message, Throwable t);
+
+ /**
+ * Logs a message with fatal log level.
+ *
+ * @param message
+ * log this message
+ */
+ void fatal(Object message);
+
+ /**
+ * Logs an error with fatal log level.
+ *
+ * @param message
+ * log this message
+ * @param t
+ * log this cause
+ */
+ void fatal(Object message, Throwable t);
+
+ /**
+ * Logs a message with info log level.
+ *
+ * @param message
+ * log this message
+ */
+ void info(Object message);
+
+ /**
+ * Logs an error with info log level.
+ *
+ * @param message
+ * log this message
+ * @param t
+ * log this cause
+ */
+ void info(Object message, Throwable t);
+
+ /**
+ * Is debug logging currently enabled?
+ * <p>
+ * Call this method to prevent having to perform expensive operations (for
+ * example, <code>String</code> concatenation) when the log level is more
+ * than debug.
+ *
+ * @return true if debug is enabled in the underlying logger.
+ */
+ boolean isDebugEnabled();
+
+ /**
+ * Is error logging currently enabled?
+ * <p>
+ * Call this method to prevent having to perform expensive operations (for
+ * example, <code>String</code> concatenation) when the log level is more
+ * than error.
+ *
+ * @return true if error is enabled in the underlying logger.
+ */
+ boolean isErrorEnabled();
+
+ /**
+ * Is fatal logging currently enabled?
+ * <p>
+ * Call this method to prevent having to perform expensive operations (for
+ * example, <code>String</code> concatenation) when the log level is more
+ * than fatal.
+ *
+ * @return true if fatal is enabled in the underlying logger.
+ */
+ boolean isFatalEnabled();
+
+ /**
+ * Is info logging currently enabled?
+ * <p>
+ * Call this method to prevent having to perform expensive operations (for
+ * example, <code>String</code> concatenation) when the log level is more
+ * than info.
+ *
+ * @return true if info is enabled in the underlying logger.
+ */
+ boolean isInfoEnabled();
+
+ /**
+ * Is trace logging currently enabled?
+ * <p>
+ * Call this method to prevent having to perform expensive operations (for
+ * example, <code>String</code> concatenation) when the log level is more
+ * than trace.
+ *
+ * @return true if trace is enabled in the underlying logger.
+ */
+ boolean isTraceEnabled();
+
+ /**
+ * Is warn logging currently enabled?
+ * <p>
+ * Call this method to prevent having to perform expensive operations (for
+ * example, <code>String</code> concatenation) when the log level is more
+ * than warn.
+ *
+ * @return true if warn is enabled in the underlying logger.
+ */
+ boolean isWarnEnabled();
+
+ /**
+ * Logs a message with trace log level.
+ *
+ * @param message
+ * log this message
+ */
+ void trace(Object message);
+
+ /**
+ * Logs an error with trace log level.
+ *
+ * @param message
+ * log this message
+ * @param t
+ * log this cause
+ */
+ void trace(Object message, Throwable t);
+
+ /**
+ * Logs a message with warn log level.
+ *
+ * @param message
+ * log this message
+ */
+ void warn(Object message);
+
+ /**
+ * Logs an error with warn log level.
+ *
+ * @param message
+ * log this message
+ * @param t
+ * log this cause
+ */
+ void warn(Object message, Throwable t);
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLogFactory.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLogFactory.java
new file mode 100644
index 0000000..e13b336
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/InternalLogFactory.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.amazonaws.log;
+
+import com.amazonaws.annotation.ThreadSafe;
+
+/**
+ * Can be used to configure the default log factory for the AWSJavaClientCore
+ * and AWSJavaClientSigners. Default to JUL, unless AWSJavaClientRuntime is
+ * present which will default it to Jakarta Commons Logging.
+ */
+@ThreadSafe
+public abstract class InternalLogFactory {
+ private static volatile InternalLogFactory factory = new JulLogFactory();
+ /** True if the log factory has been explicitly configured; false otherwise. */
+ private static volatile boolean factoryConfigured;
+
+ /**
+ * Returns an SDK logger that logs using the currently configured default
+ * log factory, given the class.
+ */
+ public static InternalLogApi getLog(Class<?> clazz) {
+ return factoryConfigured
+ ? factory.doGetLog(clazz)
+ : new InternalLog(clazz.getName()); // will look up actual logger per log
+ }
+
+ /**
+ * Returns an SDK logger that logs using the currently configured default
+ * log factory, given the name.
+ */
+ public static InternalLogApi getLog(String name) {
+ return factoryConfigured
+ ? factory.doGetLog(name)
+ : new InternalLog(name); // will look up actual logger per log
+ }
+
+ /**
+ * SPI to return a logger given a class.
+ */
+ protected abstract InternalLogApi doGetLog(Class<?> clazz);
+
+ /**
+ * SPI to return a logger given a name.
+ */
+ protected abstract InternalLogApi doGetLog(String name);
+
+ /**
+ * Returns the current default log factory.
+ */
+ public static InternalLogFactory getFactory() {
+ return factory;
+ }
+
+ /**
+ * Used to explicitly configure the log factory. The log factory can only be
+ * configured at most once. All subsequent configurations will have no
+ * effect.
+ *
+ * Note explicitly configuring the log factory will have positive
+ * performance impact on all subsequent logging, since the specific logger
+ * can be directly referenced instead of being searched every time.
+ *
+ * @param factory
+ * the log factory to be used internally by the SDK
+ *
+ * @return true if the log factory is successfully configured; false
+ * otherwise (ie the log factory is not allowed to be configured
+ * more than once for performance reasons.)
+ */
+ public synchronized static boolean configureFactory(
+ InternalLogFactory factory) {
+ if (factory == null)
+ throw new IllegalArgumentException();
+ if (factoryConfigured)
+ return false;
+ InternalLogFactory.factory = factory;
+ factoryConfigured = true;
+ return true;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/JulLog.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/JulLog.java
new file mode 100644
index 0000000..892f2d7
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/JulLog.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.log;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Used to delegate internal logging of the signers and core classes to JUL.
+ */
+final class JulLog implements InternalLogApi {
+
+ private final Logger log;
+
+ JulLog(Logger logger) {
+ this.log = logger;
+ }
+
+ @Override
+ public void debug(Object message) {
+ log.log(Level.FINE, String.valueOf(message));
+ }
+
+ @Override
+ public void debug(Object message, Throwable t) {
+ log.log(Level.FINE, String.valueOf(message), t);
+ }
+
+ @Override
+ public void error(Object message) {
+ log.log(Level.SEVERE, String.valueOf(message));
+ }
+
+ @Override
+ public void error(Object message, Throwable t) {
+ log.log(Level.SEVERE, String.valueOf(message), t);
+ }
+
+ @Override
+ public void fatal(Object message) {
+ log.log(Level.SEVERE, String.valueOf(message));
+ }
+
+ @Override
+ public void fatal(Object message, Throwable t) {
+ log.log(Level.SEVERE, String.valueOf(message), t);
+ }
+
+ @Override
+ public void info(Object message) {
+ log.log(Level.INFO, String.valueOf(message));
+ }
+
+ @Override
+ public void info(Object message, Throwable t) {
+ log.log(Level.INFO, String.valueOf(message), t);
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return log.isLoggable(Level.FINE);
+ }
+
+ @Override
+ public boolean isErrorEnabled() {
+ return log.isLoggable(Level.SEVERE);
+ }
+
+ @Override
+ public boolean isFatalEnabled() {
+ return log.isLoggable(Level.SEVERE);
+ }
+
+ @Override
+ public boolean isInfoEnabled() {
+ return log.isLoggable(Level.INFO);
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return log.isLoggable(Level.FINER);
+ }
+
+ @Override
+ public boolean isWarnEnabled() {
+ return log.isLoggable(Level.WARNING);
+ }
+
+ @Override
+ public void trace(Object message) {
+ log.log(Level.FINER, String.valueOf(message));
+ }
+
+ @Override
+ public void trace(Object message, Throwable t) {
+ log.log(Level.FINER, String.valueOf(message), t);
+ }
+
+ @Override
+ public void warn(Object message) {
+ log.log(Level.WARNING, String.valueOf(message));
+ }
+
+ @Override
+ public void warn(Object message, Throwable t) {
+ log.log(Level.WARNING, String.valueOf(message), t);
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/JulLogFactory.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/JulLogFactory.java
new file mode 100644
index 0000000..5152333
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/log/JulLogFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */package com.amazonaws.log;
+
+import java.util.logging.Logger;
+
+/**
+ * Internal logging factory for the signers and core classes based on JUL.
+ */
+public final class JulLogFactory extends InternalLogFactory {
+ @Override
+ protected InternalLogApi doGetLog(Class<?> clazz) {
+ return new JulLog(Logger.getLogger(clazz.getName()));
+ }
+
+ @Override
+ protected InternalLogApi doGetLog(String name) {
+ return new JulLog(Logger.getLogger(name));
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsDirectoryBasePathProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsDirectoryBasePathProvider.java
new file mode 100644
index 0000000..1cf293b
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsDirectoryBasePathProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.profile.path;
+
+import com.amazonaws.SdkClientException;
+import com.amazonaws.annotation.SdkInternalApi;
+
+import java.io.File;
+
+/**
+ * Base provider for all location providers that source a file from the ~/.aws directory.
+ */
+@SdkInternalApi
+public abstract class AwsDirectoryBasePathProvider implements AwsProfileFileLocationProvider {
+
+ /**
+ * @return File of ~/.aws directory.
+ */
+ protected final File getAwsDirectory() {
+ return new File(getHomeDirectory(), ".aws");
+ }
+
+ private String getHomeDirectory() {
+ String userHome = System.getProperty("user.home");
+ if (userHome == null) {
+ throw new SdkClientException(
+ "Unable to load AWS profiles: " + "'user.home' System property is not set.");
+ }
+ return userHome;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsProfileFileLocationProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsProfileFileLocationProvider.java
new file mode 100644
index 0000000..285f45b
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsProfileFileLocationProvider.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.profile.path;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.profile.path.config.SharedConfigDefaultLocationProvider;
+import com.amazonaws.profile.path.config.ConfigEnvVarOverrideLocationProvider;
+import com.amazonaws.profile.path.cred.CredentialsDefaultLocationProvider;
+import com.amazonaws.profile.path.cred.CredentialsEnvVarOverrideLocationProvider;
+import com.amazonaws.profile.path.cred.CredentialsLegacyConfigLocationProvider;
+
+import java.io.File;
+
+/**
+ * Provides the location of both the AWS Shared credentials file (~/.aws/credentials) or the AWS
+ * Shared config file (~/.aws/config).
+ */
+@SdkInternalApi
+public interface AwsProfileFileLocationProvider {
+
+ /**
+ * Location provider for the shared AWS credentials file. Checks the environment variable override
+ * first, then checks the default location (~/.aws/credentials), and finally falls back to the
+ * legacy config file (~/.aws/config) that we still support loading credentials from.
+ */
+ AwsProfileFileLocationProvider DEFAULT_CREDENTIALS_LOCATION_PROVIDER = new AwsProfileFileLocationProviderChain(
+ new CredentialsEnvVarOverrideLocationProvider(), new CredentialsDefaultLocationProvider(),
+ new CredentialsLegacyConfigLocationProvider());
+
+ /**
+ * Location provider for the shared AWS Config file. Checks environment variable override first then
+ * falls back to the default location (~/.aws/config) if not present.
+ */
+ AwsProfileFileLocationProvider DEFAULT_CONFIG_LOCATION_PROVIDER = new AwsProfileFileLocationProviderChain(
+ new ConfigEnvVarOverrideLocationProvider(), new SharedConfigDefaultLocationProvider());
+
+ /**
+ * @return Location of file containing profile data. Null if implementation cannot provide the
+ * location.
+ */
+ File getLocation();
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsProfileFileLocationProviderChain.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsProfileFileLocationProviderChain.java
new file mode 100644
index 0000000..c206fa4
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/AwsProfileFileLocationProviderChain.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.profile.path;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.profile.path.AwsProfileFileLocationProvider;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Delegates to a chain of {@link AwsProfileFileLocationProvider}. Returns null if no provider in
+ * the chain can come up with a location to the shared credentials file.
+ */
+@SdkInternalApi
+public class AwsProfileFileLocationProviderChain implements AwsProfileFileLocationProvider {
+
+ private final List<AwsProfileFileLocationProvider> providers = new ArrayList<AwsProfileFileLocationProvider>();
+
+ public AwsProfileFileLocationProviderChain(AwsProfileFileLocationProvider... providers) {
+ Collections.addAll(this.providers, providers);
+ }
+
+ @Override
+ public File getLocation() {
+ for (AwsProfileFileLocationProvider provider : providers) {
+ File path = provider.getLocation();
+ if (path != null) {
+ return path;
+ }
+ }
+ return null;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/config/ConfigEnvVarOverrideLocationProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/config/ConfigEnvVarOverrideLocationProvider.java
new file mode 100644
index 0000000..3b7ca1b
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/config/ConfigEnvVarOverrideLocationProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.profile.path.config;
+
+import com.amazonaws.SDKGlobalConfiguration;
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.profile.path.AwsProfileFileLocationProvider;
+
+import java.io.File;
+
+/**
+ * If the {@value SDKGlobalConfiguration#AWS_CONFIG_FILE_ENV_VAR} environment variable is set then we source
+ * the config file from the location specified.
+ */
+@SdkInternalApi
+public class ConfigEnvVarOverrideLocationProvider implements AwsProfileFileLocationProvider {
+
+ @Override
+ public File getLocation() {
+ String overrideLocation = System.getenv(SDKGlobalConfiguration.AWS_CONFIG_FILE_ENV_VAR);
+ if (overrideLocation != null) {
+ return new File(overrideLocation);
+ }
+ return null;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/config/SharedConfigDefaultLocationProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/config/SharedConfigDefaultLocationProvider.java
new file mode 100644
index 0000000..227b468
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/config/SharedConfigDefaultLocationProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.profile.path.config;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.profile.path.AwsDirectoryBasePathProvider;
+
+import java.io.File;
+
+/**
+ * Checks if there is a config file present at the default location (~/.aws/config).
+ */
+@SdkInternalApi
+public class SharedConfigDefaultLocationProvider extends AwsDirectoryBasePathProvider {
+
+ /**
+ * Default name of the shared AWS config file.
+ */
+ private static final String DEFAULT_CONFIG_FILE_NAME = "config";
+
+ @Override
+ public File getLocation() {
+ File file = new File(getAwsDirectory(), DEFAULT_CONFIG_FILE_NAME);
+ if (file.exists() && file.isFile()) {
+ return file;
+ }
+ return null;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsDefaultLocationProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsDefaultLocationProvider.java
new file mode 100644
index 0000000..47a9be6
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsDefaultLocationProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.profile.path.cred;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.profile.path.AwsDirectoryBasePathProvider;
+
+import java.io.File;
+
+/**
+ * Load shared credentials file from the default location (~/.aws/credentials).
+ */
+@SdkInternalApi
+public class CredentialsDefaultLocationProvider extends AwsDirectoryBasePathProvider {
+
+ private static final String DEFAULT_CREDENTIAL_PROFILES_FILENAME = "credentials";
+
+ @Override
+ public File getLocation() {
+ File credentialProfiles = new File(getAwsDirectory(), DEFAULT_CREDENTIAL_PROFILES_FILENAME);
+ if (credentialProfiles.exists() && credentialProfiles.isFile()) {
+ return credentialProfiles;
+ }
+ return null;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsEnvVarOverrideLocationProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsEnvVarOverrideLocationProvider.java
new file mode 100644
index 0000000..26a2b29
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsEnvVarOverrideLocationProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.profile.path.cred;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.profile.path.AwsProfileFileLocationProvider;
+
+import java.io.File;
+
+/**
+ * If {@value #CREDENTIAL_PROFILES_FILE_ENVIRONMENT_VARIABLE} environment variable is set then the
+ * shared credentials file is source from it's location.
+ */
+@SdkInternalApi
+public class CredentialsEnvVarOverrideLocationProvider implements AwsProfileFileLocationProvider {
+
+ private static final String CREDENTIAL_PROFILES_FILE_ENVIRONMENT_VARIABLE = "AWS_CREDENTIAL_PROFILES_FILE";
+
+ @Override
+ public File getLocation() {
+ String credentialProfilesFileOverride = System
+ .getenv(CREDENTIAL_PROFILES_FILE_ENVIRONMENT_VARIABLE);
+ if (credentialProfilesFileOverride == null) {
+ return null;
+ } else {
+ return new File(credentialProfilesFileOverride);
+ }
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsLegacyConfigLocationProvider.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsLegacyConfigLocationProvider.java
new file mode 100644
index 0000000..2693068
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/profile/path/cred/CredentialsLegacyConfigLocationProvider.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.profile.path.cred;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.profile.path.AwsDirectoryBasePathProvider;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.File;
+
+/**
+ * Treats the CLI config file as the source of credentials. We support this for legacy reasons,
+ * ideally credentials should be defined in the separate shared credentials file
+ * (~/.aws/credentials). Any credentials defined in the shared credentials file take precedence over
+ * credentials sourced from here.
+ */
+@SdkInternalApi
+public class CredentialsLegacyConfigLocationProvider extends AwsDirectoryBasePathProvider {
+
+ private static final Log LOG = LogFactory.getLog(CredentialsLegacyConfigLocationProvider.class);
+
+ /**
+ * File name of the default location of the CLI config file.
+ */
+ private static final String LEGACY_CONFIG_PROFILES_FILENAME = "config";
+
+ @Override
+ public File getLocation() {
+ File legacyConfigProfiles = new File(getAwsDirectory(), LEGACY_CONFIG_PROFILES_FILENAME);
+ if (legacyConfigProfiles.exists() && legacyConfigProfiles.isFile()) {
+ LOG.warn("Found the legacy config profiles file at [" +
+ legacyConfigProfiles.getAbsolutePath() +
+ "]. Please move it to the latest default location [~/.aws/credentials].");
+ return legacyConfigProfiles;
+ }
+ return null;
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/CredentialsEndpointRetryParameters.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/CredentialsEndpointRetryParameters.java
new file mode 100644
index 0000000..f7933c9
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/CredentialsEndpointRetryParameters.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.retry.internal;
+
+import com.amazonaws.annotation.SdkInternalApi;
+
+/**
+ * Parameters that are used in {@link CredentialsEndpointRetryPolicy}.
+ */
+@SdkInternalApi
+public class CredentialsEndpointRetryParameters {
+
+ private final Integer statusCode;
+
+ private final Exception exception;
+
+ private CredentialsEndpointRetryParameters(Builder builder) {
+ this.statusCode = builder.statusCode;
+ this.exception = builder.exception;
+ }
+
+ public Integer getStatusCode() {
+ return statusCode;
+ }
+
+ public Exception getException() {
+ return exception;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+
+ private final Integer statusCode;
+
+ private final Exception exception;
+
+ private Builder() {
+ this.statusCode = null;
+ this.exception = null;
+ }
+
+ private Builder(Integer statusCode, Exception exception) {
+ this.statusCode = statusCode;
+ this.exception = exception;
+ }
+
+ /**
+ * @param statusCode The status code from Http response.
+ *
+ * @return This object for method chaining.
+ */
+ public Builder withStatusCode(Integer statusCode) {
+ return new Builder(statusCode, this.exception);
+ }
+
+ /**
+ *
+ * @param exception The exception that was thrown.
+ * @return This object for method chaining.
+ */
+ public Builder withException(Exception exception) {
+ return new Builder(this.statusCode, exception);
+ }
+
+ public CredentialsEndpointRetryParameters build() {
+ return new CredentialsEndpointRetryParameters(this);
+ }
+
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/CredentialsEndpointRetryPolicy.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/CredentialsEndpointRetryPolicy.java
new file mode 100644
index 0000000..3d2bd41
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/CredentialsEndpointRetryPolicy.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.amazonaws.retry.internal;
+
+import com.amazonaws.annotation.SdkInternalApi;
+import com.amazonaws.auth.ContainerCredentialsProvider;
+import com.amazonaws.auth.InstanceProfileCredentialsProvider;
+
+/**
+ * Custom retry policy for credentials providers ({@link InstanceProfileCredentialsProvider},
+ * {@link ContainerCredentialsProvider}) that retrieve credentials from a local endpoint in EC2 host.
+ *
+ * Internal use only.
+ */
+@SdkInternalApi
+public interface CredentialsEndpointRetryPolicy {
+
+ public static final CredentialsEndpointRetryPolicy NO_RETRY = new CredentialsEndpointRetryPolicy() {
+
+ @Override
+ public boolean shouldRetry(int retriesAttempted, CredentialsEndpointRetryParameters retryParams) {
+ return false;
+ }
+ };
+
+ /**
+ * Returns whether a failed request should be retried.
+ *
+ * @param retriesAttempted
+ * The number of times the current request has been
+ * attempted.
+ *
+ * @return True if the failed request should be retried.
+ */
+ boolean shouldRetry(int retriesAttempted, CredentialsEndpointRetryParameters retryParams);
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/services/s3/model/Region.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/services/s3/model/Region.java
new file mode 100644
index 0000000..a44ad9c
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/services/s3/model/Region.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.services.s3.model;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+
+/**
+ * Specifies constants that define Amazon S3 Regions.
+ * <p>
+ * Amazon S3 Regions allow the user to choose the geographical region where Amazon S3
+ * will store the buckets the user creates. Choose a Amazon S3 Region to optimize
+ * latency, minimize costs, or address regulatory requirements.
+ * </p>
+ * <p>
+ * Objects stored in a Amazon S3 Region never leave that region unless explicitly
+ * transferred to another region.
+ * </p>
+ * <p>
+ * In Amazon S3, all the regions provides
+ * read-after-write consistency for PUTS of new objects in Amazon
+ * S3 buckets and eventual consistency for overwrite PUTS and DELETES.
+ * </p>
+ */
+public enum Region {
+
+ /**
+ * The US Standard Amazon S3 Region. This region is equivalent to 'us-east-1', see
+ * <a href="https://aws.amazon.com/s3/faqs/">Amazon Simple Storage Service (S3) FAQs</a> for more information.
+ * <p>
+ * This is the default Amazon S3 Region. All requests sent to <code>s3.amazonaws.com</code> go
+ * to this region unless a location constraint is specified when creating a bucket.
+ */
+ US_Standard((String[]) null),
+
+ /**
+ * The US-East-1 (Virginia) Region. This region
+ * uses Amazon S3 servers located in Virginia.
+ * <p>
+ * When using buckets in this region, set the client
+ * endpoint to <code>s3.us-east-2.amazonaws.com</code> on all requests to these buckets
+ * to reduce any latency experienced after the first hour of
+ * creating a bucket in this region.
+ * </p>
+ */
+ US_East_1("us-east-1"),
+
+ /**
+ * The US-East-2 (Ohio) Region. This region
+ * uses Amazon S3 servers located in Ohio.
+ * <p>
+ * When using buckets in this region, set the client
+ * endpoint to <code>s3.us-east-2.amazonaws.com</code> on all requests to these buckets
+ * to reduce any latency experienced after the first hour of
+ * creating a bucket in this region.
+ * </p>
+ */
+ US_East_2("us-east-2"),
+
+ /**
+ * The US-West (Northern California) Amazon S3 Region. This region uses Amazon S3
+ * servers located in Northern California.
+ * <p>
+ * When using buckets in this region, set the client
+ * endpoint to <code>s3-us-west-1.amazonaws.com</code> on all requests to these
+ * buckets to reduce any latency experienced after the first
+ * hour of creating a bucket in this region.
+ * </p>
+ */
+ US_West("us-west-1"),
+
+ /**
+ * The US-West-2 (Oregon) Region. This region uses Amazon S3 servers located
+ * in Oregon.
+ * <p>
+ * When using buckets in this region, set the client
+ * endpoint to <code>s3-us-west-2.amazonaws.com</code> on all requests to these buckets
+ * to reduce any latency experienced after the first hour of
+ * creating a bucket in this region.
+ * </p>
+ */
+ US_West_2("us-west-2"),
+
+ /**
+ * The US GovCloud Region. This region uses Amazon S3 servers located in the Northwestern
+ * region of the United States.
+ */
+ US_GovCloud("us-gov-west-1"),
+
+ /**
+ * The EU (Ireland) Amazon S3 Region. This region uses Amazon S3 servers located
+ * in Ireland.
+ */
+ EU_Ireland("eu-west-1","EU"),
+
+ /**
+ * The EU (London) Amazon S3 Region. This region uses Amazon S3 servers located
+ * in London.
+ */
+ EU_London("eu-west-2"),
+
+ /**
+ * The EU (Paris) Amazon S3 Region. This region uses Amazon S3 servers located
+ * in Paris.
+ */
+ EU_Paris("eu-west-3"),
+
+ /**
+ * The EU (Frankfurt) Amazon S3 Region. This region uses Amazon S3 servers
+ * located in Frankfurt.
+ * <p>
+ * The EU (Frankfurt) Region requires AWS V4 authentication, therefore when
+ * accessing buckets inside this region, you need to explicitly configure
+ * the "eu-central-1" endpoint for the AmazonS3Client in order to enable V4
+ * signing:
+ *
+ * <pre>
+ * AmazonS3Client s3 = new AmazonS3Client();
+ * s3.setRegion(RegionUtils.getRegion("eu-central-1"));
+ * </pre>
+ *
+ * </p>
+ *
+ * @see AmazonS3Client#setEndpoint(String)
+ * @see AmazonS3Client#setRegion(com.amazonaws.regions.Region)
+ */
+ EU_Frankfurt("eu-central-1"),
+
+ /**
+ * The Asia Pacific (Singapore) Region. This region uses Amazon S3 servers located
+ * in Singapore.
+ * <p>
+ * When using buckets in this region, set the client
+ * endpoint to <code>s3-ap-southeast-1.amazonaws.com</code> on all requests to these buckets
+ * to reduce any latency experienced after the first hour of
+ * creating a bucket in this region.
+ * </p>
+ */
+ AP_Singapore("ap-southeast-1"),
+
+ /**
+ * The Asia Pacific (Sydney) Region. This region uses Amazon S3 servers
+ * located in Sydney, Australia.
+ * <p>
+ * When using buckets in this region, set the client endpoint to
+ * <code>s3-ap-southeast-2.amazonaws.com</code> on all requests to these buckets
+ * to reduce any latency experienced after the first hour of creating a
+ * bucket in this region.
+ * </p>
+ */
+ AP_Sydney("ap-southeast-2"),
+
+ /**
+ * The Asia Pacific (Tokyo) Region. This region uses Amazon S3 servers
+ * located in Tokyo.
+ * <p>
+ * When using buckets in this region, set the client endpoint to
+ * <code>s3-ap-northeast-1.amazonaws.com</code> on all requests to these
+ * buckets to reduce any latency experienced after the first hour of
+ * creating a bucket in this region.
+ * </p>
+ */
+ AP_Tokyo("ap-northeast-1"),
+
+ /**
+ * The Asia Pacific (Seoul) Region. This region uses Amazon S3 servers
+ * located in Seoul.
+ * <p>
+ * When using buckets in this region, set the client endpoint to
+ * <code>s3.ap-northeast-2.amazonaws.com</code> on all requests to these
+ * buckets to reduce any latency experienced after the first hour of
+ * creating a bucket in this region.
+ * </p>
+ */
+ AP_Seoul("ap-northeast-2"),
+
+ /**
+ * The Asia Pacific (Mumbai) Region. This region uses Amazon S3 servers
+ * located in Mumbai.
+ * <p>
+ * When using buckets in this region, set the client endpoint to
+ * <code>s3.ap-south-1.amazonaws.com</code> on all requests to these
+ * buckets to reduce any latency experienced after the first hour of
+ * creating a bucket in this region.
+ * </p>
+ */
+ AP_Mumbai("ap-south-1"),
+
+ /**
+ * The South America (Sao Paulo) Region. This region uses Amazon S3 servers
+ * located in Sao Paulo.
+ * <p>
+ * When using buckets in this region, set the client endpoint to
+ * <code>s3-sa-east-1.amazonaws.com</code> on all requests to these buckets
+ * to reduce any latency experienced after the first hour of creating a
+ * bucket in this region.
+ * </p>
+ */
+ SA_SaoPaulo("sa-east-1"),
+
+ /**
+ * The Canada (Central) Region. This region uses Amazon S3 servers
+ * located in Canada.
+ * <p>
+ * When using buckets in this region, set the client endpoint to
+ * <code>s3.ca-central-1.amazonaws.com</code> on all requests to these buckets
+ * to reduce any latency experienced after the first hour of creating a
+ * bucket in this region.
+ * </p>
+ */
+ CA_Central("ca-central-1"),
+
+ /**
+ * The China (Beijing) Region. This region uses Amazon S3 servers
+ * located in Beijing.
+ * <p>
+ * When using buckets in this region, you must set the client endpoint to
+ * <code>s3.cn-north-1.amazonaws.com.cn</code>.
+ * </p>
+ */
+ CN_Beijing("cn-north-1"),
+
+ /**
+ * The China (Ningxia) Region. This region uses Amazon S3 servers
+ * located in Ningxia.
+ * <p>
+ * When using buckets in this region, you must set the client endpoint to
+ * <code>s3.cn-northwest-1.amazonaws.com.cn</code>.
+ * </p>
+ */
+ CN_Northwest_1("cn-northwest-1");
+
+ /**
+ * Used to extract the S3 regional id from an S3 end point.
+ * Note this pattern will not match the S3 US standard endpoint by intent.
+ * Exampless:
+ * <pre>
+ * s3-eu-west-1.amazonaws.com
+ * s3.cn-north-1.amazonaws.com.cn
+ * </pre>
+ */
+ public static final Pattern S3_REGIONAL_ENDPOINT_PATTERN =
+ Pattern.compile("s3[-.]([^.]+)\\.amazonaws\\.com(\\.[^.]*)?");
+
+ /** The list of ID's representing each region. */
+ private final List<String> regionIds;
+
+ /**
+ * Constructs a new region with the specified region ID's.
+ *
+ * @param regionIds
+ * The list of ID's representing the S3 region.
+ */
+ private Region(String... regionIds) {
+ this.regionIds = regionIds != null ? Arrays.asList(regionIds) : null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Enum#toString()
+ */
+ @Override
+ public String toString() {
+ return getFirstRegionId0();
+ }
+
+ /**
+ * Returns the first region id or null for {@link #US_Standard}.
+ */
+ public String getFirstRegionId() {
+ return getFirstRegionId0();
+ }
+
+ private String getFirstRegionId0() {
+ return this.regionIds == null || regionIds.size() == 0
+ ? null : this.regionIds.get(0);
+ }
+
+ /**
+ * Returns the Amazon S3 Region enumeration value representing the specified Amazon
+ * S3 Region ID string. If specified string doesn't map to a known Amazon S3
+ * Region, then an <code>IllegalArgumentException</code> is thrown.
+ *
+ * @param s3RegionId
+ * The Amazon S3 region ID string.
+ *
+ * @return The Amazon S3 Region enumeration value representing the specified Amazon
+ * S3 Region ID.
+ *
+ * @throws IllegalArgumentException
+ * If the specified value does not map to one of the known
+ * Amazon S3 regions.
+ */
+ public static Region fromValue(final String s3RegionId) throws IllegalArgumentException
+ {
+ if (s3RegionId == null || s3RegionId.equals("US") || s3RegionId.equals("us-east-1")) {
+ return Region.US_Standard;
+ }
+ for (Region region : Region.values()) {
+ List<String> regionIds = region.regionIds;
+ if (regionIds != null && regionIds.contains(s3RegionId))
+ return region;
+ }
+
+ throw new IllegalArgumentException(
+ "Cannot create enum from " + s3RegionId + " value!");
+ }
+}
+
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CollectionUtils.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CollectionUtils.java
new file mode 100644
index 0000000..e4cf8a7
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CollectionUtils.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.util;
+
+import java.util.Collection;
+
+public class CollectionUtils {
+
+ public static <T> boolean isNullOrEmpty(Collection<T> collection) {
+ return collection == null || collection.isEmpty();
+ }
+
+ /**
+ * Joins a collection of strings with the given separator into a single string.
+ *
+ * @param toJoin Collection containing items to join.
+ * @param separator String to join items with.
+ * @return Empty string if collection is null or empty. Otherwise joins all strings in the collection with the separator.
+ */
+ public static String join(Collection<String> toJoin, String separator) {
+ if (isNullOrEmpty(toJoin)) {
+ return "";
+ }
+
+ StringBuilder joinedString = new StringBuilder();
+ int currentIndex = 0;
+ for (String s : toJoin) {
+ if(s != null) {
+ joinedString.append(s);
+ }
+ if (currentIndex++ != toJoin.size() - 1) {
+ joinedString.append(separator);
+ }
+ }
+ return joinedString.toString();
+ }
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/DateUtils.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/DateUtils.java
new file mode 100644
index 0000000..3cef987
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/DateUtils.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Portions copyright 2006-2009 James Murty. Please see LICENSE.txt
+ * for applicable license terms and NOTICE.txt for applicable notices.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.util;
+
+import com.amazonaws.annotation.ThreadSafe;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.ZoneId;
+import java.util.Date;
+
+/**
+ * Utilities for parsing and formatting dates.
+ */
+@ThreadSafe
+public class DateUtils {
+
+ private static final ZoneId GMT = ZoneId.of("GMT");
+
+ /** ISO 8601 format */
+ protected static final DateTimeFormatter iso8601DateFormat =
+ DateTimeFormatter.ISO_DATE_TIME.withZone(GMT);
+
+ /** Alternate ISO 8601 format without fractional seconds */
+ protected static final DateTimeFormatter alternateIso8601DateFormat =
+ DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(GMT);
+
+ /**
+ * Parses the specified date string as an ISO 8601 date and returns the Date
+ * object.
+ *
+ * @param dateString
+ * The date string to parse.
+ *
+ * @return The parsed Date object.
+ */
+ public static Date parseISO8601Date(String dateString) {
+ return doParseISO8601Date(dateString);
+ }
+
+ static Date doParseISO8601Date(final String dateStringOrig) {
+ String dateString = dateStringOrig;
+
+ // For EC2 Spot Fleet.
+ if (dateString.endsWith("+0000")) {
+ dateString = dateString
+ .substring(0, dateString.length() - 5)
+ .concat("Z");
+ }
+
+ try {
+ // Normal case: nothing special here
+ final LocalDateTime ldt = LocalDateTime.parse(dateString, iso8601DateFormat);
+ return Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
+ } catch (IllegalArgumentException e) {
+ try {
+ final LocalDateTime ldt = LocalDateTime.parse(dateString, alternateIso8601DateFormat);
+ return Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
+ // If the first ISO 8601 parser didn't work, try the alternate
+ // version which doesn't include fractional seconds
+ } catch(Exception oops) {
+ // no the alternative route doesn't work; let's bubble up the original exception
+ throw e;
+ }
+ }
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/EC2MetadataUtils.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/EC2MetadataUtils.java
new file mode 100644
index 0000000..35a1fe2
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/EC2MetadataUtils.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.util;
+
+import static com.amazonaws.SDKGlobalConfiguration.EC2_METADATA_SERVICE_OVERRIDE_SYSTEM_PROPERTY;
+
+import com.amazonaws.SDKGlobalConfiguration;
+
+/**
+ * Utility class for retrieving Amazon EC2 instance metadata.<br>
+ * You can use the data to build more generic AMIs that can be modified by
+ * configuration files supplied at launch time. For example, if you run web
+ * servers for various small businesses, they can all use the same AMI and
+ * retrieve their content from the Amazon S3 bucket you specify at launch. To
+ * add a new customer at any time, simply create a bucket for the customer, add
+ * their content, and launch your AMI.<br>
+ *
+ * <p>
+ * You can disable the use of the EC2 Instance meta data service by either setting the
+ * {@link SDKGlobalConfiguration#AWS_EC2_METADATA_DISABLED_ENV_VAR} or
+ * {@link SDKGlobalConfiguration#AWS_EC2_METADATA_DISABLED_SYSTEM_PROPERTY} to 'true'(not case sensitive).
+ *
+ * More information about Amazon EC2 Metadata
+ *
+ * @see <a
+ * href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html">Amazon
+ * EC2 User Guide: Instance Metadata</a>
+ */
+public class EC2MetadataUtils {
+
+ /** Default endpoint for the Amazon EC2 Instance Metadata Service. */
+ private static final String EC2_METADATA_SERVICE_URL = "http://169.254.169.254";
+
+ /** Default resource path for credentials in the Amazon EC2 Instance Metadata Service. */
+ public static final String SECURITY_CREDENTIALS_RESOURCE = "/latest/meta-data/iam/security-credentials/";
+
+ /**
+ * Returns the host address of the Amazon EC2 Instance Metadata Service.
+ */
+ public static String getHostAddressForEC2MetadataService() {
+ String host = System.getProperty(EC2_METADATA_SERVICE_OVERRIDE_SYSTEM_PROPERTY);
+ return host != null ? host : EC2_METADATA_SERVICE_URL;
+ }
+
+}
diff --git a/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/StringUtils.java b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/StringUtils.java
new file mode 100644
index 0000000..878b53d
--- /dev/null
+++ b/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/StringUtils.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.amazonaws.util;
+
+import java.nio.charset.Charset;
+
+/**
+ * Utilities for converting objects to strings.
+ */
+public class StringUtils {
+
+ private static final String DEFAULT_ENCODING = "UTF-8";
+
+ public static final Charset UTF8 = Charset.forName(DEFAULT_ENCODING);
+
+ /**
+ * A null-safe trim method. If the input string is null, returns null;
+ * otherwise returns a trimmed version of the input.
+ */
+ public static String trim(String value) {
+ if (value == null) {
+ return null;
+ }
+ return value.trim();
+ }
+
+ /**
+ * @return true if the given value is either null or the empty string
+ */
+ public static boolean isNullOrEmpty(String value) {
+ return value == null || value.isEmpty();
+ }
+}