예제 #1
0
        /// <summary>
        /// Check if the value of any dictionary item
        /// is of type ARN.
        /// <b>Note:</b> this assumes that there is just 0-1 ARN in the path resource dictionary
        /// </summary>
        /// <param name="dictValues">The dictionary</param>
        /// <param name="arn">ARN found in dictionary</param>
        /// <returns>A boolean whether or not the dictionary contains an ARN in the values</returns>
        internal static bool DictionaryContainsArn(IDictionary <string, string> dictValues, out Arn arn)
        {
            Arn outArn      = null;
            var matchingKvp = dictValues.FirstOrDefault(kvp => Arn.TryParse(kvp.Value, out outArn));

            arn = matchingKvp.Value != null ? outArn : null;
            return(arn != null);
        }
예제 #2
0
 public TopicConfig(Arn arn) : base(arn)
 {
     Topic = arn.ToString();
 }
예제 #3
0
        public static void ProcessRequestHandlers(IExecutionContext executionContext)
        {
            var request = executionContext.RequestContext.Request;
            var config  = executionContext.RequestContext.ClientConfig;

            // If the marshalled request has the SSE header and it is set to KMS,
            // force SigV4 for this request.
            // Current operations that may set this header:
            //  CopyObject, CopyPart, InitiateMultipart, PutObject
            string sseHeaderValue;

            if (request.Headers.TryGetValue(HeaderKeys.XAmzServerSideEncryptionHeader, out sseHeaderValue) &&
                string.Equals(sseHeaderValue, ServerSideEncryptionMethod.AWSKMS.Value, StringComparison.Ordinal))
            {
                request.SignatureVersion = SignatureVersion.SigV4;
            }
            var bucketResourcePathToken = GetBucketName(request.ResourcePath);

            if (string.IsNullOrEmpty(bucketResourcePathToken))
            {
                return;
            }

            var s3Config = config as AmazonS3Config;

            if (s3Config == null)
            {
                throw new AmazonClientException("Current config object is not of type AmazonS3Config");
            }

            //If a ServiceURL is set the config ClientRegion should be null. Under this case
            //the region needs to be determined from the ServiceURL.
            var regionEndpoint = config.RegionEndpoint;

            if (regionEndpoint == null && !string.IsNullOrEmpty(config.ServiceURL))
            {
                var regionName = AWSSDKUtils.DetermineRegion(config.ServiceURL);
                regionEndpoint = RegionEndpoint.GetBySystemName(regionName);
            }

            bool isHttp;
            bool removeBucketFromResourcePath = false;

            if (Arn.IsArn(bucketResourcePathToken))
            {
                string     accessPoint;
                UriBuilder ub;
                Arn        s3Arn = Arn.Parse(bucketResourcePathToken);
                if (s3Arn.IsService("s3") && s3Arn.TryParseAccessPoint(out accessPoint))
                {
                    if (s3Arn.IsMRAPArn())
                    {
                        var partitionDnsSuffix = RegionEndpoint.GetDnsSuffixForPartition(s3Arn.Partition);
                        ValidateMRAPAccessPoint(s3Arn, s3Config, accessPoint, partitionDnsSuffix);

                        request.SignatureVersion     = SignatureVersion.SigV4a;
                        request.AuthenticationRegion = "*";

                        isHttp = config.UseHttp;
                        var scheme = isHttp ? "http" : "https";
                        ub = new UriBuilder($"{scheme}://{accessPoint}.accesspoint.s3-global.{partitionDnsSuffix}");
                    }
                    else // Non-MRAP access point
                    {
                        ValidateS3AccessPoint(s3Arn, s3Config, regionEndpoint);
                        if (!string.IsNullOrEmpty(config.ServiceURL))
                        {
                            ub      = new UriBuilder(EndpointResolver.DetermineEndpoint(s3Config, request));
                            isHttp  = string.Equals(ub.Scheme, "http", StringComparison.OrdinalIgnoreCase);
                            ub.Host = string.Concat($"{accessPoint}-{s3Arn.AccountId}.", ub.Host);
                        }
                        else
                        {
                            isHttp = config.UseHttp;
                            var scheme     = isHttp ? "http" : "https";
                            var fipsSuffix = regionEndpoint?.SystemName?.ToLower().Contains("fips") == true ? "-fips" : "";
                            ub = new UriBuilder($"{scheme}://{accessPoint}-{s3Arn.AccountId}.s3-accesspoint{fipsSuffix}{(config.UseDualstackEndpoint ? ".dualstack" : "")}.{s3Arn.Region}.{config.RegionEndpoint.PartitionDnsSuffix}");
                        }
                    }

                    request.Endpoint = ub.Uri;
                }
                else if (s3Arn.IsService(s3ObjectLambdaServiceName) && s3Arn.TryParseAccessPoint(out accessPoint))
                {
                    ValidateS3ObjectLambdaAccessPoint(s3Arn, s3Config, regionEndpoint);

                    if (!string.IsNullOrEmpty(config.ServiceURL))
                    {
                        ub      = new UriBuilder(EndpointResolver.DetermineEndpoint(s3Config, request));
                        isHttp  = string.Equals(ub.Scheme, "http", StringComparison.OrdinalIgnoreCase);
                        ub.Host = string.Concat($"{accessPoint}-{s3Arn.AccountId}.", ub.Host);
                    }
                    else
                    {
                        isHttp = s3Config.UseHttp;
                        var scheme     = isHttp ? "http" : "https";
                        var fipsSuffix = regionEndpoint?.SystemName?.ToLower().Contains("fips") == true ? "-fips" : "";
                        ub = new UriBuilder($"{scheme}://{accessPoint}-{s3Arn.AccountId}.{s3ObjectLambdaServiceName}{fipsSuffix}.{s3Arn.Region}.{config.RegionEndpoint.PartitionDnsSuffix}");
                    }

                    request.Endpoint = ub.Uri;
                }
                else if (s3Arn.IsOutpostArn())
                {
                    var outpost = s3Arn.ParseOutpost();
                    ValidateOutpostAccessPoint(s3Arn, s3Config, regionEndpoint);
                    var region = s3Config.UseArnRegion ? s3Arn.Region : regionEndpoint.SystemName;
                    bucketResourcePathToken = outpost.FullAccessPointName;

                    if (!string.IsNullOrEmpty(config.ServiceURL))
                    {
                        ub      = new UriBuilder(EndpointResolver.DetermineEndpoint(s3Config, request));
                        isHttp  = string.Equals(ub.Scheme, "http", StringComparison.OrdinalIgnoreCase);
                        ub.Host = string.Concat($"{outpost.AccessPointName}-{s3Arn.AccountId}.{outpost.OutpostId}.", ub.Host);
                    }
                    else
                    {
                        isHttp = config.UseHttp;
                        var scheme = isHttp ? "http" : "https";
                        ub = new UriBuilder($"{scheme}://{outpost.AccessPointName}-{s3Arn.AccountId}.{outpost.OutpostId}.s3-outposts.{region}.{config.RegionEndpoint.PartitionDnsSuffix}");
                    }

                    request.Endpoint = ub.Uri;
                }
                else
                {
                    throw new AmazonClientException("Invalid ARN specified for bucket name. Only access point ARNs are allowed for the value of bucket name.");
                }
                request.OverrideSigningServiceName = s3Arn.Service;
                // The access point arn can be using a region different from the configured region for the service client.
                // If so be sure to set the authentication region so the signer will use the correct region.
                if (!s3Arn.IsMRAPArn())    // Except for MRAP where signing region and ARN region diverge
                {
                    request.AuthenticationRegion = s3Arn.Region;
                    request.SignatureVersion     = SignatureVersion.SigV4;
                }

                removeBucketFromResourcePath = true;
            }
            else // not an arn
            {
                // If path style is not forced and the bucket name is DNS
                // compatible modify the endpoint to use virtual host style
                // addressing
                var bucketIsDnsCompatible = IsDnsCompatibleBucketName(bucketResourcePathToken);
                var ub = new UriBuilder(EndpointResolver.DetermineEndpoint(s3Config, request));
                isHttp = string.Equals(ub.Scheme, "http", StringComparison.OrdinalIgnoreCase);

                if (!s3Config.ForcePathStyle && bucketIsDnsCompatible)
                {
                    // If using HTTPS, bucketName cannot contain a period
                    if (isHttp || bucketResourcePathToken.IndexOf('.') < 0)
                    {
                        // Add bucket to host
                        ub.Host                      = string.Concat(bucketResourcePathToken, ".", ub.Host);
                        request.Endpoint             = ub.Uri;
                        removeBucketFromResourcePath = true;
                    }
                }

                if (request.OriginalRequest.GetType() == typeof(WriteGetObjectResponseRequest))
                {
                    if (!string.IsNullOrEmpty(config.ServiceURL))
                    {
                        ub     = new UriBuilder(EndpointResolver.DetermineEndpoint(s3Config, request));
                        isHttp = string.Equals(ub.Scheme, "http", StringComparison.OrdinalIgnoreCase);
                    }
                    else
                    {
                        isHttp = s3Config.UseHttp;
                        var scheme = isHttp ? "http" : "https";
                        var region = regionEndpoint.SystemName == "us-east-1-regional" ? "us-east-1" : regionEndpoint.SystemName;
                        ub = new UriBuilder($"{scheme}://{request.Headers["x-amz-request-route"]}.{s3ObjectLambdaServiceName}.{region}.{config.RegionEndpoint.PartitionDnsSuffix}");
                    }

                    request.Endpoint = ub.Uri;
                    request.OverrideSigningServiceName = s3ObjectLambdaServiceName;
                    request.SignatureVersion           = SignatureVersion.SigV4;
                }

                if (s3Config.UseAccelerateEndpoint)
                {
                    // Validate if bucket name is accelerate compatible and enable acceleration by using
                    // Accelerate endpoint for this request

                    if (!bucketIsDnsCompatible || BucketNameContainsPeriod(bucketResourcePathToken))
                    {
                        throw new AmazonClientException(
                                  @"S3 accelerate is enabled for this request but the bucket name is not accelerate compatible." +
                                  " The bucket name must be DNS compatible (http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html)" +
                                  " and must not contain any period (.) characters to be accelerate compatible.");
                    }

                    var  originalRequest        = request.OriginalRequest;
                    bool accelerateSupportedApi = !UnsupportedAccelerateRequestTypes.Contains(originalRequest.GetType());

                    // Skip requests which are not supported
                    if (accelerateSupportedApi)
                    {
                        request.Endpoint = GetAccelerateEndpoint(bucketResourcePathToken, s3Config);

                        if (request.SignatureVersion == SignatureVersion.SigV4 && s3Config.RegionEndpoint != null)
                        {
                            request.AlternateEndpoint = s3Config.RegionEndpoint;
                        }
                    }
                }
            }

            if (removeBucketFromResourcePath)
            {
                // Remove bucket from resource path but retain in canonical resource
                // prefix, so it gets included when we sign the request later
                var resourcePath        = request.ResourcePath;
                var canonicalBucketName = string.Concat("/", bucketResourcePathToken);
                if (resourcePath.IndexOf(canonicalBucketName, StringComparison.Ordinal) == 0)
                {
                    resourcePath = resourcePath.Substring(canonicalBucketName.Length);
                }

                request.ResourcePath            = resourcePath;
                request.CanonicalResourcePrefix = canonicalBucketName;
            }

            // Some parameters should not be sent over HTTP, just HTTPS
            if (isHttp)
            {
                ValidateHttpsOnlyHeaders(request);
            }
        }
        /// <summary>
        /// Marshaller the request object to the HTTP request.
        /// </summary>
        /// <param name="publicRequest"></param>
        /// <returns></returns>
        public IRequest Marshall(PutBucketLifecycleConfigurationRequest publicRequest)
        {
            var request = new DefaultRequest(publicRequest, "Amazon.S3Control");

            request.HttpMethod = "PUT";
            if (Arn.IsArn(publicRequest.Bucket))
            {
                publicRequest.AccountId = Amazon.S3Control.Internal.S3ArnUtils.GetAccountIdBasedOnArn(
                    publicRequest.AccountId,
                    Arn.Parse(publicRequest.Bucket).AccountId
                    );
            }

            if (publicRequest.IsSetAccountId())
            {
                request.Headers["x-amz-account-id"] = publicRequest.AccountId;
            }
            if (!publicRequest.IsSetBucket())
            {
                throw new AmazonS3ControlException("Request object does not have required field Bucket set");
            }
            request.AddPathResource("{name}", StringUtils.FromString(publicRequest.Bucket));
            request.ResourcePath = "/v20180820/bucket/{name}/lifecycleconfiguration";

            var stringWriter = new StringWriter(CultureInfo.InvariantCulture);

            using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings()
            {
                Encoding = System.Text.Encoding.UTF8, OmitXmlDeclaration = true
            }))
            {
                if (publicRequest.IsSetLifecycleConfiguration())
                {
                    xmlWriter.WriteStartElement("LifecycleConfiguration", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                    var publicRequestLifecycleConfigurationRules = publicRequest.LifecycleConfiguration.Rules;
                    if (publicRequestLifecycleConfigurationRules != null && publicRequestLifecycleConfigurationRules.Count > 0)
                    {
                        xmlWriter.WriteStartElement("Rules", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                        foreach (var publicRequestLifecycleConfigurationRulesValue in publicRequestLifecycleConfigurationRules)
                        {
                            if (publicRequestLifecycleConfigurationRulesValue != null)
                            {
                                xmlWriter.WriteStartElement("Rule", "http://awss3control.amazonaws.com/doc/2018-08-20/");

                                if (publicRequestLifecycleConfigurationRulesValue.AbortIncompleteMultipartUpload != null)
                                {
                                    xmlWriter.WriteStartElement("AbortIncompleteMultipartUpload", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                    if (publicRequestLifecycleConfigurationRulesValue.AbortIncompleteMultipartUpload.IsSetDaysAfterInitiation())
                                    {
                                        xmlWriter.WriteElementString("DaysAfterInitiation", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromInt(publicRequestLifecycleConfigurationRulesValue.AbortIncompleteMultipartUpload.DaysAfterInitiation));
                                    }

                                    xmlWriter.WriteEndElement();
                                }

                                if (publicRequestLifecycleConfigurationRulesValue.Expiration != null)
                                {
                                    xmlWriter.WriteStartElement("Expiration", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                    if (publicRequestLifecycleConfigurationRulesValue.Expiration.IsSetDate())
                                    {
                                        xmlWriter.WriteElementString("Date", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromDateTimeToISO8601(publicRequestLifecycleConfigurationRulesValue.Expiration.Date));
                                    }

                                    if (publicRequestLifecycleConfigurationRulesValue.Expiration.IsSetDays())
                                    {
                                        xmlWriter.WriteElementString("Days", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromInt(publicRequestLifecycleConfigurationRulesValue.Expiration.Days));
                                    }

                                    if (publicRequestLifecycleConfigurationRulesValue.Expiration.IsSetExpiredObjectDeleteMarker())
                                    {
                                        xmlWriter.WriteElementString("ExpiredObjectDeleteMarker", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromBool(publicRequestLifecycleConfigurationRulesValue.Expiration.ExpiredObjectDeleteMarker));
                                    }

                                    xmlWriter.WriteEndElement();
                                }

                                if (publicRequestLifecycleConfigurationRulesValue.Filter != null)
                                {
                                    xmlWriter.WriteStartElement("Filter", "http://awss3control.amazonaws.com/doc/2018-08-20/");

                                    if (publicRequestLifecycleConfigurationRulesValue.Filter.And != null)
                                    {
                                        xmlWriter.WriteStartElement("And", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                        if (publicRequestLifecycleConfigurationRulesValue.Filter.And.IsSetPrefix())
                                        {
                                            xmlWriter.WriteElementString("Prefix", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValue.Filter.And.Prefix));
                                        }

                                        var publicRequestLifecycleConfigurationRulesValueFilterAndTags = publicRequestLifecycleConfigurationRulesValue.Filter.And.Tags;
                                        if (publicRequestLifecycleConfigurationRulesValueFilterAndTags != null && publicRequestLifecycleConfigurationRulesValueFilterAndTags.Count > 0)
                                        {
                                            xmlWriter.WriteStartElement("Tags", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                            foreach (var publicRequestLifecycleConfigurationRulesValueFilterAndTagsValue in publicRequestLifecycleConfigurationRulesValueFilterAndTags)
                                            {
                                                if (publicRequestLifecycleConfigurationRulesValueFilterAndTagsValue != null)
                                                {
                                                    xmlWriter.WriteStartElement("member", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                                    if (publicRequestLifecycleConfigurationRulesValueFilterAndTagsValue.IsSetKey())
                                                    {
                                                        xmlWriter.WriteElementString("Key", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValueFilterAndTagsValue.Key));
                                                    }

                                                    if (publicRequestLifecycleConfigurationRulesValueFilterAndTagsValue.IsSetValue())
                                                    {
                                                        xmlWriter.WriteElementString("Value", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValueFilterAndTagsValue.Value));
                                                    }

                                                    xmlWriter.WriteEndElement();
                                                }
                                            }
                                            xmlWriter.WriteEndElement();
                                        }
                                        xmlWriter.WriteEndElement();
                                    }
                                    if (publicRequestLifecycleConfigurationRulesValue.Filter.IsSetPrefix())
                                    {
                                        xmlWriter.WriteElementString("Prefix", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValue.Filter.Prefix));
                                    }


                                    if (publicRequestLifecycleConfigurationRulesValue.Filter.Tag != null)
                                    {
                                        xmlWriter.WriteStartElement("Tag", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                        if (publicRequestLifecycleConfigurationRulesValue.Filter.Tag.IsSetKey())
                                        {
                                            xmlWriter.WriteElementString("Key", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValue.Filter.Tag.Key));
                                        }

                                        if (publicRequestLifecycleConfigurationRulesValue.Filter.Tag.IsSetValue())
                                        {
                                            xmlWriter.WriteElementString("Value", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValue.Filter.Tag.Value));
                                        }

                                        xmlWriter.WriteEndElement();
                                    }
                                    xmlWriter.WriteEndElement();
                                }
                                if (publicRequestLifecycleConfigurationRulesValue.IsSetID())
                                {
                                    xmlWriter.WriteElementString("ID", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValue.ID));
                                }


                                if (publicRequestLifecycleConfigurationRulesValue.NoncurrentVersionExpiration != null)
                                {
                                    xmlWriter.WriteStartElement("NoncurrentVersionExpiration", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                    if (publicRequestLifecycleConfigurationRulesValue.NoncurrentVersionExpiration.IsSetNoncurrentDays())
                                    {
                                        xmlWriter.WriteElementString("NoncurrentDays", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromInt(publicRequestLifecycleConfigurationRulesValue.NoncurrentVersionExpiration.NoncurrentDays));
                                    }

                                    xmlWriter.WriteEndElement();
                                }
                                var publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitions = publicRequestLifecycleConfigurationRulesValue.NoncurrentVersionTransitions;
                                if (publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitions != null && publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitions.Count > 0)
                                {
                                    xmlWriter.WriteStartElement("NoncurrentVersionTransitions", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                    foreach (var publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitionsValue in publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitions)
                                    {
                                        if (publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitionsValue != null)
                                        {
                                            xmlWriter.WriteStartElement("NoncurrentVersionTransition", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                            if (publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitionsValue.IsSetNoncurrentDays())
                                            {
                                                xmlWriter.WriteElementString("NoncurrentDays", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromInt(publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitionsValue.NoncurrentDays));
                                            }

                                            if (publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitionsValue.IsSetStorageClass())
                                            {
                                                xmlWriter.WriteElementString("StorageClass", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValueNoncurrentVersionTransitionsValue.StorageClass));
                                            }

                                            xmlWriter.WriteEndElement();
                                        }
                                    }
                                    xmlWriter.WriteEndElement();
                                }
                                if (publicRequestLifecycleConfigurationRulesValue.IsSetStatus())
                                {
                                    xmlWriter.WriteElementString("Status", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValue.Status));
                                }

                                var publicRequestLifecycleConfigurationRulesValueTransitions = publicRequestLifecycleConfigurationRulesValue.Transitions;
                                if (publicRequestLifecycleConfigurationRulesValueTransitions != null && publicRequestLifecycleConfigurationRulesValueTransitions.Count > 0)
                                {
                                    xmlWriter.WriteStartElement("Transitions", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                    foreach (var publicRequestLifecycleConfigurationRulesValueTransitionsValue in publicRequestLifecycleConfigurationRulesValueTransitions)
                                    {
                                        if (publicRequestLifecycleConfigurationRulesValueTransitionsValue != null)
                                        {
                                            xmlWriter.WriteStartElement("Transition", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                            if (publicRequestLifecycleConfigurationRulesValueTransitionsValue.IsSetDate())
                                            {
                                                xmlWriter.WriteElementString("Date", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromDateTimeToISO8601(publicRequestLifecycleConfigurationRulesValueTransitionsValue.Date));
                                            }

                                            if (publicRequestLifecycleConfigurationRulesValueTransitionsValue.IsSetDays())
                                            {
                                                xmlWriter.WriteElementString("Days", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromInt(publicRequestLifecycleConfigurationRulesValueTransitionsValue.Days));
                                            }

                                            if (publicRequestLifecycleConfigurationRulesValueTransitionsValue.IsSetStorageClass())
                                            {
                                                xmlWriter.WriteElementString("StorageClass", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestLifecycleConfigurationRulesValueTransitionsValue.StorageClass));
                                            }

                                            xmlWriter.WriteEndElement();
                                        }
                                    }
                                    xmlWriter.WriteEndElement();
                                }
                                xmlWriter.WriteEndElement();
                            }
                        }
                        xmlWriter.WriteEndElement();
                    }

                    xmlWriter.WriteEndElement();
                }
            }
            try
            {
                string content = stringWriter.ToString();
                request.Content = System.Text.Encoding.UTF8.GetBytes(content);
                request.Headers["Content-Type"] = "application/xml";
                var checksum = Amazon.Util.AWSSDKUtils.GenerateChecksumForContent(content, true);
                request.Headers[Amazon.Util.HeaderKeys.ContentMD5Header] = checksum;
                request.Headers[Amazon.Util.HeaderKeys.XAmzApiVersion]   = "2018-08-20";
            }
            catch (EncoderFallbackException e)
            {
                throw new AmazonServiceException("Unable to marshall request to XML", e);
            }


            var hostPrefixLabels = new
            {
                AccountId = StringUtils.FromString(publicRequest.AccountId),
            };

            if (!HostPrefixUtils.IsValidLabelValue(hostPrefixLabels.AccountId))
            {
                throw new AmazonS3ControlException("AccountId can only contain alphanumeric characters and dashes and must be between 1 and 63 characters long.");
            }

            request.HostPrefix = $"{hostPrefixLabels.AccountId}.";
            return(request);
        }
예제 #5
0
 /// <summary>
 /// Check if aws ARN resembles an outpost ARN
 /// </summary>
 /// <param name="arn">An AWS ARN to parse</param>
 /// <returns>True if the ARN contains an outpost resource identifier.</returns>
 public static bool IsOutpostArn(this Arn arn)
 {
     return(!string.IsNullOrEmpty(arn.Resource) &&
            (S3ArnUtils.ArnSplit.Any(i => arn.Resource.StartsWith($"{ResourceTypeOutpost}{i}")) ||
             arn.Resource.Equals(ResourceTypeOutpost)));
 }
예제 #6
0
 /// <summary>
 /// Check if the ARN has a valid service name
 /// </summary>
 /// <param name="arn">The ARN which is being validated</param>
 public static bool IsValidService(this Arn arn)
 {
     return(arn.Service.Equals(S3ArnUtils.S3OutpostsService));
 }
예제 #7
0
        /// <summary>
        /// Create a signed URL allowing access to a resource that would
        /// usually require authentication.
        /// </summary>
        /// <remarks>
        /// <para>
        /// When using query string authentication you create a query,
        /// specify an expiration time for the query, sign it with your
        /// signature, place the data in an HTTP request, and distribute
        /// the request to a user or embed the request in a web page.
        /// </para>
        /// <para>
        /// A PreSigned URL can be generated for GET, PUT, DELETE and HEAD
        /// operations on your bucketName, keys, and versions.
        /// </para>
        /// </remarks>
        /// <param name="request">The GetPreSignedUrlRequest that defines the
        /// parameters of the operation.</param>
        /// <param name="useSigV2Fallback">determines if signing will fall back to SigV2 if the
        /// signing region is us-east-1</param>
        /// <returns>A string that is the signed http request.</returns>
        /// <exception cref="T:System.ArgumentException" />
        /// <exception cref="T:System.ArgumentNullException" />
        internal string GetPreSignedURLInternal(GetPreSignedUrlRequest request, bool useSigV2Fallback = true)
        {
            if (Credentials == null)
            {
                throw new AmazonS3Exception("Credentials must be specified, cannot call method anonymously");
            }

            if (request == null)
            {
                throw new ArgumentNullException("request", "The PreSignedUrlRequest specified is null!");
            }

            if (!request.IsSetExpires())
            {
                throw new InvalidOperationException("The Expires specified is null!");
            }

            var aws4Signing = AWSConfigsS3.UseSignatureVersion4;

            Arn    arn;
            string accessPoint;

            if (Arn.TryParse(request.BucketName, out arn) && arn.TryParseAccessPoint(out accessPoint))
            {
                aws4Signing = true;
            }
            else
            {
                var region = AWS4Signer.DetermineSigningRegion(Config, "s3", alternateEndpoint: null, request: null);
                if (aws4Signing && string.IsNullOrEmpty(region))
                {
                    throw new InvalidOperationException("To use AWS4 signing, a region must be specified in the client configuration using the AuthenticationRegion or Region properties, or be determinable from the service URL.");
                }

                RegionEndpoint endpoint = RegionEndpoint.GetBySystemName(region);
                var            s3SignatureVersionOverride = endpoint.GetEndpointForService("s3").SignatureVersionOverride;
                if (s3SignatureVersionOverride == "4" || s3SignatureVersionOverride == null)
                {
                    aws4Signing = true;
                }

                var fallbackToSigV2 = useSigV2Fallback && !AWSConfigsS3.UseSigV4SetExplicitly;
                if (endpoint == RegionEndpoint.USEast1 && fallbackToSigV2)
                {
                    aws4Signing = false;
                }

                // If the expiration is longer than SigV4 will allow then automatically use SigV2 instead.
                // But only if the region we're signing for allows SigV2.
                if (aws4Signing)
                {
                    var secondsUntilExpiration = GetSecondsUntilExpiration(this.Config, request, aws4Signing);

                    if (secondsUntilExpiration > AWS4PreSignedUrlSigner.MaxAWS4PreSignedUrlExpiry &&
                        s3SignatureVersionOverride == "2")
                    {
                        aws4Signing = false;
                    }
                }
            }


            var immutableCredentials = Credentials.GetCredentials();
            var irequest             = Marshall(this.Config, request, immutableCredentials.AccessKey, immutableCredentials.Token, aws4Signing);

            irequest.Endpoint = EndpointResolver.DetermineEndpoint(this.Config, irequest);

            var context = new Amazon.Runtime.Internal.ExecutionContext(new Amazon.Runtime.Internal.RequestContext(true, new NullSigner())
            {
                Request = irequest, ClientConfig = this.Config
            }, null);

            AmazonS3PostMarshallHandler.ProcessRequestHandlers(context);

            var metrics = new RequestMetrics();

            string authorization;

            if (aws4Signing)
            {
                var aws4Signer    = new AWS4PreSignedUrlSigner();
                var signingResult = aws4Signer.SignRequest(irequest,
                                                           this.Config,
                                                           metrics,
                                                           immutableCredentials.AccessKey,
                                                           immutableCredentials.SecretKey);
                authorization = "&" + signingResult.ForQueryParameters;
            }
            else
            {
                Amazon.S3.Internal.S3Signer.SignRequest(irequest, metrics, immutableCredentials.AccessKey, immutableCredentials.SecretKey);
                authorization = irequest.Headers[HeaderKeys.AuthorizationHeader];
                authorization = authorization.Substring(authorization.IndexOf(":", StringComparison.Ordinal) + 1);
                authorization = "&Signature=" + AmazonS3Util.UrlEncode(authorization, false);
            }

            Uri    url    = AmazonServiceClient.ComposeUrl(irequest);
            string result = url.AbsoluteUri + authorization;

            Protocol protocol = DetermineProtocol();

            if (request.Protocol != protocol)
            {
                switch (protocol)
                {
                case Protocol.HTTP:
                    result = result.Replace("http://", "https://");
                    break;

                case Protocol.HTTPS:
                    result = result.Replace("https://", "http://");
                    break;
                }
            }
            return(result);
        }
예제 #8
0
 /// <summary>
 /// Check if the ARN has a valid Account ID
 /// </summary>
 /// <param name="arn">The ARN which is being validated</param>
 public static bool HasValidAccountId(this Arn arn)
 {
     return(string.IsNullOrEmpty(arn.AccountId) || (arn.AccountId.Length == 12 && arn.AccountId.ToCharArray().All(x => char.IsDigit(x))));
 }
예제 #9
0
        /// <summary>
        /// Marshaller the request object to the HTTP request.
        /// </summary>
        /// <param name="publicRequest"></param>
        /// <returns></returns>
        public IRequest Marshall(PutBucketTaggingRequest publicRequest)
        {
            var request = new DefaultRequest(publicRequest, "Amazon.S3Control");

            request.HttpMethod = "PUT";
            if (Arn.IsArn(publicRequest.Bucket))
            {
                publicRequest.AccountId = Amazon.S3Control.Internal.S3ArnUtils.GetAccountIdBasedOnArn(
                    publicRequest.AccountId,
                    Arn.Parse(publicRequest.Bucket).AccountId
                    );
            }

            if (publicRequest.IsSetAccountId())
            {
                request.Headers["x-amz-account-id"] = publicRequest.AccountId;
            }
            if (!publicRequest.IsSetBucket())
            {
                throw new AmazonS3ControlException("Request object does not have required field Bucket set");
            }
            request.AddPathResource("{name}", StringUtils.FromString(publicRequest.Bucket));
            request.ResourcePath = "/v20180820/bucket/{name}/tagging";

            var stringWriter = new XMLEncodedStringWriter(CultureInfo.InvariantCulture);

            using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings()
            {
                Encoding = System.Text.Encoding.UTF8, OmitXmlDeclaration = true, NewLineHandling = NewLineHandling.Entitize
            }))
            {
                if (publicRequest.IsSetTagging())
                {
                    xmlWriter.WriteStartElement("Tagging", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                    var publicRequestTaggingTagSet = publicRequest.Tagging.TagSet;
                    if (publicRequestTaggingTagSet != null && publicRequestTaggingTagSet.Count > 0)
                    {
                        xmlWriter.WriteStartElement("TagSet", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                        foreach (var publicRequestTaggingTagSetValue in publicRequestTaggingTagSet)
                        {
                            if (publicRequestTaggingTagSetValue != null)
                            {
                                xmlWriter.WriteStartElement("member", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                                if (publicRequestTaggingTagSetValue.IsSetKey())
                                {
                                    xmlWriter.WriteElementString("Key", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestTaggingTagSetValue.Key));
                                }

                                if (publicRequestTaggingTagSetValue.IsSetValue())
                                {
                                    xmlWriter.WriteElementString("Value", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequestTaggingTagSetValue.Value));
                                }

                                xmlWriter.WriteEndElement();
                            }
                        }
                        xmlWriter.WriteEndElement();
                    }

                    xmlWriter.WriteEndElement();
                }
            }
            try
            {
                string content = stringWriter.ToString();
                request.Content = System.Text.Encoding.UTF8.GetBytes(content);
                request.Headers["Content-Type"] = "application/xml";
                ChecksumUtils.SetRequestChecksumMD5(request);
                request.Headers[Amazon.Util.HeaderKeys.XAmzApiVersion] = "2018-08-20";
            }
            catch (EncoderFallbackException e)
            {
                throw new AmazonServiceException("Unable to marshall request to XML", e);
            }


            var hostPrefixLabels = new
            {
                AccountId = StringUtils.FromString(publicRequest.AccountId),
            };

            if (!HostPrefixUtils.IsValidLabelValue(hostPrefixLabels.AccountId))
            {
                throw new AmazonS3ControlException("AccountId can only contain alphanumeric characters and dashes and must be between 1 and 63 characters long.");
            }

            request.HostPrefix = $"{hostPrefixLabels.AccountId}.";
            return(request);
        }
        /// <summary>
        /// Marshaller the request object to the HTTP request.
        /// </summary>
        /// <param name="publicRequest"></param>
        /// <returns></returns>
        public IRequest Marshall(CreateAccessPointRequest publicRequest)
        {
            var request = new DefaultRequest(publicRequest, "Amazon.S3Control");

            request.HttpMethod = "PUT";
            if (Arn.IsArn(publicRequest.Bucket))
            {
                publicRequest.AccountId = Amazon.S3Control.Internal.S3ArnUtils.GetAccountIdBasedOnArn(
                    publicRequest.AccountId,
                    Arn.Parse(publicRequest.Bucket).AccountId
                    );
            }

            if (publicRequest.IsSetAccountId())
            {
                request.Headers["x-amz-account-id"] = publicRequest.AccountId;
            }
            if (!publicRequest.IsSetName())
            {
                throw new AmazonS3ControlException("Request object does not have required field Name set");
            }
            request.AddPathResource("{name}", StringUtils.FromString(publicRequest.Name));
            request.ResourcePath      = "/v20180820/accesspoint/{name}";
            request.MarshallerVersion = 2;

            var stringWriter = new StringWriter(CultureInfo.InvariantCulture);

            using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings()
            {
                Encoding = System.Text.Encoding.UTF8, OmitXmlDeclaration = true
            }))
            {
                xmlWriter.WriteStartElement("CreateAccessPointRequest", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                if (publicRequest.IsSetBucket())
                {
                    xmlWriter.WriteElementString("Bucket", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequest.Bucket));
                }


                if (publicRequest.PublicAccessBlockConfiguration != null)
                {
                    xmlWriter.WriteStartElement("PublicAccessBlockConfiguration", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                    if (publicRequest.PublicAccessBlockConfiguration.IsSetBlockPublicAcls())
                    {
                        xmlWriter.WriteElementString("BlockPublicAcls", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromBool(publicRequest.PublicAccessBlockConfiguration.BlockPublicAcls));
                    }

                    if (publicRequest.PublicAccessBlockConfiguration.IsSetBlockPublicPolicy())
                    {
                        xmlWriter.WriteElementString("BlockPublicPolicy", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromBool(publicRequest.PublicAccessBlockConfiguration.BlockPublicPolicy));
                    }

                    if (publicRequest.PublicAccessBlockConfiguration.IsSetIgnorePublicAcls())
                    {
                        xmlWriter.WriteElementString("IgnorePublicAcls", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromBool(publicRequest.PublicAccessBlockConfiguration.IgnorePublicAcls));
                    }

                    if (publicRequest.PublicAccessBlockConfiguration.IsSetRestrictPublicBuckets())
                    {
                        xmlWriter.WriteElementString("RestrictPublicBuckets", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromBool(publicRequest.PublicAccessBlockConfiguration.RestrictPublicBuckets));
                    }

                    xmlWriter.WriteEndElement();
                }

                if (publicRequest.VpcConfiguration != null)
                {
                    xmlWriter.WriteStartElement("VpcConfiguration", "http://awss3control.amazonaws.com/doc/2018-08-20/");
                    if (publicRequest.VpcConfiguration.IsSetVpcId())
                    {
                        xmlWriter.WriteElementString("VpcId", "http://awss3control.amazonaws.com/doc/2018-08-20/", StringUtils.FromString(publicRequest.VpcConfiguration.VpcId));
                    }

                    xmlWriter.WriteEndElement();
                }

                xmlWriter.WriteEndElement();
            }
            try
            {
                string content = stringWriter.ToString();
                request.Content = System.Text.Encoding.UTF8.GetBytes(content);
                request.Headers["Content-Type"] = "application/xml";
                request.Headers[Amazon.Util.HeaderKeys.XAmzApiVersion] = "2018-08-20";
            }
            catch (EncoderFallbackException e)
            {
                throw new AmazonServiceException("Unable to marshall request to XML", e);
            }


            var hostPrefixLabels = new
            {
                AccountId = StringUtils.FromString(publicRequest.AccountId),
            };

            if (!HostPrefixUtils.IsValidLabelValue(hostPrefixLabels.AccountId))
            {
                throw new AmazonS3ControlException("AccountId can only contain alphanumeric characters and dashes and must be between 1 and 63 characters long.");
            }

            request.HostPrefix = $"{hostPrefixLabels.AccountId}.";
            return(request);
        }
예제 #11
0
 /// <summary>
 /// Checks whether an ARN belongs to a particular service
 /// </summary>
 /// <returns>True if a match is found</returns>
 public static bool IsService(this Arn arn, string serviceName)
 {
     return(arn.Service.Equals(serviceName, StringComparison.Ordinal));
 }