Example #1
0
 /**
  * Constructor, used if you're not calling the class statically
  *
  * @param string $accessKey Access key
  * @param string $secretKey Secret key
  * @param boolean $useSSL Whether or not to use SSL
  * @return void
  */
 public function __construct($accessKey = null, $secretKey = null, $useSSL = true)
 {
     if ($accessKey !== null && $secretKey !== null) {
         self::setAuth($accessKey, $secretKey);
     }
     self::$useSSL = $useSSL;
 }
Example #2
0
 static function get_s3()
 {
     if (!self::$_s3) {
         require_once MODPATH . "aws_s3/lib/s3.php";
         S3::setAuth(module::get_var("aws_s3", "access_key"), module::get_var("aws_s3", "secret_key"));
         S3::$useSSL = module::get_var("aws_s3", "use_ssl", false);
     }
     return self::$_s3;
 }
Example #3
0
 /**
  * List your invalidation batches for invalidateDistribution() in a CloudFront distribution
  *
  * http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/ListInvalidation.html
  * returned array looks like this:
  *	Array
  *	(
  *		[I31TWB0CN9V6XD] => InProgress
  *		[IT3TFE31M0IHZ] => Completed
  *		[I12HK7MPO1UQDA] => Completed
  *		[I1IA7R6JKTC3L2] => Completed
  *	)
  *
  * @param string $distributionId Distribution ID from listDistributions()
  * @return array
  */
 public static function getDistributionInvalidationList($distributionId)
 {
     if (!extension_loaded('openssl')) {
         self::__triggerError(sprintf("S3::getDistributionInvalidationList(): [%s] %s", "CloudFront functionality requires SSL"), __FILE__, __LINE__);
         return false;
     }
     $useSSL = self::$useSSL;
     self::$useSSL = true;
     // CloudFront requires SSL
     $rest = new S3Request('GET', '', '2010-11-01/distribution/' . $distributionId . '/invalidation', 'cloudfront.amazonaws.com');
     $rest = self::__getCloudFrontResponse($rest);
     self::$useSSL = $useSSL;
     if ($rest->error === false && $rest->code !== 200) {
         $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
     }
     if ($rest->error !== false) {
         trigger_error(sprintf("S3::getDistributionInvalidationList('{$distributionId}'): [%s]", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
         return false;
     } elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->InvalidationSummary)) {
         $list = array();
         foreach ($rest->body->InvalidationSummary as $summary) {
             $list[(string) $summary->Id] = (string) $summary->Status;
         }
         return $list;
     }
     return array();
 }
Example #4
0
 /**
  * Get a list of CloudFront distributions
  *
  * @return array
  */
 public static function listDistributions()
 {
     self::$useSSL = true;
     // CloudFront requires SSL
     $rest = new S3Request('GET', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
     $rest = self::__getCloudFrontResponse($rest);
     if ($rest->error === false && $rest->code !== 200) {
         $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
     }
     if ($rest->error !== false) {
         trigger_error(sprintf("S3::listDistributions(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
         return false;
     } elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary)) {
         $list = array();
         if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated)) {
             //$info['marker'] = (string)$rest->body->Marker;
             //$info['maxItems'] = (int)$rest->body->MaxItems;
             //$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
         }
         foreach ($rest->body->DistributionSummary as $summary) {
             $list[(string) $summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
         }
         return $list;
     }
     return array();
 }
