Skip to content

Commit

Permalink
Refactor amazon_s34_sign().
Browse files Browse the repository at this point in the history
See: #440
  • Loading branch information
jaswsinc committed Jan 8, 2015
1 parent 4e3237f commit 6a57070
Showing 1 changed file with 34 additions and 18 deletions.
52 changes: 34 additions & 18 deletions s2member/includes/classes/files-in.inc.php
Expand Up @@ -659,15 +659,36 @@ public static function amazon_s3_sign($string = '')
* @package s2Member\Files
* @since 150108
*
* @param string $string Input string/data, to be signed by this routine.
*
* @return string An AWS4-HMAC-SHA256 signature for Amazon S3.
*/
public static function amazon_s34_sign($string = '')
{
$s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
$s3_date_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign(date('Ymd'), 'AWS4'.$s3c['secret_key']);
$s3_date_region_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign($s3c['bucket_region'], $s3_date_key);
$s3_date_region_service_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign('s3', $s3_date_region_key);
$s3_signing_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign('aws4_request', $s3_date_region_service_key);

return c_ws_plugin__s2member_utils_strings::hmac_sha1_sign((string)$string, $s3_signing_key);
}

/**
* Creates an Amazon S3 AWS4-HMAC-SHA256 signature/authorization header.
*
* @package s2Member\Files
* @since 150108
*
* @param string $domain The API endpoint domain; e.g. `[bucket].s3.amazonaws.com`.
* @param string $location The API endpoint URI; e.g. `/?acl`.
* @param string $method The request method; e.g. `GET`, `PUT`, `POST`, etc.
* @param array $headers An associative array of all headers.
* @param string $body Any input data sent with the request.
*
* @return string An AWS4-HMAC-SHA256 signature for Amazon S3.
* @return string An AWS4-HMAC-SHA256 signature/authorization header for Amazon S3.
*/
public static function amazon_s34_sign($domain = 's3.amazonaws.com', $location = '/', $method = 'GET', $headers = array(), $body = '')
public static function amazon_s34_authorization($domain = 's3.amazonaws.com', $location = '/', $method = 'GET', $headers = array(), $body = '')
{
$domain = trim(strtolower((string)$domain));
$location = trim((string)$location);
Expand All @@ -685,11 +706,6 @@ public static function amazon_s34_sign($domain = 's3.amazonaws.com', $location =
$s3_canonical_path = !empty($s3_location_parts['path']) ? '/'.ltrim($s3_location_parts['path'], '/') : '/';
$s3_scope = date('Ymd').'/'.$s3c['bucket_region'].'/s3/aws4_request';

$s3_date_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign(date('Ymd'), 'AWS4'.$s3c['secret_key']);
$s3_date_region_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign($s3c['bucket_region'], $s3_date_key);
$s3_date_region_service_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign('s3', $s3_date_region_key);
$s3_signing_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign('aws4_request', $s3_date_region_service_key);

$s3_canonical_query = ''; // Initialize.
wp_parse_str((string)@$s3_location_parts['query'], $query_args);
ksort($query_args, SORT_STRING);
Expand All @@ -713,21 +729,21 @@ public static function amazon_s34_sign($domain = 's3.amazonaws.com', $location =
$s3_canonical_headers = trim($s3_canonical_headers);
unset($_key, $_value); // Housekeeping.

$s3_hashed_payload = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign($body, $s3_signing_key);
$s3_hashed_payload = self::amazon_s34_sign($body);

$s3_canonicial_request = $method."\n".
$s3_canonical_path."\n".
$s3_canonical_query."\n".
$s3_canonical_headers."\n".
implode(';', $s3_canonical_header_keys)."\n".
$s3_hashed_payload;
$s3_canonicial_request_sha256 = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign($s3_canonicial_request, $s3_signing_key);
$s3_canonicial_request_sha256 = self::amazon_s34_sign($s3_canonicial_request);

$s3_string_to_sign = 'AWS4-HMAC-SHA256'."\n".
$s3_iso8601_date."\n".
$s3_scope."\n".
$s3_canonicial_request_sha256;
$s3_signature = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign($s3_string_to_sign, $s3_signing_key);
$s3_signature = self::amazon_s34_sign($s3_string_to_sign);

$s3_authorization_header_signature = 'AWS4-HMAC-SHA256 Credential='.$s3c['access_key'].'/'.$s3_scope.','.
'SignedHeaders='.implode(';', $s3_canonical_header_keys).','.
Expand Down Expand Up @@ -794,8 +810,8 @@ public static function amazon_s3_auto_configure_acls()
$s3_date = gmdate('D, d M Y H:i:s').' GMT';
$s3_location = strtolower($s3c['bucket']) !== $s3c['bucket'] ? '/'.$s3c['bucket'].'/?acl' : '/?acl';
$s3_domain = strtolower($s3c['bucket']) !== $s3c['bucket'] ? 's3.amazonaws.com' : $s3c['bucket'].'.s3.amazonaws.com';
$s3_headers = array('Host' => $s3_domain, 'Date' => $s3_date);
$s3_headers['Authorization'] = self::amazon_s34_sign($s3_domain, $s3_location, 'GET', $s3_headers, '');
$s3_headers = array('Host' => $s3_domain, 'Date' => $s3_date, 'x-amz-content-sha256' => self::amazon_s34_sign(''));
$s3_headers['Authorization'] = self::amazon_s34_authorization($s3_domain, $s3_location, 'GET', $s3_headers, '');
$s3_args = array('method' => 'GET', 'redirection' => 5, 'headers' => $s3_headers);

if(($s3_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$s3_domain.$s3_location, FALSE, array_merge($s3_args, array('timeout' => 20)), 'array')) && $s3_response['code'] === 200)
Expand All @@ -804,8 +820,8 @@ public static function amazon_s3_auto_configure_acls()
{
$s3_owner = array('access_id' => trim($s3_owner_id_tag[1]), 'display_name' => trim($s3_owner_display_name_tag[1]));
$s3_acls_xml = '<AccessControlPolicy><Owner><ID>'.esc_html($s3_owner['access_id']).'</ID><DisplayName>'.esc_html($s3_owner['display_name']).'</DisplayName></Owner><AccessControlList><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>'.esc_html($s3_owner['access_id']).'</ID><DisplayName>'.esc_html($s3_owner['display_name']).'</DisplayName></Grantee><Permission>FULL_CONTROL</Permission></Grant>'.(($cfc['distros_s3_access_id']) ? '<Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>'.esc_html($cfc['distros_s3_access_id']).'</ID><DisplayName>s2Member/CloudFront</DisplayName></Grantee><Permission>READ</Permission></Grant>' : '').'</AccessControlList></AccessControlPolicy>';
$s3_headers = array('Host' => $s3_domain, 'Date' => $s3_date, 'Content-Type' => 'application/xml');
$s3_headers['Authorization'] = self::amazon_s34_sign($s3_domain, $s3_location, 'PUT', $s3_headers, $s3_acls_xml);
$s3_headers = array('Host' => $s3_domain, 'Date' => $s3_date, 'Content-Type' => 'application/xml', 'x-amz-content-sha256' => self::amazon_s34_sign($s3_acls_xml));
$s3_headers['Authorization'] = self::amazon_s34_authorization($s3_domain, $s3_location, 'PUT', $s3_headers, $s3_acls_xml);
$s3_args = array('method' => 'PUT', 'redirection' => 5, 'body' => $s3_acls_xml, 'headers' => $s3_headers);

if(($s3_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$s3_domain.$s3_location, FALSE, array_merge($s3_args, array('timeout' => 20)), 'array')) && $s3_response['code'] === 200)
Expand All @@ -814,16 +830,16 @@ public static function amazon_s3_auto_configure_acls()
$s3_policy_sid = md5(uniqid('s2Member/CloudFront:', TRUE));
$s3_location = strtolower($s3c['bucket']) !== $s3c['bucket'] ? '/'.$s3c['bucket'].'/?policy' : '/?policy';
$s3_policy_json = '{"Version":"2008-10-17","Id":"'.c_ws_plugin__s2member_utils_strings::esc_dq($s3_policy_id).'","Statement":[{"Sid":"'.c_ws_plugin__s2member_utils_strings::esc_dq($s3_policy_sid).'","Effect":"Allow","Principal":{"CanonicalUser":"'.c_ws_plugin__s2member_utils_strings::esc_dq($cfc['distros_s3_access_id']).'"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::'.c_ws_plugin__s2member_utils_strings::esc_dq($s3c['bucket']).'/*"}]}';
$s3_headers = array('Host' => $s3_domain, 'Date' => $s3_date, 'Content-Type' => 'application/json');
$s3_headers['Authorization'] = self::amazon_s34_sign($s3_domain, $s3_location, 'PUT', $s3_headers, $s3_policy_json);
$s3_headers = array('Host' => $s3_domain, 'Date' => $s3_date, 'Content-Type' => 'application/json', 'x-amz-content-sha256' => self::amazon_s34_sign($s3_policy_json));
$s3_headers['Authorization'] = self::amazon_s34_authorization($s3_domain, $s3_location, 'PUT', $s3_headers, $s3_policy_json);
$s3_args = array('method' => 'PUT', 'redirection' => 5, 'body' => $s3_policy_json, 'headers' => $s3_headers);

if(!$cfc['distros_s3_access_id'] || (($s3_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$s3_domain.$s3_location, FALSE, array_merge($s3_args, array('timeout' => 20)), 'array')) && ($s3_response['code'] === 200 || $s3_response['code'] === 204)))
{
$s3_location = strtolower($s3c['bucket']) !== $s3c['bucket'] ? '/'.$s3c['bucket'].'/crossdomain.xml' : '/crossdomain.xml';
$s3_policy_xml = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents(dirname(dirname(__FILE__)).'/templates/cfg-files/s2-cross-xml.php')));
$s3_headers = array('Host' => $s3_domain, 'Date' => $s3_date, 'Content-Type' => 'text/xml', 'X-Amz-Acl' => 'public-read');
$s3_headers['Authorization'] = self::amazon_s34_sign($s3_domain, $s3_location, 'PUT', $s3_headers, $s3_policy_xml);
$s3_headers = array('Host' => $s3_domain, 'Date' => $s3_date, 'Content-Type' => 'text/xml', 'X-Amz-Acl' => 'public-read', 'x-amz-content-sha256' => self::amazon_s34_sign($s3_policy_xml));
$s3_headers['Authorization'] = self::amazon_s34_authorization($s3_domain, $s3_location, 'PUT', $s3_headers, $s3_policy_xml);
$s3_args = array('method' => 'PUT', 'redirection' => 5, 'body' => $s3_policy_xml, 'headers' => $s3_headers);

if(($s3_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$s3_domain.$s3_location, FALSE, array_merge($s3_args, array('timeout' => 20)), 'array')) && $s3_response['code'] === 200)
Expand Down

0 comments on commit 6a57070

Please sign in to comment.