authenticate ()

Generates a cURL handle with all of the required authentication bits set.

Access

public

Returns

Type

Description

resource

A cURL handle ready for executing.

Source

Method defined in authentication/signature_v3query.class.php | Toggle source view (142 lines) | View on GitHub

public function authenticate()
{
    // Determine signing values
    $current_time = time();
    $date = gmdate(CFUtilities::DATE_FORMAT_RFC2616, $current_time);
    $timestamp = gmdate(CFUtilities::DATE_FORMAT_ISO8601, $current_time);
    $nonce = $this->util->generate_guid();
    $curlopts = array();
    $signed_headers = array();

    // Do we have an authentication token?
    if ($this->auth_token)
    {
        $headers['X-Amz-Security-Token'] = $this->auth_token;
        $query['SecurityToken'] = $this->auth_token;
    }

    $query['Action'] = $this->operation;
    $query['Version'] = $this->api_version;

    // Set custom CURLOPT settings
    if (is_array($this->payload) && isset($this->payload['curlopts']))
    {
        $curlopts = $this->payload['curlopts'];
        unset($this->payload['curlopts']);
    }

    // Merge in any options that were passed in
    if (is_array($this->payload))
    {
        $query = array_merge($query, $this->payload);
    }

    $return_curl_handle = isset($query['returnCurlHandle']) ? $query['returnCurlHandle'] : false;
    unset($query['returnCurlHandle']);

    // Do a case-sensitive, natural order sort on the array keys.
    uksort($query, 'strcmp');
    $canonical_query_string = $this->util->to_signable_string($query);

    // Remove the default scheme from the domain.
    $domain = str_replace(array('http://', 'https://'), '', $this->endpoint);

    // Parse our request.
    $parsed_url = parse_url('http://' . $domain);

    // Set the proper host header.
    if (isset($parsed_url['port']) && (integer) $parsed_url['port'] !== 80 && (integer) $parsed_url['port'] !== 443)
    {
        $host_header = strtolower($parsed_url['host']) . ':' . $parsed_url['port'];
    }
    else
    {
        $host_header = strtolower($parsed_url['host']);
    }

    // Set the proper request URI.
    $request_uri = isset($parsed_url['path']) ? $parsed_url['path'] : '/';

    // Generate the querystring from $query
    $this->querystring = $this->util->to_query_string($query);

    // Gather information to pass along to other classes.
    $helpers = array(
        'utilities' => $this->utilities_class,
        'request' => $this->request_class,
        'response' => $this->response_class,
    );

    // Compose the request.
    $request_url = ($this->use_ssl ? 'https://' : 'http://') . $domain;
    $request_url .= !isset($parsed_url['path']) ? '/' : '';

    // Instantiate the request class
    $request = new $this->request_class($request_url, $this->proxy, $helpers, $this->credentials);
    $request->set_method('POST');
    $request->set_body($this->querystring);
    $headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';

    // Pass along registered stream callbacks
    if ($this->registered_streaming_read_callback)
    {
        $request->register_streaming_read_callback($this->registered_streaming_read_callback);
    }

    if ($this->registered_streaming_write_callback)
    {
        $request->register_streaming_write_callback($this->registered_streaming_write_callback);
    }

    // Add authentication headers
    $headers['X-Amz-Nonce'] = $nonce;
    $headers['Date'] = $date;
    $headers['Content-Length'] = strlen($this->querystring);
    $headers['Content-MD5'] = $this->util->hex_to_base64(md5($this->querystring));
    $headers['Host'] = $host_header;

    // Sort headers
    uksort($headers, 'strnatcasecmp');

    // Prepare the string to sign (HTTPS)
    $this->string_to_sign = $date . $nonce;

    // Add headers to request and compute the string to sign
    foreach ($headers as $header_key => $header_value)
    {
        // Strip linebreaks from header values as they're illegal and can allow for security issues
        $header_value = str_replace(array("\r", "\n"), '', $header_value);

        // Add the header if it has a value
        if ($header_value !== '')
        {
            $request->add_header($header_key, $header_value);
        }

        // Generate the string to sign
        if (
            substr(strtolower($header_key), 0, 8) === 'content-' ||
            strtolower($header_key) === 'date' ||
            strtolower($header_key) === 'expires' ||
            strtolower($header_key) === 'host' ||
            substr(strtolower($header_key), 0, 6) === 'x-amz-'
        )
        {
            $signed_headers[] = $header_key;
        }
    }

    // Hash the AWS secret key and generate a signature for the request.
    $signature = base64_encode(hash_hmac('sha256', $this->string_to_sign, $this->secret_key, true));

    $headers['X-Amzn-Authorization'] = 'AWS3-HTTPS'
        . ' AWSAccessKeyId=' . $this->key
        . ',Algorithm=HmacSHA256'
        . ',SignedHeaders=' . implode(';', $signed_headers)
        . ',Signature=' . $signature;

    $request->add_header('X-Amzn-Authorization', $headers['X-Amzn-Authorization']);
    $request->request_headers = $headers;

    return $request;
}

Copyright © 2010–2013 Amazon Web Services, LLC


Feedback