Example #5
0
 /**
  * Invalidate objects in a CloudFront distribution
  *
  * Thanks to Martin Lindkvist for S3::invalidateDistribution()
  *
  * @param string $distributionId Distribution ID from listDistributions()
  * @param array $paths Array of object paths to invalidate
  * @return boolean
  */
 public static function invalidateDistribution($distributionId, $paths)
 {
     if (!extension_loaded('openssl')) {
         self::__triggerError(sprintf("S3::invalidateDistribution(): [%s] %s", "CloudFront functionality requires SSL"), __FILE__, __LINE__);
         return false;
     }
     $useSSL = self::$useSSL;
     self::$useSSL = true;
     // CloudFront requires SSL
     $rest = new S3Request('POST', '', '2010-08-01/distribution/' . $distributionId . '/invalidation', 'cloudfront.amazonaws.com');
     $rest->data = self::__getCloudFrontInvalidationBatchXML($paths, (string) microtime(true));
     $rest->size = strlen($rest->data);
     $rest = self::__getCloudFrontResponse($rest);
     self::$useSSL = $useSSL;
     if ($rest->error === false && $rest->code !== 201) {
         $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
     }
     if ($rest->error !== false) {
         trigger_error(sprintf("S3::invalidate('{$distributionId}',{$paths}): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
         return false;
     }
     return true;
 }
Example #6
0
 /**
  * Get the S3 response
  *
  * @return object | false
  */
 public function getResponse()
 {
     $query = '';
     S3::$useSSL = false;
     if (sizeof($this->parameters) > 0) {
         $query = substr($this->uri, -1) !== '?' ? '?' : '&';
         foreach ($this->parameters as $var => $value) {
             if ($value == null || $value == '') {
                 $query .= $var . '&';
             } else {
                 $query .= $var . '=' . rawurlencode($value) . '&';
             }
         }
         $query = substr($query, 0, -1);
         $this->uri .= $query;
         if (array_key_exists('acl', $this->parameters) || array_key_exists('location', $this->parameters) || array_key_exists('torrent', $this->parameters) || array_key_exists('logging', $this->parameters)) {
             $this->resource .= $query;
         }
     }
     $url = (S3::$useSSL && extension_loaded('openssl') ? 'https://' : 'http://') . $this->headers['Host'] . $this->uri;
     //var_dump($this->bucket, $this->uri, $this->resource, $url);
     // Basic setup
     $curl = curl_init();
     curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
     if (S3::$useSSL) {
         curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
         curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);
     }
     curl_setopt($curl, CURLOPT_URL, $url);
     // Headers
     $headers = array();
     $amz = array();
     foreach ($this->amzHeaders as $header => $value) {
         if (strlen($value) > 0) {
             $headers[] = $header . ': ' . $value;
         }
     }
     foreach ($this->headers as $header => $value) {
         if (strlen($value) > 0) {
             $headers[] = $header . ': ' . $value;
         }
     }
     // Collect AMZ headers for signature
     foreach ($this->amzHeaders as $header => $value) {
         if (strlen($value) > 0) {
             $amz[] = strtolower($header) . ':' . $value;
         }
     }
     // AMZ headers must be sorted
     if (sizeof($amz) > 0) {
         sort($amz);
         $amz = "\n" . implode("\n", $amz);
     } else {
         $amz = '';
     }
     // Authorization string (CloudFront stringToSign should only contain a date)
     $headers[] = 'Authorization: ' . S3::__getSignature($this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] : $this->verb . "\n" . $this->headers['Content-MD5'] . "\n" . $this->headers['Content-Type'] . "\n" . $this->headers['Date'] . $amz . "\n" . $this->resource);
     curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
     curl_setopt($curl, CURLOPT_HEADER, false);
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
     curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
     curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
     curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
     // Request types
     switch ($this->verb) {
         case 'GET':
             break;
         case 'PUT':
         case 'POST':
             // POST only used for CloudFront
             if ($this->fp !== false) {
                 curl_setopt($curl, CURLOPT_PUT, true);
                 curl_setopt($curl, CURLOPT_INFILE, $this->fp);
                 if ($this->size >= 0) {
                     curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
                 }
             } elseif ($this->data !== false) {
                 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
                 curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
                 if ($this->size >= 0) {
                     curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size);
                 }
             } else {
                 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
             }
             break;
         case 'HEAD':
             curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
             curl_setopt($curl, CURLOPT_NOBODY, true);
             break;
         case 'DELETE':
             curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
             break;
         default:
             break;
     }
     // Execute, grab errors
     if (curl_exec($curl)) {
         $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
     } else {
         $this->response->error = array('code' => curl_errno($curl), 'message' => curl_error($curl), 'resource' => $this->resource);
     }
     @curl_close($curl);
     // Parse body into XML
     if ($this->response->error === false && isset($this->response->headers['type']) && $this->response->headers['type'] == 'application/xml' && isset($this->response->body)) {
         $this->response->body = simplexml_load_string($this->response->body);
         // Grab S3 errors
         if (!in_array($this->response->code, array(200, 204)) && isset($this->response->body->Code, $this->response->body->Message)) {
             $this->response->error = array('code' => (string) $this->response->body->Code, 'message' => (string) $this->response->body->Message);
             if (isset($this->response->body->Resource)) {
                 $this->response->error['resource'] = (string) $this->response->body->Resource;
             }
             unset($this->response->body);
         }
     }
     // Clean up file resources
     if ($this->fp !== false && is_resource($this->fp)) {
         fclose($this->fp);
     }
     return $this->response;
 }
