From 84f2de76490d8fa07fecbbe55b334c23b46f34de Mon Sep 17 00:00:00 2001 From: Jaex Date: Mon, 20 Mar 2017 02:05:23 +0300 Subject: [PATCH] Added DreamObjects support, Amazon S3 Identifier optional now it can be automatically populated from hostname --- ShareX.UploadersLib/FileUploaders/AmazonS3.cs | 61 ++++++++++++++----- .../FileUploaders/AmazonS3Region.cs | 8 ++- .../ShareX.UploadersLib.csproj | 1 - 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/ShareX.UploadersLib/FileUploaders/AmazonS3.cs b/ShareX.UploadersLib/FileUploaders/AmazonS3.cs index 7723b6248..aed1508b9 100644 --- a/ShareX.UploadersLib/FileUploaders/AmazonS3.cs +++ b/ShareX.UploadersLib/FileUploaders/AmazonS3.cs @@ -48,7 +48,7 @@ public override bool CheckConfig(UploadersConfig config) { return config.AmazonS3Settings != null && !string.IsNullOrEmpty(config.AmazonS3Settings.AccessKeyID) && !string.IsNullOrEmpty(config.AmazonS3Settings.SecretAccessKey) && !string.IsNullOrEmpty(config.AmazonS3Settings.RegionHostname) && - !string.IsNullOrEmpty(config.AmazonS3Settings.RegionIdentifier) && !string.IsNullOrEmpty(config.AmazonS3Settings.Bucket); + !string.IsNullOrEmpty(config.AmazonS3Settings.Bucket); } public override GenericUploader CreateUploader(UploadersConfig config, TaskReferenceHelper taskInfo) @@ -78,7 +78,8 @@ public sealed class AmazonS3 : FileUploader new AmazonS3Region("US West (N. California)", "s3-us-west-1.amazonaws.com", "us-west-1"), new AmazonS3Region("US West (Oregon)", "s3-us-west-2.amazonaws.com", "us-west-2"), new AmazonS3Region("China (Beijing)", "s3.cn-north-1.amazonaws.com.cn", "cn-north-1"), - new AmazonS3Region("US GovCloud West (Oregon)", "s3-us-gov-west-1.amazonaws.com", "us-gov-west-1") + new AmazonS3Region("US GovCloud West (Oregon)", "s3-us-gov-west-1.amazonaws.com", "us-gov-west-1"), + new AmazonS3Region("DreamObjects", "objects-us-west-1.dream.io") }; private AmazonS3Settings Settings { get; set; } @@ -94,7 +95,8 @@ public override UploadResult Upload(Stream stream, string fileName) string host = $"{Settings.Bucket}.{hostname}"; string algorithm = "AWS4-HMAC-SHA256"; string credentialDate = DateTime.UtcNow.ToString("yyyyMMdd", CultureInfo.InvariantCulture); - string scope = $"{credentialDate}/{Settings.RegionIdentifier}/s3/aws4_request"; + string identifier = GetIdentifier(); + string scope = $"{credentialDate}/{identifier}/s3/aws4_request"; string credential = $"{Settings.AccessKeyID}/{scope}"; string longDate = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture); string expiresTotalSeconds = ((long)TimeSpan.FromHours(1).TotalSeconds).ToString(); @@ -134,12 +136,11 @@ public override UploadResult Upload(Stream stream, string fileName) scope + "\n" + BytesToHex(ComputeHash(canonicalRequest)); - byte[] secretKey = Encoding.UTF8.GetBytes("AWS4" + Settings.SecretAccessKey); - byte[] dateKey = ComputeHMAC(Encoding.UTF8.GetBytes(credentialDate), secretKey); - byte[] dateRegionKey = ComputeHMAC(Encoding.UTF8.GetBytes(Settings.RegionIdentifier), dateKey); - byte[] dateRegionServiceKey = ComputeHMAC(Encoding.UTF8.GetBytes("s3"), dateRegionKey); - byte[] signingKey = ComputeHMAC(Encoding.UTF8.GetBytes("aws4_request"), dateRegionServiceKey); - string signature = BytesToHex(ComputeHMAC(Encoding.UTF8.GetBytes(stringToSign), signingKey)); + byte[] dateKey = ComputeHMAC(credentialDate, "AWS4" + Settings.SecretAccessKey); + byte[] dateRegionKey = ComputeHMAC(identifier, dateKey); + byte[] dateRegionServiceKey = ComputeHMAC("s3", dateRegionKey); + byte[] signingKey = ComputeHMAC("aws4_request", dateRegionServiceKey); + string signature = BytesToHex(ComputeHMAC(stringToSign, signingKey)); args.Add("X-Amz-Signature", signature); @@ -170,6 +171,18 @@ public override UploadResult Upload(Stream stream, string fileName) }; } + private string GetIdentifier() + { + if (!string.IsNullOrEmpty(Settings.RegionIdentifier)) + { + return Settings.RegionIdentifier; + } + + string hostname = URLHelpers.RemovePrefixes(Settings.RegionHostname); + int index = hostname.IndexOf('.'); + return hostname.Substring(0, index); + } + private string GetUploadPath(string fileName) { string path = NameParser.Parse(NameParserType.FolderPath, Settings.ObjectPrefix.Trim('/')); @@ -216,22 +229,42 @@ private string GetSignedHeaders(NameValueCollection headers) return string.Join(";", headers.AllKeys.Select(x => x.ToLowerInvariant())); } + private byte[] ComputeHash(byte[] data) + { + using (SHA256Managed hashAlgorithm = new SHA256Managed()) + { + return hashAlgorithm.ComputeHash(data); + } + } + private byte[] ComputeHash(string data) { - byte[] bytes = Encoding.UTF8.GetBytes(data); - SHA256Managed hashstring = new SHA256Managed(); - byte[] hash = hashstring.ComputeHash(bytes); - return hash; + return ComputeHash(Encoding.UTF8.GetBytes(data)); } private byte[] ComputeHMAC(byte[] data, byte[] key) { - using (HashAlgorithm hashAlgorithm = new HMACSHA256(key)) + using (HMACSHA256 hashAlgorithm = new HMACSHA256(key)) { return hashAlgorithm.ComputeHash(data); } } + private byte[] ComputeHMAC(string data, string key) + { + return ComputeHMAC(Encoding.UTF8.GetBytes(data), Encoding.UTF8.GetBytes(key)); + } + + private byte[] ComputeHMAC(byte[] data, string key) + { + return ComputeHMAC(data, Encoding.UTF8.GetBytes(key)); + } + + private byte[] ComputeHMAC(string data, byte[] key) + { + return ComputeHMAC(Encoding.UTF8.GetBytes(data), key); + } + private string BytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); diff --git a/ShareX.UploadersLib/FileUploaders/AmazonS3Region.cs b/ShareX.UploadersLib/FileUploaders/AmazonS3Region.cs index 286ee99bb..d11dd6210 100644 --- a/ShareX.UploadersLib/FileUploaders/AmazonS3Region.cs +++ b/ShareX.UploadersLib/FileUploaders/AmazonS3Region.cs @@ -31,6 +31,12 @@ public class AmazonS3Region public string Hostname { get; set; } public string Identifier { get; set; } + public AmazonS3Region(string name, string hostname) + { + Name = name; + Hostname = hostname; + } + public AmazonS3Region(string name, string hostname, string identifier) { Name = name; @@ -40,7 +46,7 @@ public AmazonS3Region(string name, string hostname, string identifier) public override string ToString() { - return $"{Name} [{Identifier}]"; + return $"{Name} [{Hostname}]"; } } } \ No newline at end of file diff --git a/ShareX.UploadersLib/ShareX.UploadersLib.csproj b/ShareX.UploadersLib/ShareX.UploadersLib.csproj index d0842071c..1448fa4ab 100644 --- a/ShareX.UploadersLib/ShareX.UploadersLib.csproj +++ b/ShareX.UploadersLib/ShareX.UploadersLib.csproj @@ -118,7 +118,6 @@ -