File indexing completed on 2024-06-23 05:55:44

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Service_WindowsAzure
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 /**
0023  * @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
0024  */
0025 // require_once 'Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php';
0026 
0027 /**
0028  * @category   Zend
0029  * @package    Zend_Service_WindowsAzure
0030  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0031  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0032  */ 
0033 class Zend_Service_WindowsAzure_Credentials_SharedKey
0034     extends Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
0035 {
0036     /**
0037    * Sign request URL with credentials
0038    *
0039    * @param string $requestUrl Request URL
0040    * @param string $resourceType Resource type
0041    * @param string $requiredPermission Required permission
0042    * @return string Signed request URL
0043    */
0044   public function signRequestUrl(
0045     $requestUrl = '',
0046     $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
0047     $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
0048   ) {
0049       return $requestUrl;
0050   }
0051   
0052   /**
0053    * Sign request headers with credentials
0054    *
0055    * @param string $httpVerb HTTP verb the request will use
0056    * @param string $path Path for the request
0057    * @param string $queryString Query string for the request
0058    * @param array $headers x-ms headers to add
0059    * @param boolean $forTableStorage Is the request for table storage?
0060    * @param string $resourceType Resource type
0061    * @param string $requiredPermission Required permission
0062    * @param mixed  $rawData Raw post data
0063    * @return array Array of headers
0064    */
0065   public function signRequestHeaders(
0066     $httpVerb = Zend_Http_Client::GET,
0067     $path = '/',
0068     $queryString = '',
0069     $headers = null,
0070     $forTableStorage = false,
0071     $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
0072     $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ,
0073     $rawData = null
0074   ) {
0075     // http://github.com/sriramk/winazurestorage/blob/214010a2f8931bac9c96dfeb337d56fe084ca63b/winazurestorage.py
0076 
0077     // Table storage?
0078     if ($forTableStorage) {
0079       // require_once 'Zend/Service/WindowsAzure/Credentials/Exception.php';
0080       throw new Zend_Service_WindowsAzure_Credentials_Exception('The Windows Azure SDK for PHP does not support SharedKey authentication on table storage. Use SharedKeyLite authentication instead.');
0081     }
0082     
0083     // Determine path
0084     if ($this->_usePathStyleUri) {
0085       $path = substr($path, strpos($path, '/'));
0086     }
0087 
0088     // Determine query
0089     $queryString = $this->_prepareQueryStringForSigning($queryString);
0090   
0091     // Canonicalized headers
0092     $canonicalizedHeaders = array();
0093     
0094     // Request date
0095     $requestDate = '';
0096     if (isset($headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'])) {
0097         $requestDate = $headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'];
0098     } else {
0099         $requestDate = gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123
0100         $canonicalizedHeaders[] = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date:' . $requestDate;
0101     }
0102     
0103     // Build canonicalized headers
0104     if (!is_null($headers)) {
0105       foreach ($headers as $header => $value) {
0106         if (is_bool($value)) {
0107           $value = $value === true ? 'True' : 'False';
0108         }
0109 
0110         $headers[$header] = $value;
0111         if (substr($header, 0, strlen(Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER)) == Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER) {
0112             $canonicalizedHeaders[] = strtolower($header) . ':' . $value;
0113         }
0114       }
0115     }
0116     sort($canonicalizedHeaders);
0117 
0118     // Build canonicalized resource string
0119     $canonicalizedResource  = '/' . $this->_accountName;
0120     if ($this->_usePathStyleUri) {
0121       $canonicalizedResource .= '/' . $this->_accountName;
0122     }
0123     $canonicalizedResource .= $path;
0124     if ($queryString !== '') {
0125         $queryStringItems = $this->_makeArrayOfQueryString($queryString);
0126         foreach ($queryStringItems as $key => $value) {
0127           $canonicalizedResource .= "\n" . strtolower($key) . ':' . urldecode($value);
0128         }
0129     }
0130     
0131     // Content-Length header
0132     $contentLength = '';
0133     if (strtoupper($httpVerb) != Zend_Http_Client::GET
0134        && strtoupper($httpVerb) != Zend_Http_Client::DELETE
0135        && strtoupper($httpVerb) != Zend_Http_Client::HEAD) {
0136       $contentLength = 0;
0137       
0138       if (!is_null($rawData)) {
0139         $contentLength = strlen($rawData);
0140       }
0141     }
0142 
0143     // Create string to sign   
0144     $stringToSign   = array();
0145     $stringToSign[] = strtoupper($httpVerb);                  // VERB
0146       $stringToSign[] = $this->_issetOr($headers, 'Content-Encoding', '');    // Content-Encoding
0147       $stringToSign[] = $this->_issetOr($headers, 'Content-Language', '');    // Content-Language
0148       $stringToSign[] = $contentLength;                       // Content-Length
0149       $stringToSign[] = $this->_issetOr($headers, 'Content-MD5', '');       // Content-MD5
0150       $stringToSign[] = $this->_issetOr($headers, 'Content-Type', '');      // Content-Type
0151       $stringToSign[] = "";                           // Date
0152       $stringToSign[] = $this->_issetOr($headers, 'If-Modified-Since', '');   // If-Modified-Since
0153       $stringToSign[] = $this->_issetOr($headers, 'If-Match', '');        // If-Match
0154       $stringToSign[] = $this->_issetOr($headers, 'If-None-Match', '');     // If-None-Match
0155       $stringToSign[] = $this->_issetOr($headers, 'If-Unmodified-Since', '');   // If-Unmodified-Since
0156       $stringToSign[] = $this->_issetOr($headers, 'Range', '');         // Range
0157       
0158       if (!$forTableStorage && count($canonicalizedHeaders) > 0) {
0159         $stringToSign[] = implode("\n", $canonicalizedHeaders); // Canonicalized headers
0160       }
0161         
0162       $stringToSign[] = $canonicalizedResource;         // Canonicalized resource
0163       $stringToSign   = implode("\n", $stringToSign);
0164       $signString     = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true));
0165 
0166       // Sign request
0167       $headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'] = $requestDate;
0168       $headers['Authorization'] = 'SharedKey ' . $this->_accountName . ':' . $signString;
0169       
0170       // Return headers
0171       return $headers;
0172   }
0173 }