Example #7
0
 /**
  * Invalidates files in a CloudFront distribution
  *
  * @return array
  */
 public static function getInvalidationList($distributionId)
 {
     self::$useSSL = true;
     // CloudFront requires SSL
     $rest = new S3Request('GET', '', '2010-08-01/distribution/' . $distributionId . '/invalidation', 'cloudfront.amazonaws.com');
     $rest = self::__getCloudFrontResponse($rest);
     if ($rest->error === false && $rest->code !== 200) {
         $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
     }
     if ($rest->error !== false) {
         trigger_error(sprintf("S3::getInvalidationList(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
         return false;
     }
     return $rest;
 }
Example #8
0
 function test_s3($accesskey, $secretkey, $bucket, $directory = '', $ssl)
 {
     if (empty($accesskey) || empty($secretkey) || empty($bucket)) {
         return 'Missing one or more required fields.';
     }
     require_once dirname(__FILE__) . '/lib/s3/s3.php';
     $s3 = new S3($accesskey, $secretkey);
     if ($ssl != '1') {
         S3::$useSSL = false;
     }
     if ($s3->getBucketLocation($bucket) === false) {
         // Easy way to see if bucket already exists.
         $s3->putBucket($bucket, S3::ACL_PUBLIC_READ);
     }
     if (!empty($directory)) {
         $directory = $directory . '/';
     }
     if ($s3->putObject('Upload test for BackupBuddy for Amazon S3', $bucket, $directory . 'backupbuddy.txt', S3::ACL_PRIVATE)) {
         // Success... just delete temp test file later...
     } else {
         return 'Unable to upload. Verify your keys, bucket name, and account permissions.';
     }
     if (!S3::deleteObject($bucket, $directory . '/backupbuddy.txt')) {
         return 'Partial success. Could not delete temp file.';
     }
     return true;
     // Success!
 }
Example #9
0
 /**
  * Creates invalidation bath
  *
  * @static
  * @param integer $distributionId
  * @param array $paths
  * @return array|bool
  */
 public static function createInvalidation($distributionId, $paths)
 {
     self::$useSSL = true;
     // CloudFront requires SSL
     $rest = new S3Request('POST', '', '2010-11-01/distribution/' . $distributionId . '/invalidation', 'cloudfront.amazonaws.com');
     $rest->data = self::__getCloudFrontInvalidationBath($paths);
     $rest->size = strlen($rest->data);
     $rest->setHeader('Content-Type', 'application/xml');
     $rest = self::__getCloudFrontResponse($rest);
     if ($rest->error === false && $rest->code !== 201) {
         $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
     }
     if ($rest->error !== false) {
         trigger_error(sprintf("S3::createInvalidation(%d, '%s'): [%s] %s", $distributionId, implode(', ', $paths), $rest->error['code'], $rest->error['message']), E_USER_WARNING);
         return false;
     } elseif ($rest->body instanceof SimpleXMLElement) {
         return self::__parseCloudFrontInvalidation($rest->body);
     }
     return false;
 }
Example #10
0
 function cron_aws($aws_accesskey, $aws_secretkey, $aws_bucket, $aws_directory, $file, $delete_after_int = 0)
 {
     $details = '';
     $details .= "AWS Access Key: " . $aws_accesskey . "\n";
     if ($this->_debug) {
         $details .= "AWS Secret Key: " . $aws_secretkey . "\n";
     } else {
         $details .= "AWS Secret Key: *hidden*\n";
     }
     $details .= "AWS Bucket: " . $aws_bucket . "\n";
     $details .= "AWS Directory: " . $aws_directory . "\n";
     $details .= "Local File & Path: " . $this->_options['backup_directory'] . '/' . basename($file) . "\n";
     $details .= "Filename: " . basename($file) . "\n";
     $this->log('Starting Amazon S3 cron. Details: ' . $details);
     require_once dirname(__FILE__) . '/lib/s3/s3.php';
     $s3 = new S3($aws_accesskey, $aws_secretkey);
     if ($this->_options['aws_ssl'] != '1') {
         S3::$useSSL = false;
     }
     $this->log('About to put bucket to Amazon S3 cron.');
     $s3->putBucket($aws_bucket, S3::ACL_PUBLIC_READ);
     $this->log('About to put object (the file) to Amazon S3 cron.');
     if ($s3->putObject(S3::inputFile($file), $aws_bucket, $aws_directory . '/' . basename($file), S3::ACL_PRIVATE)) {
         // success
         $this->log('SUCCESS sending to Amazon S3!');
     } else {
         $this->mail_notice('ERROR #9002! Failed sending file to Amazon S3. Details:' . "\n\n" . $details);
         $this->log('FAILURE sending to Amazon S3! Details: ' . $details, 'error');
     }
     if ($delete_after_int == 1) {
         $this->log('Deleting backup file after Amazon S3 cron.');
         unlink($file);
         $this->log('Done deleting backup file after Amazon S3 cron.');
     }
 }
 function test_s3($accesskey, $secretkey, $bucket, $directory = '', $ssl)
 {
     if (empty($accesskey) || empty($secretkey) || empty($bucket)) {
         return __('Missing one or more required fields.', 'it-l10n-backupbuddy');
     }
     $bucket_requirements = __("Your bucket name must meet certain criteria. It must fulfill the following: \n\n Characters may be lowercase letters, numbers, periods (.), and dashes (-). \n Must start with a number or letter. \n Must be between 3 and 63 characters long. \n Must not be formatted as an IP address (e.g., 192.168.5.4). \n Should not contain underscores (_). \n Should be between 3 and 63 characters long. \n Should not end with a dash. \n Cannot contain two, adjacent periods. \n Cannot contain dashes next to periods.", 'it-l10n-backupbuddy');
     if (preg_match("/^[a-z0-9][a-z0-9\\-\\.]*(?<!-)\$/i", $bucket) == 0) {
         // Starts with a-z or 0-9; middle is a-z, 0-9, -, or .; cannot end in a dash.
         return __('Your bucket contains a period next to a dash.', 'it-l10n-backupbuddy') . ' ' . $bucket_requirements;
     }
     if (strlen($bucket) < 3 || strlen($bucket) > 63) {
         // Must be between 3 and 63 characters long
         return __('Your bucket must be between 3 and 63 characters long.', 'it-l10n-backupbuddy') . ' ' . $bucket_requirements;
     }
     if (strstr($bucket, '.-') !== false || strstr($bucket, '-.') !== false || strstr($bucket, '..') !== false) {
         // Bucket names cannot contain dashes next to periods (e.g., "my-.bucket.com" and "my.-bucket" are invalid)
         return __('Your bucket contains a period next to a dash.', 'it-l10n-backupbuddy') . ' ' . $bucket_requirements;
     }
     require_once dirname(__FILE__) . '/lib/s3/s3.php';
     $s3 = new S3($accesskey, $secretkey);
     if ($ssl != '1') {
         S3::$useSSL = false;
     }
     if ($s3->getBucketLocation($bucket) === false) {
         // Easy way to see if bucket already exists.
         $s3->putBucket($bucket, S3::ACL_PRIVATE);
     }
     if (!empty($directory)) {
         $directory = $directory . '/';
     }
     if ($s3->putObject(__('Upload test for BackupBuddy for Amazon S3', 'it-l10n-backupbuddy'), $bucket, $directory . 'backupbuddy.txt', S3::ACL_PRIVATE)) {
         // Success... just delete temp test file later...
     } else {
         return __('Unable to upload. Verify your keys, bucket name, and account permissions.', 'it-l10n-backupbuddy');
     }
     if (!S3::deleteObject($bucket, $directory . 'backupbuddy.txt')) {
         return __('Partial success. Could not delete temp file.', 'it-l10n-backupbuddy');
     }
     return true;
     // Success!
 }
Example #12
0
 static function validate_access_details($access_key, $secret_key, $bucket_name)
 {
     require_once MODPATH . "aws_s3/lib/s3.php";
     S3::setAuth($access_key, $secret_key);
     S3::$useSSL = false;
     $success_test = S3::putObjectString((string) time(), $bucket_name, ".s3_test");
     if ($success_test) {
         S3::deleteObject($bucket_name, ".s3_test");
     }
     return $success_test;
 }