InfiniteWP Client - Version 1.9.4.11

Version Description

  • Jun 16th 2021 =
  • Improvement: Amazon s3 library updated.
  • Improvement: Wordfence data not correctly showing in Client report due to the Wordfence recent release.
  • Improvement: wp_new_user_notification function deprecated arg removed.
  • Improvement: New constant (IWP_PHP_DB_ROWS) introduced on the WordPress site to take more row in the PHP database dump backup method.
  • Improvement: If MySQL Dump fails, the admin panel will automatically retry MySQL Dump with a different 'max_allowed_packet' value.
  • Improvement: Added a few locations for the MySQL dump command.
  • Improvement: Multicall method backup speed enhanced.
  • Improvement: Enabled support for "Exclude file size" in Phoenix method backup.
  • Fix: Multiple Deprecated notices and Warnings when backing up a site (installed on a server with PHP8) using all backup methods.
  • Fix: Fatal errors due to disabled PHP functions on certain hosting providers.
  • Fix: WP Option cache causing issue in Phoenix backup on certain servers.
  • Fix: MySQL Dump using 'passthru()' function not working both single and multicall method.
  • Fix: MySQL Dump not working if 'max_allowed_packet' size has low value.
  • Fix: open_basedir warning fixed.
Download this release

Release Info

Developer infinitewp
Plugin Icon 128x128 InfiniteWP Client
Version 1.9.4.11
Comparing to
See all releases

Code changes from version 1.9.4.8.2 to 1.9.4.11

Files changed (161) hide show
  1. activities_log.class.php +5 -4
  2. addons/file_editor/file_editor.class.php +1 -1
  3. addons/malware_scanner_sucuri/malware_scanner_sucuri.class.php +1 -1
  4. addons/manage_users/user.class.php +1 -1
  5. addons/post_links/post.class.php +42 -27
  6. addons/wordfence/wordfence.class.php +9 -9
  7. backup.class.multicall.php +141 -45
  8. backup.class.singlecall.php +84 -26
  9. backup/backup-repo-test.php +1 -1
  10. backup/backup.core.class.php +44 -16
  11. backup/backup.php +5 -5
  12. backup/class.semaphore.php +3 -3
  13. backup/functions.php +1 -1
  14. backup/s3.php +1 -1
  15. core.class.php +54 -1
  16. debug-chart/src/fusioncharts.php +1 -1
  17. init.php +78 -25
  18. installer.class.php +3 -3
  19. iwp-file-iterator.php +6 -1
  20. lib/Dropbox2/OAuth/Storage/WordPress.php +1 -1
  21. lib/Google/Http/REST.php +1 -1
  22. lib/Google/Utils.php +1 -1
  23. lib/Google2/Http/REST.php +1 -1
  24. lib/Google2/Utils.php +1 -1
  25. lib/S3.php +1 -1
  26. lib/amazon/autoload.php +2 -2
  27. lib/amazon/aws/aws-sdk-php/LICENSE.md +141 -0
  28. lib/amazon/aws/aws-sdk-php/NOTICE.md +112 -0
  29. lib/amazon/aws/aws-sdk-php/composer.json +42 -0
  30. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Aws.php +2 -1
  31. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Client/AbstractClient.php +1 -1
  32. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Client/ClientBuilder.php +5 -4
  33. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Client/ExpiredCredentialsChecker.php +1 -1
  34. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Client/UploadBodyListener.php +1 -1
  35. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Command/AwsQueryVisitor.php +3 -0
  36. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractRefreshableCredentials.php +19 -0
  37. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Credentials/CacheableCredentials.php +2 -1
  38. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Credentials/Credentials.php +33 -18
  39. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Credentials/RefreshableInstanceProfileCredentials.php +35 -3
  40. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Enum/ClientOptions.php +5 -0
  41. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/DefaultXmlExceptionParser.php +16 -7
  42. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Exception/ServiceResponseException.php +38 -0
  43. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Facade/Facade.php +2 -0
  44. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Facade/FacadeInterface.php +2 -0
  45. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Resources/aws-config.php +48 -0
  46. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureListener.php +7 -2
  47. lib/amazon/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV4.php +11 -4
  48. lib/amazon/aws/aws-sdk-php/src/Aws/S3/AcpListener.php +1 -1
  49. lib/amazon/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchTagSetException.php +22 -0
  50. lib/amazon/aws/aws-sdk-php/src/Aws/S3/IncompleteMultipartUploadChecker.php +56 -0
  51. lib/amazon/aws/aws-sdk-php/src/Aws/S3/Model/Acp.php +2 -2
  52. lib/amazon/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/AbstractTransfer.php +2 -2
  53. lib/amazon/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/ParallelTransfer.php +3 -3
  54. lib/amazon/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/SerialTransfer.php +1 -1
  55. lib/amazon/aws/aws-sdk-php/src/Aws/S3/Resources/s3-2006-03-01.php +749 -2
  56. lib/amazon/aws/aws-sdk-php/src/Aws/S3/ResumableDownload.php +2 -2
  57. lib/amazon/aws/aws-sdk-php/src/Aws/S3/S3Client.php +21 -8
  58. lib/amazon/aws/aws-sdk-php/src/Aws/S3/StreamWrapper.php +19 -4
  59. lib/amazon/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSyncBuilder.php +0 -1
  60. lib/amazon/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSyncBuilder.php +1 -1
  61. lib/amazon/composer/ClassLoader.php +54 -22
  62. lib/amazon/composer/InstalledVersions.php +400 -0
  63. lib/amazon/composer/LICENSE +21 -0
  64. lib/amazon/composer/autoload_classmap.php +1 -0
  65. lib/amazon/composer/autoload_files.php +12 -0
  66. lib/amazon/composer/autoload_namespaces.php +0 -1
  67. lib/amazon/composer/autoload_psr4.php +1 -0
  68. lib/amazon/composer/autoload_real.php +29 -22
  69. lib/amazon/composer/autoload_static.php +58 -0
  70. lib/amazon/composer/include_paths.php +10 -0
  71. lib/amazon/composer/installed.json +246 -0
  72. lib/amazon/composer/installed.php +205 -0
  73. lib/amazon/composer/platform_check.php +26 -0
  74. lib/amazon/guzzle/guzzle/CHANGELOG.md +751 -0
  75. lib/amazon/guzzle/guzzle/LICENSE +19 -0
  76. lib/amazon/guzzle/guzzle/README.md +57 -0
  77. lib/amazon/guzzle/guzzle/UPGRADING.md +537 -0
  78. lib/amazon/guzzle/guzzle/build.xml +45 -0
  79. lib/amazon/guzzle/guzzle/composer.json +82 -0
  80. lib/amazon/guzzle/guzzle/phar-stub.php +16 -0
  81. lib/amazon/guzzle/guzzle/phpunit.xml.dist +48 -0
  82. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/AbstractBatchDecorator.php +66 -0
  83. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/Batch.php +92 -0
  84. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchBuilder.php +199 -0
  85. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchClosureDivisor.php +39 -0
  86. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchClosureTransfer.php +40 -0
  87. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchCommandTransfer.php +75 -0
  88. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchDivisorInterface.php +18 -0
  89. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchInterface.php +32 -0
  90. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchRequestTransfer.php +65 -0
  91. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchSizeDivisor.php +47 -0
  92. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchTransferInterface.php +16 -0
  93. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/Exception/BatchTransferException.php +90 -0
  94. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/ExceptionBufferingBatch.php +50 -0
  95. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/FlushingBatch.php +60 -0
  96. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/HistoryBatch.php +39 -0
  97. lib/amazon/guzzle/guzzle/src/Guzzle/Batch/NotifyingBatch.php +38 -0
  98. lib/amazon/guzzle/guzzle/src/Guzzle/Http/Curl/CurlHandle.php +6 -5
  99. lib/amazon/guzzle/guzzle/src/Guzzle/Http/Curl/CurlMulti.php +1 -1
  100. lib/amazon/guzzle/guzzle/src/Guzzle/Http/Curl/RequestMediator.php +2 -0
  101. lib/amazon/guzzle/guzzle/src/Guzzle/Http/EntityBody.php-tmp +0 -188
  102. lib/amazon/guzzle/guzzle/src/Guzzle/Http/Message/Response.php +2 -2
  103. lib/amazon/guzzle/guzzle/src/Guzzle/Log/AbstractLogAdapter.php +16 -0
  104. lib/amazon/guzzle/guzzle/src/Guzzle/Log/ArrayLogAdapter.php +34 -0
  105. lib/amazon/guzzle/guzzle/src/Guzzle/Log/ClosureLogAdapter.php +23 -0
  106. lib/amazon/guzzle/guzzle/src/Guzzle/Log/LogAdapterInterface.php +18 -0
  107. lib/amazon/guzzle/guzzle/src/Guzzle/Log/MessageFormatter.php +179 -0
  108. lib/amazon/guzzle/guzzle/src/Guzzle/Log/MonologLogAdapter.php +34 -0
  109. lib/amazon/guzzle/guzzle/src/Guzzle/Log/PsrLogAdapter.php +36 -0
  110. lib/amazon/guzzle/guzzle/src/Guzzle/Log/Zf1LogAdapter.php +24 -0
  111. lib/amazon/guzzle/guzzle/src/Guzzle/Log/Zf2LogAdapter.php +21 -0
  112. lib/amazon/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php +1 -1
  113. lib/amazon/s3IWPBackup.php +7 -3
  114. lib/amazon/symfony/event-dispatcher/.gitignore +3 -0
  115. lib/amazon/symfony/event-dispatcher/CHANGELOG.md +23 -0
  116. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php → ContainerAwareEventDispatcher.php} +18 -37
  117. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/Debug → Debug}/TraceableEventDispatcher.php +58 -18
  118. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/Debug → Debug}/TraceableEventDispatcherInterface.php +0 -0
  119. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/Debug → Debug}/WrappedListener.php +2 -2
  120. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/DependencyInjection → DependencyInjection}/RegisterListenersPass.php +7 -17
  121. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/Event.php → Event.php} +11 -21
  122. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/EventDispatcher.php → EventDispatcher.php} +48 -35
  123. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/EventDispatcherInterface.php → EventDispatcherInterface.php} +2 -17
  124. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/EventSubscriberInterface.php → EventSubscriberInterface.php} +1 -5
  125. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/GenericEvent.php → GenericEvent.php} +20 -31
  126. lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php → ImmutableEventDispatcher.php} +8 -10
  127. lib/amazon/symfony/event-dispatcher/LICENSE +19 -0
  128. lib/amazon/symfony/event-dispatcher/README.md +15 -0
  129. lib/amazon/symfony/event-dispatcher/composer.json +44 -0
  130. lib/amazon/symfony/event-dispatcher/phpunit.xml.dist +31 -0
  131. lib/dropbox.php +1 -1
  132. lib/ftp.class.php +1 -1
  133. lib/phpseclib/phpseclib/BACKERS.md +8 -0
  134. lib/phpseclib/phpseclib/LICENSE +2 -3
  135. lib/phpseclib/phpseclib/README.md +16 -4
  136. lib/phpseclib/phpseclib/appveyor.yml +27 -0
  137. lib/phpseclib/phpseclib/composer.json +1 -1
  138. lib/phpseclib/phpseclib/composer.lock +0 -1669
  139. lib/phpseclib/phpseclib/phpseclib/Crypt/Base.php +61 -12
  140. lib/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php +2 -32
  141. lib/phpseclib/phpseclib/phpseclib/Crypt/Hash.php +100 -32
  142. lib/phpseclib/phpseclib/phpseclib/Crypt/RC2.php +1 -1
  143. lib/phpseclib/phpseclib/phpseclib/Crypt/RC4.php +1 -1
  144. lib/phpseclib/phpseclib/phpseclib/Crypt/RSA.php +157 -14
  145. lib/phpseclib/phpseclib/phpseclib/Crypt/Random.php +8 -1
  146. lib/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php +38 -30
  147. lib/phpseclib/phpseclib/phpseclib/File/ANSI.php +5 -2
  148. lib/phpseclib/phpseclib/phpseclib/File/ASN1.php +209 -51
  149. lib/phpseclib/phpseclib/phpseclib/File/X509.php +341 -46
  150. lib/phpseclib/phpseclib/phpseclib/Math/BigInteger.php +43 -14
  151. lib/phpseclib/phpseclib/phpseclib/Net/SCP.php +5 -0
  152. lib/phpseclib/phpseclib/phpseclib/Net/SFTP.php +160 -40
  153. lib/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php +1 -1
  154. lib/phpseclib/phpseclib/phpseclib/Net/SSH1.php +3 -0
  155. lib/phpseclib/phpseclib/phpseclib/Net/SSH2.php +1101 -502
  156. lib/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php +153 -26
  157. lib/phpseclib/phpseclib/phpseclib/bootstrap.php +1 -0
  158. lib/sftp.php +1 -1
  159. pclzip.class.php +13 -11
  160. readme.txt +17 -1
  161. stats.class.php +7 -3
activities_log.class.php CHANGED
@@ -548,7 +548,7 @@ class IWP_MMB_Activities_log {
548
  return $this->iwp_mmb_post_update_translations_complete_actions($update_actions);
549
  }
550
 
551
- function iwp_mmb_upgrader_post_install($flag, $hook_extra, $result) {
552
  global $wp_version;
553
 
554
  if(
@@ -557,7 +557,8 @@ class IWP_MMB_Activities_log {
557
  && is_object($hook_extra['language_update'])
558
  ) {
559
  remove_filter('update_translations_complete_actions', array(&$this,'iwp_mmb_update_translations_complete_actions'));
560
- return $this->iwp_mmb_post_update_translations_complete_actions(array());
 
561
  }
562
 
563
  if(
@@ -569,7 +570,7 @@ class IWP_MMB_Activities_log {
569
  $this->iwp_mmb_collect_plugin_details($hook_extra['plugin']);
570
  }
571
 
572
- return $result;
573
  }
574
 
575
  function iwp_mmb_update_is_save_activity_log($is_save_activity_log) {
@@ -687,7 +688,7 @@ class IWP_MMB_Activities_log {
687
  unset($return['detailed'][$key]);
688
  } else if(!array_key_exists('details',$mainActionArray)) {
689
  foreach($mainActionArray as $key_inner => &$subActionsArray) {
690
- if(!$subActionsArray[$count_key] && $key_inner!=$count_key) {
691
  unset($mainActionArray[$key_inner]);
692
  }
693
  }
548
  return $this->iwp_mmb_post_update_translations_complete_actions($update_actions);
549
  }
550
 
551
+ function iwp_mmb_upgrader_post_install($response, $hook_extra, $result) {
552
  global $wp_version;
553
 
554
  if(
557
  && is_object($hook_extra['language_update'])
558
  ) {
559
  remove_filter('update_translations_complete_actions', array(&$this,'iwp_mmb_update_translations_complete_actions'));
560
+ $this->iwp_mmb_post_update_translations_complete_actions(array());
561
+ return $response;
562
  }
563
 
564
  if(
570
  $this->iwp_mmb_collect_plugin_details($hook_extra['plugin']);
571
  }
572
 
573
+ return $response;
574
  }
575
 
576
  function iwp_mmb_update_is_save_activity_log($is_save_activity_log) {
688
  unset($return['detailed'][$key]);
689
  } else if(!array_key_exists('details',$mainActionArray)) {
690
  foreach($mainActionArray as $key_inner => &$subActionsArray) {
691
+ if(empty($subActionsArray[$count_key]) && $key_inner!=$count_key) {
692
  unset($mainActionArray[$key_inner]);
693
  }
694
  }
addons/file_editor/file_editor.class.php CHANGED
@@ -266,7 +266,7 @@ function iwp_mmb_direct_to_any_copy($source, $destination, $overwrite = false, $
266
  }
267
  }
268
 
269
- $fileHandler = fopen($new_temp_subfolders.$file['name'],w);
270
  fwrite($fileHandler,$fileContent);
271
  fclose($fileHandler);
272
 
266
  }
267
  }
268
 
269
+ $fileHandler = fopen($new_temp_subfolders.$file['name'],'w');
270
  fwrite($fileHandler,$fileContent);
271
  fclose($fileHandler);
272
 
addons/malware_scanner_sucuri/malware_scanner_sucuri.class.php CHANGED
@@ -24,7 +24,7 @@ public function getSucuriInstalled(){
24
  return $this->is_sucuri_installed;
25
  }
26
 
27
- public function getScannedCacheResult($assoc = 0){
28
  if (!$this->getSucuriInstalled() || !class_exists('SucuriScanCache')) {
29
  return false;
30
  }
24
  return $this->is_sucuri_installed;
25
  }
26
 
27
+ public function getScannedCacheResult($assoc = 0, $onlyInfo = false){
28
  if (!$this->getSucuriInstalled() || !class_exists('SucuriScanCache')) {
29
  return false;
30
  }
addons/manage_users/user.class.php CHANGED
@@ -127,7 +127,7 @@ class IWP_MMB_User extends IWP_MMB_Core
127
 
128
  if($args['email_notify']){
129
  //require_once ABSPATH . WPINC . '/pluggable.php';
130
- wp_new_user_notification($user_id, $args['user_pass']);
131
  }
132
  return $user_id;
133
  }else{
127
 
128
  if($args['email_notify']){
129
  //require_once ABSPATH . WPINC . '/pluggable.php';
130
+ wp_new_user_notification($user_id);
131
  }
132
  return $user_id;
133
  }else{
addons/post_links/post.class.php CHANGED
@@ -37,6 +37,16 @@ class IWP_MMB_Post extends IWP_MMB_Core
37
  include_once ABSPATH . 'wp-admin/includes/file.php';
38
 
39
  $post_struct = $args['post_data'];
 
 
 
 
 
 
 
 
 
 
40
 
41
 
42
 
@@ -51,47 +61,52 @@ class IWP_MMB_Post extends IWP_MMB_Core
51
  $upload = wp_upload_dir();
52
 
53
  // create dynamic url RegExp
54
- $iwp_base_url = parse_url($post_upload_dir['url']);
55
- $iwp_regexp_url = $iwp_base_url['host'] . $iwp_base_url['path'];
56
- $rep = array(
57
- '/',
58
- '+',
59
- '.',
60
- ':',
61
- '?'
62
- );
63
- $with = array(
64
- '\/',
65
- '\+',
66
- '\.',
67
- '\:',
68
- '\?'
69
- );
70
- $iwp_regexp_url = str_replace($rep, $with, $iwp_regexp_url);
71
 
72
- // rename all src ../wp-content/ with hostname/wp-content/
73
-
74
- $iwp_mmb_dot_url = '..' . $iwp_mmb_base_url['path'];
75
- $iwp_mmb_dot_url = str_replace($rep, $with, $iwp_mmb_dot_url);
76
- $dot_match_count = preg_match_all('/(<a[^>]+href=\"([^"]+)\"[^>]*>)?(<\s*img.[^\/>]*src="([^"]*' . $iwp_mmb_dot_url . '[^\s]+\.(jpg|jpeg|png|gif|bmp))"[^>]*>)/ixu', $post_data['post_content'], $dot_get_urls, PREG_SET_ORDER);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
 
79
  if ($dot_match_count > 0) {
80
  foreach ($dot_get_urls as $dot_url) {
81
  $match_dot = '/' . str_replace($rep, $with, $dot_url[4]) . '/';
82
- $replace_dot = 'http://' . $iwp_mmb_base_url['host'] . substr($dot_url[4], 2, strlen($dot_url[4]));
83
  $post_data['post_content'] = preg_replace($match_dot, $replace_dot, $post_data['post_content']);
84
 
85
  if ($dot_url[1] != '') {
86
  $match_dot_a = '/' . str_replace($rep, $with, $dot_url[2]) . '/';
87
- $replace_dot_a = 'http://' . $iwp_mmb_base_url['host'] . substr($dot_url[2], 2, strlen($dot_url[2]));
88
  $post_data['post_content'] = preg_replace($match_dot_a, $replace_dot_a, $post_data['post_content']);
89
  }
90
  }
91
  }
92
 
93
  //to find all the images
94
- $match_count = preg_match_all('/(<a[^>]+href=\"([^"]+)\"[^>]*>)?(<\s*img.[^\/>]*src="([^"]+' . $iwp_mmb_regexp_url . '[^\s]+\.(jpg|jpeg|png|gif|bmp))"[^>]*>)/ixu', $post_data['post_content'], $get_urls, PREG_SET_ORDER);
95
 
96
  ///////////
97
  //$html = $params['postContent'];
@@ -245,7 +260,7 @@ class IWP_MMB_Post extends IWP_MMB_Core
245
  $post_data['post_content'] = $post_content;
246
 
247
  }
248
- if (count($post_atta_img)) {
249
  foreach ($post_atta_img as $img) {
250
  $file_name = basename($img['src']);
251
 
@@ -351,7 +366,7 @@ class IWP_MMB_Post extends IWP_MMB_Core
351
 
352
  }
353
 
354
- if (count($attachments)) {
355
  foreach ($attachments as $atta_id => $featured_id) {
356
  $result = wp_update_post(array(
357
  'ID' => $atta_id,
37
  include_once ABSPATH . 'wp-admin/includes/file.php';
38
 
39
  $post_struct = $args['post_data'];
40
+ if(function_exists('iwp_recursive_parse_args')){
41
+ $defaults = array(
42
+ 'post_extras' => array(
43
+ 'post_upload_dir' => array(),
44
+ 'post_checksum' =>'',
45
+ 'post_atta_images' =>''
46
+ ),
47
+ );
48
+ $post_struct = iwp_recursive_parse_args($post_struct,$defaults);
49
+ }
50
 
51
 
52
 
61
  $upload = wp_upload_dir();
62
 
63
  // create dynamic url RegExp
64
+ $dot_match_count = 0;
65
+ $iwp_regexp_url = "";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ if(!empty($post_upload_dir)){
68
+ $iwp_base_url = parse_url($post_upload_dir['url']);
69
+ $iwp_regexp_url = $iwp_base_url['host'] . $iwp_base_url['path'];
70
+ $rep = array(
71
+ '/',
72
+ '+',
73
+ '.',
74
+ ':',
75
+ '?'
76
+ );
77
+ $with = array(
78
+ '\/',
79
+ '\+',
80
+ '\.',
81
+ '\:',
82
+ '\?'
83
+ );
84
+ $iwp_regexp_url = str_replace($rep, $with, $iwp_regexp_url);
85
+
86
+ // rename all src ../wp-content/ with hostname/wp-content/
87
+
88
+ $iwp_mmb_dot_url = '..' . $iwp_base_url['path'];
89
+ $iwp_mmb_dot_url = str_replace($rep, $with, $iwp_mmb_dot_url);
90
+ $dot_match_count = preg_match_all('/(<a[^>]+href=\"([^"]+)\"[^>]*>)?(<\s*img.[^\/>]*src="([^"]*' . $iwp_mmb_dot_url . '[^\s]+\.(jpg|jpeg|png|gif|bmp))"[^>]*>)/ixu', $post_data['post_content'], $dot_get_urls, PREG_SET_ORDER);
91
+ }
92
 
93
 
94
  if ($dot_match_count > 0) {
95
  foreach ($dot_get_urls as $dot_url) {
96
  $match_dot = '/' . str_replace($rep, $with, $dot_url[4]) . '/';
97
+ $replace_dot = 'http://' . $iwp_base_url['host'] . substr($dot_url[4], 2, strlen($dot_url[4]));
98
  $post_data['post_content'] = preg_replace($match_dot, $replace_dot, $post_data['post_content']);
99
 
100
  if ($dot_url[1] != '') {
101
  $match_dot_a = '/' . str_replace($rep, $with, $dot_url[2]) . '/';
102
+ $replace_dot_a = 'http://' . $iwp_base_url['host'] . substr($dot_url[2], 2, strlen($dot_url[2]));
103
  $post_data['post_content'] = preg_replace($match_dot_a, $replace_dot_a, $post_data['post_content']);
104
  }
105
  }
106
  }
107
 
108
  //to find all the images
109
+ $match_count = preg_match_all('/(<a[^>]+href=\"([^"]+)\"[^>]*>)?(<\s*img.[^\/>]*src="([^"]+' . $iwp_regexp_url . '[^\s]+\.(jpg|jpeg|png|gif|bmp))"[^>]*>)/ixu', $post_data['post_content'], $get_urls, PREG_SET_ORDER);
110
 
111
  ///////////
112
  //$html = $params['postContent'];
260
  $post_data['post_content'] = $post_content;
261
 
262
  }
263
+ if (!empty($post_atta_img) && is_array($post_atta_img)) {
264
  foreach ($post_atta_img as $img) {
265
  $file_name = basename($img['src']);
266
 
366
 
367
  }
368
 
369
+ if (!empty($attachments) && is_array($attachments)) {
370
  foreach ($attachments as $atta_id => $featured_id) {
371
  $result = wp_update_post(array(
372
  'ID' => $atta_id,
addons/wordfence/wordfence.class.php CHANGED
@@ -56,49 +56,49 @@ class IWP_WORDFENCE extends IWP_MMB_Core
56
  switch ($type) {
57
  case 'humans':
58
  $query = "SELECT count('id')
59
- FROM ".$wpdb->base_prefix."wfHits
60
  WHERE jsRun = 1 AND ctime >= '$from' AND ctime <= '$to'";
61
  break;
62
 
63
  case 'registered_users':
64
  $query = "SELECT count('id')
65
- FROM ".$wpdb->base_prefix."wfHits
66
  WHERE userID > 0 AND ctime >= '$from' AND ctime <= '$to'";
67
  break;
68
  case 'crawlers':
69
  $query = "SELECT count('id')
70
- FROM ".$wpdb->base_prefix."wfHits
71
  WHERE jsRun = 0 AND ctime >= '$from' AND ctime <= '$to'";
72
  break;
73
 
74
  case 'google_crawlers':
75
  $query = "SELECT count('id')
76
- FROM ".$wpdb->base_prefix."wfHits
77
  WHERE isGoogle = 1 AND ctime >= '$from' AND ctime <= '$to'";
78
  break;
79
  case 'four_oh_four':
80
  $query = "SELECT count('id')
81
- FROM ".$wpdb->base_prefix."wfHits
82
  WHERE statusCode = '404' AND ctime >= '$from' AND ctime <= '$to'";
83
  break;
84
  case 'logins_logouts':
85
  $query = "SELECT count('id')
86
- FROM ".$wpdb->base_prefix."wfLogins
87
  WHERE ctime >= '$from' AND ctime <= '$to'";
88
  break;
89
  case 'locked_out':
90
  $query = "SELECT count('IP')
91
- FROM ".$wpdb->base_prefix."wfLockedOut
92
  WHERE blockedTime >= '$from' AND `blockedTime` <= '$to'";
93
  break;
94
  case 'blocked':
95
  $query = "SELECT count('id')
96
- FROM ".$wpdb->base_prefix."wfHits
97
  WHERE action = 'blocked:wordfence' AND ctime >= '$from' AND ctime <= '$to'";
98
  break;
99
  case 'blocked_firewall':
100
  $query = "SELECT count('id')
101
- FROM ".$wpdb->base_prefix."wfHits
102
  WHERE action = 'blocked:waf' AND ctime >= '$from' AND ctime <= '$to'";
103
  break;
104
 
56
  switch ($type) {
57
  case 'humans':
58
  $query = "SELECT count('id')
59
+ FROM ".$wpdb->base_prefix."wfhits
60
  WHERE jsRun = 1 AND ctime >= '$from' AND ctime <= '$to'";
61
  break;
62
 
63
  case 'registered_users':
64
  $query = "SELECT count('id')
65
+ FROM ".$wpdb->base_prefix."wfhits
66
  WHERE userID > 0 AND ctime >= '$from' AND ctime <= '$to'";
67
  break;
68
  case 'crawlers':
69
  $query = "SELECT count('id')
70
+ FROM ".$wpdb->base_prefix."wfhits
71
  WHERE jsRun = 0 AND ctime >= '$from' AND ctime <= '$to'";
72
  break;
73
 
74
  case 'google_crawlers':
75
  $query = "SELECT count('id')
76
+ FROM ".$wpdb->base_prefix."wfhits
77
  WHERE isGoogle = 1 AND ctime >= '$from' AND ctime <= '$to'";
78
  break;
79
  case 'four_oh_four':
80
  $query = "SELECT count('id')
81
+ FROM ".$wpdb->base_prefix."wfhits
82
  WHERE statusCode = '404' AND ctime >= '$from' AND ctime <= '$to'";
83
  break;
84
  case 'logins_logouts':
85
  $query = "SELECT count('id')
86
+ FROM ".$wpdb->base_prefix."wflogins
87
  WHERE ctime >= '$from' AND ctime <= '$to'";
88
  break;
89
  case 'locked_out':
90
  $query = "SELECT count('IP')
91
+ FROM ".$wpdb->base_prefix."wfblocks7
92
  WHERE blockedTime >= '$from' AND `blockedTime` <= '$to'";
93
  break;
94
  case 'blocked':
95
  $query = "SELECT count('id')
96
+ FROM ".$wpdb->base_prefix."wfhits
97
  WHERE action = 'blocked:wordfence' AND ctime >= '$from' AND ctime <= '$to'";
98
  break;
99
  case 'blocked_firewall':
100
  $query = "SELECT count('id')
101
+ FROM ".$wpdb->base_prefix."wfhits
102
  WHERE action = 'blocked:waf' AND ctime >= '$from' AND ctime <= '$to'";
103
  break;
104
 
backup.class.multicall.php CHANGED
@@ -146,6 +146,11 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
146
  {
147
  return $this->statusLog($datas['backupParentHID'], array('stage' => 'trigger_check', 'status' => 'error', 'statusMsg' => 'Error while fetching table data', 'statusCode' => 'error_while_fetching_table_data'));
148
  }
 
 
 
 
 
149
  $action = $responseParams['nextFunc'];
150
  $status = $responseParams['status'];
151
  if(empty($action))
@@ -421,41 +426,64 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
421
  $temp_sql_file_name = $file.".sql";
422
  $file = $db_folder . $temp_sql_file_name;
423
  global $wpdb;
424
- $paths = $this->getMySQLPath();
 
 
 
 
 
 
 
 
425
  $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
426
  //$command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
427
- $command0 = $wpdb->get_col('SHOW TABLES LIKE "'.$wpdb->base_prefix.'%"');
428
- $full_table = array();
429
- $structure_only_table = array();
430
- if (!empty($exclude_tables)) {
431
- foreach ($command0 as $tk => $table) {
432
- foreach ($exclude_tables as $ke => $exclude_table) {
433
- $structure = false;
434
- if (strpos($table, $exclude_table)) {
435
- $structure = true;
436
- break;
 
 
 
437
  }
 
 
 
 
 
438
  }
439
- if ($structure) {
440
- $structure_only_table [] = $table;
441
- }else{
442
- $full_table [] = $table;
443
- }
444
  }
445
- }else{
446
- $full_table = $command0;
447
- }
448
- $wp_tables = join("\" \"",$full_table);
 
 
 
 
 
 
 
449
  $skipThisTable = false;
450
- $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --max_allowed_packet=8M --net_buffer_length=1M --skip-comments --skip-set-charset --allow-keywords --dump-date --add-drop-table --skip-lock-tables --extended-insert "' . DB_NAME . '" "'.$wp_tables.'" > ' . $brace . $file . $brace;
451
-
 
 
 
 
452
 
453
  iwp_mmb_print_flush('DB DUMP CMD: Start');
454
  ob_start();
455
  update_option('iwp_multical_db_dump_flag', 1);
456
  if (!empty($structure_only_table)) {
457
- $wp_tables = join("\" \"",$structure_only_table);
458
- $structure_command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables --no-data "' . DB_NAME . '" "'.$wp_tables.'" >> ' . $brace . $file . $brace;
459
  // $result = $this->iwp_mmb_exec($structure_command);
460
  $command.=' && '.$structure_command;
461
 
@@ -466,6 +494,43 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
466
  $time = microtime(true);
467
  $finish_part = $time;
468
  $total_time_part = $finish_part - $this->iwpScriptStartTime;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
 
470
  if (!$result) { // Fallback to php
471
  // $result = $this->backup_db_php($file);
@@ -556,7 +621,12 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
556
  $paths['mysqldump'] = 'mysqldump.exe';
557
  }
558
  } else{
559
- $mysqlPath = "/usr/bin/mysqldump,/bin/mysqldump,/usr/local/bin/mysqldump,/usr/sfw/bin/mysqldump,/usr/xdg4/bin/mysqldump,/opt/bin/mysqldump";
 
 
 
 
 
560
  $bin = explode(',' , $mysqlPath);
561
  $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
562
  $db_folder = IWP_DB_DIR . '/';
@@ -577,12 +647,19 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
577
  'mysql' => $value,
578
  'mysqldump' => $value
579
  );
580
-
581
  return $paths;
582
  }
583
  unlink($file);
584
  }
585
 
 
 
 
 
 
 
 
586
  return $paths;
587
  }
588
 
@@ -745,13 +822,15 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
745
  $res_arr = array();
746
  $res_arr['response_data'] = array();
747
  $res_arr['file_name'] = DB_NAME;
748
- $res_arr['response_data'] = array();
749
  $res_arr['backup_file'] = $backup_file;
750
  $res_arr['backup_url'] = $this -> backup_url;
751
  $res_arr['account_info'] = $account_info;
752
  $this->statusLog($historyID, array('stage' => 'backupDB', 'status' => 'initiating', 'statusMsg' => 'createdFileNameAndSent','responseParams' => $res_arr));
753
  $func = $this->check_sys();
754
  $db_result = true;
 
 
 
755
  if ($db_result) {
756
  $db_result = $this->backup_db_dump_multi($historyID);
757
  }
@@ -920,7 +999,13 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
920
  //$tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
921
  $this_prefix = $wpdb->base_prefix;
922
  $tables = $wpdb->get_results('SHOW TABLES LIKE "'.$this_prefix.'%"', ARRAY_N);
923
-
 
 
 
 
 
 
924
  foreach ($tables as $table) {
925
  $is_continue = '';
926
  foreach($response_array as $k => $v)
@@ -988,9 +1073,9 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
988
  {
989
  $breakingCount = 0;
990
  }
991
- if ($count > 100)
992
  {
993
- $count = ceil($count / 100);
994
  if($left_out_count > 0)
995
  {
996
  $temp_left_count = $left_out_count;
@@ -1019,14 +1104,14 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
1019
  {
1020
  if($done_count > ($i))
1021
  {
1022
- $count_field += 100 * $no_of_cols;
1023
  continue;
1024
  }
1025
  }
1026
 
1027
  iwp_mmb_auto_print('backup_db_php_fail_safe');
1028
- $low_limit = $i * 100;
1029
- $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
1030
  $rows = $wpdb->get_results($qry, ARRAY_A);
1031
 
1032
  $number_data_types = 'tinyint, smallint, mediumint, bigint, int, decimal, numeric, real, float, double';
@@ -1797,6 +1882,9 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
1797
  }
1798
  manual_debug('', 'afterHeaderWrite', 0);
1799
  $v_size = @ftell($archive->zip_fd)-$v_offset;
 
 
 
1800
  $archive->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment);
1801
  $archive->privCloseFd();
1802
  echo 'iwpmsg next Count -'.$nextCount;
@@ -1849,6 +1937,9 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
1849
  $status = 'error';
1850
  return array('error' => 'Must be error');
1851
  }
 
 
 
1852
  if($status == 'partiallyCompleted')
1853
  {
1854
  echo 'iwpmsg filesNextCount: '.$nextCount;
@@ -2077,7 +2168,7 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
2077
  unset($p_filedescr_list);
2078
  unset($p_filedescr_list_array['p_filedescr_list']);
2079
  $result_arr['response_data']['next_file_index'] = $p_filedescr_list_array['next_file_index'];
2080
- $result_arr['response_data']['complete_folder_list'] = $p_filedescr_list_array['complete_folder_list'];
2081
 
2082
  $this->statusLog($this -> hisID, array('stage' => 'gettingFileList', 'status' => 'processing', 'statusMsg' => 'gettingFileListInMultiCall','responseParams' => $result_arr));
2083
  unset($p_filedescr_list_array);
@@ -2151,6 +2242,9 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
2151
  {
2152
  $v_read_size = ($actualFileSize < IWP_PCLZIP_READ_BLOCK_SIZE ? $actualFileSize : IWP_PCLZIP_READ_BLOCK_SIZE);
2153
  $v_buffer = fread($archive->zip_fd, $v_read_size);
 
 
 
2154
  @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2155
  $actualFileSize -= $v_read_size;
2156
  }
@@ -3914,7 +4008,7 @@ class IWP_MMB_Backup_Multicall extends IWP_MMB_Core
3914
  if ($this->iwp_mmb_function_exists('system'))
3915
  return 'system';
3916
 
3917
- if ($this->iwp_mmb_function_exists('passhtru'))
3918
  return 'passthru';
3919
 
3920
  return false;
@@ -4400,7 +4494,7 @@ function ftp_backup($historyID,$args = '')
4400
  }
4401
  }
4402
 
4403
- function postUploadS3VerificationBwdComp($backup_file, $destFile, $type = "", $as3_bucket = "", $as3_access_key = "", $as3_secure_key = "", $as3_bucket_region = "", &$obj, $actual_file_size, $size1, $size2, $return_size = false){
4404
  $response = $obj -> if_object_exists($as3_bucket, $destFile);
4405
  if($response == true)
4406
  {
@@ -4631,8 +4725,8 @@ function ftp_backup($historyID,$args = '')
4631
 
4632
  $args = $responseParams['dropboxArgs'];
4633
  $prevChunkResults = $responseParams['response_data'];
4634
- $uploadid = $prevChunkResults['upload_id'];
4635
- $offset = $prevChunkResults['offset'];
4636
  $current_file_num = $responseParams['current_file_num'];
4637
  }
4638
 
@@ -6255,7 +6349,7 @@ function ftp_backup($historyID,$args = '')
6255
 
6256
  $deleteRes = $wpdb->query($delete_query);
6257
  }
6258
- if ($fromNewBackup) {
6259
  return ($deleted)?true:false;
6260
  }else{
6261
  return true;
@@ -6625,6 +6719,7 @@ function ftp_backup($historyID,$args = '')
6625
  $cpuUsageLog = 'DE_clCPUUsage.'.$iwp_multicall_hisID.'.txt';
6626
  $debug_count = 0;
6627
  $every_count = 0;
 
6628
  if (function_exists('sys_getloadavg')) {
6629
  $cpu_load = sys_getloadavg();
6630
  $current_cpu_load = $cpu_load[0];
@@ -6634,11 +6729,10 @@ function ftp_backup($historyID,$args = '')
6634
  $this_memory_in_mb = memory_get_usage();
6635
  $this_memory_in_mb = $this_memory_in_mb / 1048576;
6636
  $this_time_taken = microtime(true) - $GLOBALS['IWP_MMB_PROFILING']['ACTION_START'];
6637
-
6638
- file_put_contents(IWP_BACKUP_DIR . '/'.$memoryPeakLog,$debug_count . $printText . " " . round($this_memory_peak_in_mb, 2) ."\n");
6639
- file_put_contents(IWP_BACKUP_DIR . '/'.$memoryUsageLog,$debug_count . $printText . " " . round($this_memory_in_mb, 2) ."\n");
6640
- file_put_contents(IWP_BACKUP_DIR . '/'.$timeTakenLog,$debug_count . $printText . " " . round($this_time_taken, 2) ."\n");
6641
- file_put_contents(IWP_BACKUP_DIR . '/'.$cpuUsageLog,$debug_count . $printText . " " . $current_cpu_load ."\n");
6642
  }
6643
  }
6644
 
@@ -6683,7 +6777,9 @@ function ftp_backup($historyID,$args = '')
6683
  $cpuUsageLog = 'DE_clCPUUsage.'.$iwp_multicall_hisID.'.txt';
6684
  if (function_exists('sys_getloadavg')) {
6685
  $cpu_load = sys_getloadavg();
6686
- $current_cpu_load = $cpu_load[0];
 
 
6687
  }
6688
 
6689
  if($conditions == 'printOnly'){
146
  {
147
  return $this->statusLog($datas['backupParentHID'], array('stage' => 'trigger_check', 'status' => 'error', 'statusMsg' => 'Error while fetching table data', 'statusCode' => 'error_while_fetching_table_data'));
148
  }
149
+ $defaults = array (
150
+ 'nextFunc' => NULL,
151
+ 'status' => NULL
152
+ );
153
+ $responseParams = wp_parse_args( $responseParams, $defaults );
154
  $action = $responseParams['nextFunc'];
155
  $status = $responseParams['status'];
156
  if(empty($action))
426
  $temp_sql_file_name = $file.".sql";
427
  $file = $db_folder . $temp_sql_file_name;
428
  global $wpdb;
429
+ if(empty($responseParams['mysqldump'])){
430
+ $paths = $this->getMySQLPath();
431
+ }else{
432
+ $paths['mysqldump'] = $responseParams['mysqldump'];
433
+ }
434
+ if(empty($paths['mysqldump'])){
435
+ // Fallback to php
436
+ return false;
437
+ }
438
  $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
439
  //$command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
440
+ if(empty($responseParams['full_table'])){
441
+ // Avoid getting exclude_table on mysqlDump retry call
442
+ $command0 = $wpdb->get_col('SHOW TABLES LIKE "'.$wpdb->base_prefix.'%"');
443
+ $full_table = array();
444
+ $structure_only_table = array();
445
+ if (!empty($exclude_tables)) {
446
+ foreach ($command0 as $tk => $table) {
447
+ foreach ($exclude_tables as $ke => $exclude_table) {
448
+ $structure = false;
449
+ if (!empty($exclude_table) && strpos($table, $exclude_table)) {
450
+ $structure = true;
451
+ break;
452
+ }
453
  }
454
+ if ($structure) {
455
+ $structure_only_table [] = $table;
456
+ }else{
457
+ $full_table [] = $table;
458
+ }
459
  }
460
+ }else{
461
+ $full_table = $command0;
 
 
 
462
  }
463
+ $wp_tables = join("\" \"",$full_table);
464
+ if(!empty($structure_only_table)){
465
+ $structure_only_table = join("\" \"",$structure_only_table);
466
+ }
467
+
468
+ }else{
469
+ $wp_tables = $responseParams['full_table'];
470
+ if(!empty($responseParams['structure_only_table'])){
471
+ $structure_only_table = $responseParams['structure_only_table'];
472
+ }
473
+ }
474
  $skipThisTable = false;
475
+ $msqld_max_allowed_packet = (defined('IWP_MYSQLDUMP_MAX_ALLOWED_PACKET') && (is_int(IWP_MYSQLDUMP_MAX_ALLOWED_PACKET) || is_string(IWP_MYSQLDUMP_MAX_ALLOWED_PACKET))) ? IWP_MYSQLDUMP_MAX_ALLOWED_PACKET : '8M';
476
+ if(!empty($responseParams['max_allowed_packet'])){
477
+ $msqld_max_allowed_packet = $responseParams['max_allowed_packet'];
478
+ }
479
+
480
+ $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --max_allowed_packet='.$msqld_max_allowed_packet.' --net_buffer_length=1M --skip-comments --skip-set-charset --allow-keywords --dump-date --add-drop-table --skip-lock-tables --extended-insert "' . DB_NAME . '" "'.$wp_tables.'" > ' . $brace . $file . $brace;
481
 
482
  iwp_mmb_print_flush('DB DUMP CMD: Start');
483
  ob_start();
484
  update_option('iwp_multical_db_dump_flag', 1);
485
  if (!empty($structure_only_table)) {
486
+ $structure_command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables --no-data "' . DB_NAME . '" "'.$structure_only_table.'" >> ' . $brace . $file . $brace;
 
487
  // $result = $this->iwp_mmb_exec($structure_command);
488
  $command.=' && '.$structure_command;
489
 
494
  $time = microtime(true);
495
  $finish_part = $time;
496
  $total_time_part = $finish_part - $this->iwpScriptStartTime;
497
+ if(!$result && !defined('IWP_MYSQLDUMP_MAX_ALLOWED_PACKET')){
498
+ // It will work when the Mysqldump comment available, but due to low max_allowed_packet size. Mysqldump not working, so we are manually increasing the max_allowed_packet size
499
+ // the call triggered from trigger_check via nextFunc
500
+ if(!empty($responseParams['max_allowed_packet'])){
501
+ delete_option('iwp_multical_db_dump_flag');
502
+ return $this->backupDBPHP($historyID);
503
+ }
504
+ if(empty($responseParams['max_allowed_packet'])){
505
+ global $iwp_mmb_core;
506
+ $db_final_response['success']['max_allowed_packet'] = $iwp_mmb_core->get_max_allowed_packet();
507
+
508
+ }
509
+ $db_final_response['success']['response_data'] = array();
510
+ $db_final_response['success']['backup_file'] = $responseParams['backup_file'];
511
+ $db_final_response['success']['backup_url'] = $responseParams['backup_url'];
512
+ $db_final_response['success']['parentHID'] = $historyID;
513
+ $db_final_response['success']['backupParentHID'] = $historyID;
514
+ $db_final_response['success']['nextFunc'] = 'backup_db_dump_multi';
515
+ $db_final_response['success']['account_info'] = $responseParams['account_info'];
516
+ $db_final_response['success']['status'] = 'partiallyCompleted';
517
+ $db_final_response['success']['full_table'] = $wp_tables;
518
+ $db_final_response['success']['mysqldump'] = $paths['mysqldump'];
519
+ if(!empty($structure_only_table)){
520
+ $db_final_response['success']['structure_only_table'] = $structure_only_table;
521
+ }
522
+
523
+ $backupStage = 'backupDBMultiCall';
524
+ $this->statusLog($historyID, array('stage' => $backupStage, 'status' => 'partiallyCompleted', 'statusMsg' => 'backupDBMultiCallRetry','nextFunc' => 'backup_db_dump_multi', 'responseParams' => $db_final_response['success']));
525
+
526
+ $db_res_array = array();
527
+ $db_res_array['status'] = 'partiallyCompleted';
528
+ $db_res_array['statusMsg'] = 'backupDBMultiCallRetry';
529
+ $db_res_array['backupParentHID'] = $historyID;
530
+ $db_res_array['parentHID'] = $historyID;
531
+ $db_res_array['max_allowed_packet'] = $db_final_response['success']['max_allowed_packet'];
532
+ return $db_res_array;
533
+ }
534
 
535
  if (!$result) { // Fallback to php
536
  // $result = $this->backup_db_php($file);
621
  $paths['mysqldump'] = 'mysqldump.exe';
622
  }
623
  } else{
624
+ if(defined('IWP_MYSQLDUMP_EXECUTABLE') && IWP_MYSQLDUMP_EXECUTABLE){
625
+ $mysqlPath = IWP_MYSQLDUMP_EXECUTABLE;
626
+ }else{
627
+ $mysqlPath = iwp_mmb_build_mysqldump_list();
628
+ }
629
+
630
  $bin = explode(',' , $mysqlPath);
631
  $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
632
  $db_folder = IWP_DB_DIR . '/';
647
  'mysql' => $value,
648
  'mysqldump' => $value
649
  );
650
+
651
  return $paths;
652
  }
653
  unlink($file);
654
  }
655
 
656
+ if (empty($paths['mysql'])){
657
+ $paths['mysql'] = $this->iwp_mmb_exec('which mysql', true);
658
+ }
659
+
660
+ if (empty($paths['mysqldump'])){
661
+ $paths['mysqldump'] = $this->iwp_mmb_exec('which mysqldump', true);
662
+ }
663
  return $paths;
664
  }
665
 
822
  $res_arr = array();
823
  $res_arr['response_data'] = array();
824
  $res_arr['file_name'] = DB_NAME;
 
825
  $res_arr['backup_file'] = $backup_file;
826
  $res_arr['backup_url'] = $this -> backup_url;
827
  $res_arr['account_info'] = $account_info;
828
  $this->statusLog($historyID, array('stage' => 'backupDB', 'status' => 'initiating', 'statusMsg' => 'createdFileNameAndSent','responseParams' => $res_arr));
829
  $func = $this->check_sys();
830
  $db_result = true;
831
+ if($func == false){
832
+ $db_result = false;
833
+ }
834
  if ($db_result) {
835
  $db_result = $this->backup_db_dump_multi($historyID);
836
  }
999
  //$tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
1000
  $this_prefix = $wpdb->base_prefix;
1001
  $tables = $wpdb->get_results('SHOW TABLES LIKE "'.$this_prefix.'%"', ARRAY_N);
1002
+
1003
+ $max_row_limit = 100;
1004
+ if(defined('IWP_PHP_DB_ROWS') && (is_int(IWP_PHP_DB_ROWS) || is_string(IWP_PHP_DB_ROWS))){
1005
+ if(IWP_PHP_DB_ROWS > $max_row_limit ){
1006
+ $max_row_limit = IWP_PHP_DB_ROWS;
1007
+ }
1008
+ }
1009
  foreach ($tables as $table) {
1010
  $is_continue = '';
1011
  foreach($response_array as $k => $v)
1073
  {
1074
  $breakingCount = 0;
1075
  }
1076
+ if ($count > $max_row_limit)
1077
  {
1078
+ $count = ceil($count / $max_row_limit);
1079
  if($left_out_count > 0)
1080
  {
1081
  $temp_left_count = $left_out_count;
1104
  {
1105
  if($done_count > ($i))
1106
  {
1107
+ $count_field += $max_row_limit * $no_of_cols;
1108
  continue;
1109
  }
1110
  }
1111
 
1112
  iwp_mmb_auto_print('backup_db_php_fail_safe');
1113
+ $low_limit = $i * $max_row_limit;
1114
+ $qry = "SELECT * FROM $table[0] LIMIT $low_limit, $max_row_limit";
1115
  $rows = $wpdb->get_results($qry, ARRAY_A);
1116
 
1117
  $number_data_types = 'tinyint, smallint, mediumint, bigint, int, decimal, numeric, real, float, double';
1882
  }
1883
  manual_debug('', 'afterHeaderWrite', 0);
1884
  $v_size = @ftell($archive->zip_fd)-$v_offset;
1885
+ if(empty($v_comment)){
1886
+ $v_comment = '';
1887
+ }
1888
  $archive->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment);
1889
  $archive->privCloseFd();
1890
  echo 'iwpmsg next Count -'.$nextCount;
1937
  $status = 'error';
1938
  return array('error' => 'Must be error');
1939
  }
1940
+ if(!isset($p_filedescr_list)){
1941
+ $p_filedescr_list = array();
1942
+ }
1943
  if($status == 'partiallyCompleted')
1944
  {
1945
  echo 'iwpmsg filesNextCount: '.$nextCount;
2168
  unset($p_filedescr_list);
2169
  unset($p_filedescr_list_array['p_filedescr_list']);
2170
  $result_arr['response_data']['next_file_index'] = $p_filedescr_list_array['next_file_index'];
2171
+ $result_arr['response_data']['complete_folder_list'] = isset($p_filedescr_list_array['complete_folder_list']) ? $p_filedescr_list_array['complete_folder_list'] : array();
2172
 
2173
  $this->statusLog($this -> hisID, array('stage' => 'gettingFileList', 'status' => 'processing', 'statusMsg' => 'gettingFileListInMultiCall','responseParams' => $result_arr));
2174
  unset($p_filedescr_list_array);
2242
  {
2243
  $v_read_size = ($actualFileSize < IWP_PCLZIP_READ_BLOCK_SIZE ? $actualFileSize : IWP_PCLZIP_READ_BLOCK_SIZE);
2244
  $v_buffer = fread($archive->zip_fd, $v_read_size);
2245
+ if (empty($v_buffer)) {
2246
+ break;
2247
+ }
2248
  @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2249
  $actualFileSize -= $v_read_size;
2250
  }
4008
  if ($this->iwp_mmb_function_exists('system'))
4009
  return 'system';
4010
 
4011
+ if ($this->iwp_mmb_function_exists('passthru'))
4012
  return 'passthru';
4013
 
4014
  return false;
4494
  }
4495
  }
4496
 
4497
+ function postUploadS3VerificationBwdComp($backup_file, $destFile, $type = "", $as3_bucket = "", $as3_access_key = "", $as3_secure_key = "", $as3_bucket_region = "", &$obj = "", $actual_file_size = "", $size1 = 0 , $size2 = 0, $return_size = false){
4498
  $response = $obj -> if_object_exists($as3_bucket, $destFile);
4499
  if($response == true)
4500
  {
4725
 
4726
  $args = $responseParams['dropboxArgs'];
4727
  $prevChunkResults = $responseParams['response_data'];
4728
+ $uploadid = isset($prevChunkResults['upload_id']) ? $prevChunkResults['upload_id'] : 0;
4729
+ $offset = isset($prevChunkResults['offset']) ? $prevChunkResults['offset'] : 0;
4730
  $current_file_num = $responseParams['current_file_num'];
4731
  }
4732
 
6349
 
6350
  $deleteRes = $wpdb->query($delete_query);
6351
  }
6352
+ if (!empty($fromNewBackup) && $fromNewBackup) {
6353
  return ($deleted)?true:false;
6354
  }else{
6355
  return true;
6719
  $cpuUsageLog = 'DE_clCPUUsage.'.$iwp_multicall_hisID.'.txt';
6720
  $debug_count = 0;
6721
  $every_count = 0;
6722
+ $current_cpu_load = 0;
6723
  if (function_exists('sys_getloadavg')) {
6724
  $cpu_load = sys_getloadavg();
6725
  $current_cpu_load = $cpu_load[0];
6729
  $this_memory_in_mb = memory_get_usage();
6730
  $this_memory_in_mb = $this_memory_in_mb / 1048576;
6731
  $this_time_taken = microtime(true) - $GLOBALS['IWP_MMB_PROFILING']['ACTION_START'];
6732
+ file_put_contents(IWP_BACKUP_DIR . '/'.$memoryPeakLog,$debug_count . " " . round($this_memory_peak_in_mb, 2) ."\n");
6733
+ file_put_contents(IWP_BACKUP_DIR . '/'.$memoryUsageLog,$debug_count . " " . round($this_memory_in_mb, 2) ."\n");
6734
+ file_put_contents(IWP_BACKUP_DIR . '/'.$timeTakenLog,$debug_count . " " . round($this_time_taken, 2) ."\n");
6735
+ file_put_contents(IWP_BACKUP_DIR . '/'.$cpuUsageLog,$debug_count . " " . $current_cpu_load ."\n");
 
6736
  }
6737
  }
6738
 
6777
  $cpuUsageLog = 'DE_clCPUUsage.'.$iwp_multicall_hisID.'.txt';
6778
  if (function_exists('sys_getloadavg')) {
6779
  $cpu_load = sys_getloadavg();
6780
+ if(!empty($cpu_load)){
6781
+ $current_cpu_load = $cpu_load[0];
6782
+ }
6783
  }
6784
 
6785
  if($conditions == 'printOnly'){
backup.class.singlecall.php CHANGED
@@ -150,7 +150,7 @@ class IWP_MMB_Backup_Singlecall extends IWP_MMB_Core
150
  global $iwp_mmb_activities_log;
151
 
152
  if (!empty($params)) {
153
-
154
  $this->statusLog($historyID, array('stage' => 'verification', 'status' => 'processing', 'statusMsg' => 'verificationInitiated'), $params);
155
 
156
  $this->set_resource_limit();
@@ -1093,14 +1093,31 @@ function delete_task_now($task_name){
1093
  return $result;
1094
  }
1095
 
1096
- $result = $this->backup_db_dump($file); // try mysqldump always then fallback to php dump
1097
- return $result;
 
 
 
 
 
 
 
 
 
 
 
 
 
1098
  }
1099
 
1100
  function backup_db_dump($file)
1101
  {
1102
  global $wpdb;
1103
  $paths = $this->getMySQLPath();
 
 
 
 
1104
  $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
1105
  $exclude_tables = $this->tasks['args']['exclude_tables'];
1106
  //$command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
@@ -1126,12 +1143,13 @@ function delete_task_now($task_name){
1126
  $full_table = $command0;
1127
  }
1128
  $wp_tables = join("\" \"",$full_table);
1129
- $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --max_allowed_packet=8M --net_buffer_length=1M --skip-comments --skip-set-charset --allow-keywords --dump-date --add-drop-table --skip-lock-tables --extended-insert "' . DB_NAME . '" "'.$wp_tables.'" > ' . $brace . $file . $brace;
 
1130
  iwp_mmb_print_flush('DB DUMP CMD: Start');
1131
  ob_start();
1132
  if (!empty($structure_only_table)) {
1133
- $wp_tables = join("\" \"",$structure_only_table);
1134
- $structure_command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables --no-data "' . DB_NAME . '" "'.$wp_tables.'" >> ' . $brace . $file . $brace;
1135
  // $result = $this->iwp_mmb_exec($structure_command);
1136
  $command.=' && '.$structure_command;
1137
 
@@ -1139,10 +1157,26 @@ function delete_task_now($task_name){
1139
  $result = $this->iwp_mmb_exec($command);
1140
  ob_get_clean();
1141
  iwp_mmb_print_flush('DB DUMP CMD: End');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1142
 
1143
  if (!$result) { // Fallback to php
1144
- $result = $this->backup_db_php($file);
1145
- return $result;
1146
  }
1147
 
1148
  if (iwp_mmb_get_file_size($file) == 0 || !is_file($file) || !$result) {
@@ -1241,6 +1275,13 @@ function delete_task_now($task_name){
1241
  iwp_mmb_print_flush('DB DUMP PHP Normal: End');
1242
  }
1243
  else{
 
 
 
 
 
 
 
1244
  iwp_mmb_print_flush('DB DUMP PHP Fail-safe: Start');
1245
  file_put_contents($file, '');//safe to reset any old data
1246
  //$tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
@@ -1269,15 +1310,15 @@ function delete_task_now($task_name){
1269
  }
1270
 
1271
  $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
1272
- if ($count > 100)
1273
- $count = ceil($count / 100);
1274
  else if ($count > 0)
1275
  $count = 1;
1276
 
1277
  for ($i = 0; $i < $count; $i++) {
1278
  iwp_mmb_auto_print('backup_db_php_fail_safe');
1279
- $low_limit = $i * 100;
1280
- $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
1281
  $rows = $wpdb->get_results($qry, ARRAY_A);
1282
  if (is_array($rows)) {
1283
  foreach ($rows as $row) {
@@ -1349,6 +1390,7 @@ function delete_task_now($task_name){
1349
  global $wpdb;
1350
  $query = 'SHOW TABLE STATUS';
1351
  $tables = $wpdb->get_results($query, ARRAY_A);
 
1352
  foreach ($tables as $table) {
1353
  if (in_array($table['Engine'], array(
1354
  'MyISAM',
@@ -1421,7 +1463,11 @@ function delete_task_now($task_name){
1421
  $paths['mysqldump'] = 'mysqldump.exe';
1422
  }
1423
  } else{
1424
- $mysqlPath = "/usr/bin/mysqldump,/bin/mysqldump,/usr/local/bin/mysqldump,/usr/sfw/bin/mysqldump,/usr/xdg4/bin/mysqldump,/opt/bin/mysqldump";
 
 
 
 
1425
  $bin = explode(',' , $mysqlPath);
1426
  $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
1427
  $db_folder = IWP_DB_DIR . '/';
@@ -1447,7 +1493,13 @@ function delete_task_now($task_name){
1447
  }
1448
  unlink($file);
1449
  }
1450
-
 
 
 
 
 
 
1451
  return $paths;
1452
  }
1453
 
@@ -1460,7 +1512,7 @@ function delete_task_now($task_name){
1460
  if ($this->iwp_mmb_function_exists('system'))
1461
  return 'system';
1462
 
1463
- if ($this->iwp_mmb_function_exists('passhtru'))
1464
  return 'passthru';
1465
 
1466
  return false;
@@ -1952,7 +2004,7 @@ function delete_task_now($task_name){
1952
  $no_low_quota = true;
1953
  }
1954
  }*/
1955
- $disk_free_space = @disk_free_space(IWP_BACKUP_DIR);
1956
  if ($disk_free_space == false) {
1957
  $quota_free = 'Unknown';
1958
  } else {
@@ -2889,13 +2941,17 @@ function ftp_backup($args)
2889
  $table_name = $wpdb->base_prefix . "iwp_backup_status";
2890
  $rows = $wpdb->get_results("select * from ".$table_name);
2891
  $task_res = array();
2892
- foreach($rows as $key => $value){
2893
- $task_results = unserialize($value->taskResults);
2894
- $task_res[$value->taskName][$value->historyID] = $task_results['task_results'][$value->historyID];
2895
- if (!empty($task_results['backhack_status'])) {
2896
- $task_res[$value->taskName][$value->historyID]['backhack_status'] = $task_results['backhack_status'];
2897
- }
2898
- }
 
 
 
 
2899
  $stats = $task_res;
2900
  return $stats;
2901
  /*foreach ($rows as $obj) {
@@ -3073,7 +3129,9 @@ function ftp_backup($args)
3073
  //$requestParams = unserialize($tasks['requestParams']);
3074
  $requestParams = $this->getRequiredData($result_id, 'requestParams');
3075
 
3076
- $args = $requestParams['account_info'];
 
 
3077
 
3078
  if (isset($backup['server'])) {
3079
  $backup_file = $backup['server']['file_path'];
@@ -3344,7 +3402,7 @@ function ftp_backup($args)
3344
  $returnParams['backupID'] = $insertID;
3345
  $returnParams['stage'] = $statusArray['stage'] ;
3346
  $returnParams['status'] = $statusArray['status'];
3347
- $returnParams['nextFunc'] = $statusArray['nextFunc'];
3348
  return array('success' => $returnParams);
3349
  }
3350
  else
@@ -3573,7 +3631,7 @@ if( !function_exists('upgradeOldDropBoxBackupList')){
3573
  }
3574
  foreach ($rows as $ID => $taskArray) {
3575
  $requestParams = unserialize($taskArray['requestParams']);
3576
- $accountInfo = $requestParams['account_info'];
3577
  if (isset($accountInfo['iwp_dropbox']) && isset($accountInfo['iwp_dropbox']['oauth_token']) && !empty($accountInfo['iwp_dropbox']['oauth_token'])) {
3578
  $requestParams['account_info']['iwp_dropbox']['consumer_key'] = '';
3579
  $requestParams['account_info']['iwp_dropbox']['consumer_secret'] = '';
150
  global $iwp_mmb_activities_log;
151
 
152
  if (!empty($params)) {
153
+ $historyID = '';
154
  $this->statusLog($historyID, array('stage' => 'verification', 'status' => 'processing', 'statusMsg' => 'verificationInitiated'), $params);
155
 
156
  $this->set_resource_limit();
1093
  return $result;
1094
  }
1095
 
1096
+ $func = $this->check_sys();
1097
+ $db_result = true;
1098
+ if($func == false){
1099
+ $db_result = false;
1100
+ }
1101
+ if ($db_result) {
1102
+
1103
+ $db_result = $this->backup_db_dump($file);
1104
+ }
1105
+
1106
+ if ($db_result == false) {
1107
+
1108
+ $db_result = $this->backup_db_php($file);
1109
+ }
1110
+ return $db_result;
1111
  }
1112
 
1113
  function backup_db_dump($file)
1114
  {
1115
  global $wpdb;
1116
  $paths = $this->getMySQLPath();
1117
+ if(empty($paths['mysqldump'])){
1118
+ // Fallback to $this->backup_db_php($file);
1119
+ return false;
1120
+ }
1121
  $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
1122
  $exclude_tables = $this->tasks['args']['exclude_tables'];
1123
  //$command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
1143
  $full_table = $command0;
1144
  }
1145
  $wp_tables = join("\" \"",$full_table);
1146
+ $msqld_max_allowed_packet = (defined('IWP_MYSQLDUMP_MAX_ALLOWED_PACKET') && (is_int(IWP_MYSQLDUMP_MAX_ALLOWED_PACKET) || is_string(IWP_MYSQLDUMP_MAX_ALLOWED_PACKET))) ? IWP_MYSQLDUMP_MAX_ALLOWED_PACKET : '8M';
1147
+ $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --max_allowed_packet='.$msqld_max_allowed_packet.' --net_buffer_length=1M --skip-comments --skip-set-charset --allow-keywords --dump-date --add-drop-table --skip-lock-tables --extended-insert "' . DB_NAME . '" "'.$wp_tables.'" > ' . $brace . $file . $brace;
1148
  iwp_mmb_print_flush('DB DUMP CMD: Start');
1149
  ob_start();
1150
  if (!empty($structure_only_table)) {
1151
+ $structure_only_wp_table = join("\" \"",$structure_only_table);
1152
+ $structure_command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables --no-data "' . DB_NAME . '" "'.$structure_only_wp_table.'" >> ' . $brace . $file . $brace;
1153
  // $result = $this->iwp_mmb_exec($structure_command);
1154
  $command.=' && '.$structure_command;
1155
 
1157
  $result = $this->iwp_mmb_exec($command);
1158
  ob_get_clean();
1159
  iwp_mmb_print_flush('DB DUMP CMD: End');
1160
+
1161
+ if(!$result && !defined('IWP_MYSQLDUMP_MAX_ALLOWED_PACKET')){
1162
+ // It will work when the Mysqldump comment available, but due to low max_allowed_packet size. Mysqldump not working, so we are manually increasing the max_allowed_packet size
1163
+
1164
+ global $iwp_mmb_core;
1165
+ $msqld_max_allowed_packet = $iwp_mmb_core->get_max_allowed_packet();
1166
+ $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --max_allowed_packet='.$msqld_max_allowed_packet.' --net_buffer_length=1M --skip-comments --skip-set-charset --allow-keywords --dump-date --add-drop-table --skip-lock-tables --extended-insert "' . DB_NAME . '" "'.$wp_tables.'" > ' . $brace . $file . $brace;
1167
+
1168
+ iwp_mmb_print_flush('DB DUMP CMD RETRY: Start');
1169
+ ob_start();
1170
+ if (!empty($structure_only_table)) {
1171
+ $command.=' && '.$structure_command;
1172
+ }
1173
+ $result = $this->iwp_mmb_exec($command);
1174
+ ob_get_clean();
1175
+ iwp_mmb_print_flush('DB DUMP CMD RETRY: End');
1176
+ }
1177
 
1178
  if (!$result) { // Fallback to php
1179
+ return false;
 
1180
  }
1181
 
1182
  if (iwp_mmb_get_file_size($file) == 0 || !is_file($file) || !$result) {
1275
  iwp_mmb_print_flush('DB DUMP PHP Normal: End');
1276
  }
1277
  else{
1278
+ $max_row_limit = 100;
1279
+ if(defined('IWP_PHP_DB_ROWS') && (is_int(IWP_PHP_DB_ROWS) || is_string(IWP_PHP_DB_ROWS))){
1280
+ if(IWP_PHP_DB_ROWS > $max_row_limit ){
1281
+ $max_row_limit = IWP_PHP_DB_ROWS;
1282
+ }
1283
+ }
1284
+
1285
  iwp_mmb_print_flush('DB DUMP PHP Fail-safe: Start');
1286
  file_put_contents($file, '');//safe to reset any old data
1287
  //$tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
1310
  }
1311
 
1312
  $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
1313
+ if ($count > $max_row_limit)
1314
+ $count = ceil($count / $max_row_limit);
1315
  else if ($count > 0)
1316
  $count = 1;
1317
 
1318
  for ($i = 0; $i < $count; $i++) {
1319
  iwp_mmb_auto_print('backup_db_php_fail_safe');
1320
+ $low_limit = $i * $max_row_limit;
1321
+ $qry = "SELECT * FROM $table[0] LIMIT $low_limit, $max_row_limit";
1322
  $rows = $wpdb->get_results($qry, ARRAY_A);
1323
  if (is_array($rows)) {
1324
  foreach ($rows as $row) {
1390
  global $wpdb;
1391
  $query = 'SHOW TABLE STATUS';
1392
  $tables = $wpdb->get_results($query, ARRAY_A);
1393
+ $table_string = '';
1394
  foreach ($tables as $table) {
1395
  if (in_array($table['Engine'], array(
1396
  'MyISAM',
1463
  $paths['mysqldump'] = 'mysqldump.exe';
1464
  }
1465
  } else{
1466
+ if(defined('IWP_MYSQLDUMP_EXECUTABLE') && IWP_MYSQLDUMP_EXECUTABLE){
1467
+ $mysqlPath = IWP_MYSQLDUMP_EXECUTABLE;
1468
+ }else{
1469
+ $mysqlPath = iwp_mmb_build_mysqldump_list();
1470
+ }
1471
  $bin = explode(',' , $mysqlPath);
1472
  $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
1473
  $db_folder = IWP_DB_DIR . '/';
1493
  }
1494
  unlink($file);
1495
  }
1496
+ if (empty($paths['mysql'])){
1497
+ $paths['mysql'] = $this->iwp_mmb_exec('which mysql', true);
1498
+ }
1499
+
1500
+ if (empty($paths['mysqldump'])){
1501
+ $paths['mysqldump'] = $this->iwp_mmb_exec('which mysqldump', true);
1502
+ }
1503
  return $paths;
1504
  }
1505
 
1512
  if ($this->iwp_mmb_function_exists('system'))
1513
  return 'system';
1514
 
1515
+ if ($this->iwp_mmb_function_exists('passthru'))
1516
  return 'passthru';
1517
 
1518
  return false;
2004
  $no_low_quota = true;
2005
  }
2006
  }*/
2007
+ $disk_free_space = function_exists('disk_free_space') ? @disk_free_space(IWP_BACKUP_DIR) : false;
2008
  if ($disk_free_space == false) {
2009
  $quota_free = 'Unknown';
2010
  } else {
2941
  $table_name = $wpdb->base_prefix . "iwp_backup_status";
2942
  $rows = $wpdb->get_results("select * from ".$table_name);
2943
  $task_res = array();
2944
+ if(!empty($rows)){
2945
+ foreach($rows as $key => $value){
2946
+ $task_results = unserialize($value->taskResults);
2947
+ if(!empty($task_results['task_results'])){
2948
+ $task_res[$value->taskName][$value->historyID] = $task_results['task_results'][$value->historyID];
2949
+ }
2950
+ if (!empty($task_results['backhack_status'])) {
2951
+ $task_res[$value->taskName][$value->historyID]['backhack_status'] = $task_results['backhack_status'];
2952
+ }
2953
+ }
2954
+ }
2955
  $stats = $task_res;
2956
  return $stats;
2957
  /*foreach ($rows as $obj) {
3129
  //$requestParams = unserialize($tasks['requestParams']);
3130
  $requestParams = $this->getRequiredData($result_id, 'requestParams');
3131
 
3132
+ if(!empty($requestParams['account_info'])){
3133
+ $args = $requestParams['account_info'];
3134
+ }
3135
 
3136
  if (isset($backup['server'])) {
3137
  $backup_file = $backup['server']['file_path'];
3402
  $returnParams['backupID'] = $insertID;
3403
  $returnParams['stage'] = $statusArray['stage'] ;
3404
  $returnParams['status'] = $statusArray['status'];
3405
+ $returnParams['nextFunc'] = isset($statusArray['nextFunc']) ? $statusArray['nextFunc']:NULL;
3406
  return array('success' => $returnParams);
3407
  }
3408
  else
3631
  }
3632
  foreach ($rows as $ID => $taskArray) {
3633
  $requestParams = unserialize($taskArray['requestParams']);
3634
+ $accountInfo = isset($requestParams['account_info']) ? $requestParams['account_info']:array();
3635
  if (isset($accountInfo['iwp_dropbox']) && isset($accountInfo['iwp_dropbox']['oauth_token']) && !empty($accountInfo['iwp_dropbox']['oauth_token'])) {
3636
  $requestParams['account_info']['iwp_dropbox']['consumer_key'] = '';
3637
  $requestParams['account_info']['iwp_dropbox']['consumer_secret'] = '';
backup/backup-repo-test.php CHANGED
@@ -3,6 +3,7 @@
3
  class IWP_BACKUP_REPO_TEST {
4
 
5
  public function repositoryTestConnection($account_info){
 
6
  if(isset($account_info['iwp_ftp']) && !empty($account_info)) {
7
  $return = $this->FTPTestConnection($account_info['iwp_ftp']);
8
  }
@@ -188,7 +189,6 @@ class IWP_BACKUP_REPO_TEST {
188
  $uploadFilePath = IWP_BACKUP_DIR;
189
  $uploadTestFile = $sftp->put(basename($backup_file),$backup_file,NET_SFTP_LOCAL_FILE);
190
  @unlink($backup_file);
191
- $appPathFile = APP_ROOT.$testFile;
192
  if ($uploadTestFile === false) {
193
  return array('status' => 'error',
194
  'errorMsg' => 'FTP upload failed.',
3
  class IWP_BACKUP_REPO_TEST {
4
 
5
  public function repositoryTestConnection($account_info){
6
+ $return = array();
7
  if(isset($account_info['iwp_ftp']) && !empty($account_info)) {
8
  $return = $this->FTPTestConnection($account_info['iwp_ftp']);
9
  }
189
  $uploadFilePath = IWP_BACKUP_DIR;
190
  $uploadTestFile = $sftp->put(basename($backup_file),$backup_file,NET_SFTP_LOCAL_FILE);
191
  @unlink($backup_file);
 
192
  if ($uploadTestFile === false) {
193
  return array('status' => 'error',
194
  'errorMsg' => 'FTP upload failed.',
backup/backup.core.class.php CHANGED
@@ -439,7 +439,7 @@ class IWP_MMB_Backup_Core {
439
  $quota_free = '';
440
  }
441
 
442
- $disk_free_space = @disk_free_space($iwp_backup_dir);
443
  # == rather than === here is deliberate; support experience shows that a result of (int)0 is not reliable. i.e. 0 can be returned when the real result should be false.
444
  if ($disk_free_space == false) {
445
  call_user_func($logging_function, "Free space on disk containing InfiniteWP's temporary directory: Unknown".$quota_free);
@@ -1435,6 +1435,7 @@ class IWP_MMB_Backup_Core {
1435
  }
1436
 
1437
  public function backup_resume($resumption_no, $bnonce, $first_call = false) {
 
1438
 
1439
  set_error_handler(array($this, 'php_error'), E_ALL & ~E_STRICT);
1440
  if ($first_call) {
@@ -1554,12 +1555,12 @@ class IWP_MMB_Backup_Core {
1554
  // Argh. In fact, this has limited effect, as apparently (at least on another install seen), the saving of the updated transient via jobdata_set() also took no effect. Still, it does not hurt.
1555
  if ($resumption_no >= 1 && 'finished' == $this->jobdata_get('jobstatus')) {
1556
  $this->log('Terminate: This backup job is already finished (1).');
1557
- delete_option('IWP_backup_status');
1558
  die;
1559
  } elseif ('backup' == $job_type && !empty($this->backup_is_already_complete)) {
1560
  $this->jobdata_set('jobstatus', 'finished');
1561
  $this->log('Terminate: This backup job is already finished (2).');
1562
- delete_option('IWP_backup_status');
1563
  die;
1564
  }
1565
 
@@ -2002,6 +2003,7 @@ class IWP_MMB_Backup_Core {
2002
  // This procedure initiates a backup run
2003
  // $backup_files/$backup_database: true/false = yes/no (over-write allowed); 1/0 = yes/no (force)
2004
  public function boot_backup($backup_files, $backup_database, $restrict_files_to_override = false, $one_shot = false, $service = false, $options = array()) {
 
2005
 
2006
  @ignore_user_abort(true);
2007
  @set_time_limit(IWP_SET_TIME_LIMIT);
@@ -2010,7 +2012,7 @@ class IWP_MMB_Backup_Core {
2010
  // Generate backup information
2011
  $use_nonce = (empty($options['use_nonce'])) ? false : $options['use_nonce'];
2012
  $this->backup_time_nonce($use_nonce);
2013
- update_option('IWP_running_backupID',$this->nonce);
2014
  // The current_resumption is consulted within logfile_open()
2015
  $this->current_resumption = 0;
2016
  $this->logfile_open($this->nonce);
@@ -2018,7 +2020,8 @@ class IWP_MMB_Backup_Core {
2018
  if (!is_file($this->logfile_name)) {
2019
  $this->log('Failed to open log file ('.$this->logfile_name.') - the directory ('.$iwp_backup_dir.') for creating files in is not writable, or you ran out of disk space). Backup aborted.');
2020
  $this->log(__('Could not create files in the backup directory. Backup aborted','InfiniteWP'), 'error');
2021
- delete_option('IWP_running_backupID');
 
2022
  return false;
2023
  }
2024
 
@@ -2067,7 +2070,7 @@ class IWP_MMB_Backup_Core {
2067
  if (!IWP_MMB_Backup_Options::get_iwp_backup_option('IWP_debug_mode') && !empty($this->logfile_name) && file_exists($this->logfile_name)) {
2068
  unlink($this->logfile_name);
2069
  }
2070
- delete_option('IWP_running_backupID');
2071
  return $ret;
2072
  }
2073
 
@@ -2075,13 +2078,13 @@ class IWP_MMB_Backup_Core {
2075
  // doing_action() was added in WP 3.9
2076
  // wp_cron() can be called from the 'init' action
2077
 
2078
- if (function_exists('doing_action') && (doing_action('init') || @constant('DOING_CRON')) && (doing_action('IWP_backup_database') || doing_action('IWP_backup'))) {
2079
  $last_scheduled_action_called_at = get_option("IWP_last_scheduled_$semaphore");
2080
  // 11 minutes - so, we're assuming that they haven't custom-modified their schedules to run scheduled backups more often than that. If they have, they need also to use the filter to over-ride this check.
2081
  $seconds_ago = time() - $last_scheduled_action_called_at;
2082
  if ($last_scheduled_action_called_at && $seconds_ago < 660 && apply_filters('IWP_check_repeated_scheduled_backups', true)) {
2083
  $this->log(sprintf('Scheduled backup aborted - another backup of this type was apparently invoked by the WordPress scheduler only %d seconds ago - the WordPress scheduler invoking events multiple times usually indicates a very overloaded server (or other plugins that mis-use the scheduler)', $seconds_ago));
2084
- delete_option('IWP_running_backupID');
2085
  return;
2086
  }
2087
  }
@@ -2433,6 +2436,7 @@ class IWP_MMB_Backup_Core {
2433
  }
2434
 
2435
  private function backup_finish($cancel_event, $do_cleanup, $allow_email, $resumption_no, $force_abort = false) {
 
2436
 
2437
  if (!empty($this->semaphore)) $this->semaphore->unlock();
2438
 
@@ -2508,7 +2512,7 @@ class IWP_MMB_Backup_Core {
2508
  $this->log('The backup apparently succeeded and is now complete');
2509
  }
2510
  delete_option('IWP_jobdata_'.$this->nonce);
2511
- update_option('IWP_backup_status', '0');
2512
  $GLOBALS['iwp_mmb_activities_log']->iwp_mmb_save_iwp_activities('backup', 'multiCallNow', 'direct', array('what' => $what), $userid);
2513
  } else {
2514
  $final_message = __('The backup apparently succeeded (with warnings) and is now complete','InfiniteWP');
@@ -2517,7 +2521,7 @@ class IWP_MMB_Backup_Core {
2517
  }
2518
  $GLOBALS['iwp_mmb_activities_log']->iwp_mmb_save_iwp_activities('backup', 'multiCallNow', 'direct', array('what' => $what), $userid);
2519
  delete_option('IWP_jobdata_'.$this->nonce);
2520
- update_option('IWP_backup_status', '0');
2521
  }
2522
  if ($remote_sent && !$force_abort) $final_message .= '. '.__('To complete your migration/clone, you should now log in to the remote site and restore the backup set.', 'InfiniteWP');
2523
  if ($do_cleanup) $delete_jobdata = apply_filters('IWP_backup_complete', $delete_jobdata);
@@ -2544,7 +2548,7 @@ class IWP_MMB_Backup_Core {
2544
  // This is left until last for the benefit of the front-end UI, which then gets maximum chance to display the 'finished' status
2545
  if ($delete_jobdata) {
2546
  delete_option('IWP_jobdata_'.$this->nonce);
2547
- update_option('IWP_backup_status', '0');
2548
  }
2549
 
2550
  }
@@ -2874,12 +2878,12 @@ class IWP_MMB_Backup_Core {
2874
 
2875
  // Add backquotes to tables and db-names in SQL queries. Taken from phpMyAdmin.
2876
  public function backquote($a_name) {
2877
- if (!empty($a_name) && $a_name != '*') {
2878
  if (is_array($a_name)) {
2879
  $result = array();
2880
- reset($a_name);
2881
- while(list($key, $val) = each($a_name))
2882
  $result[$key] = '`'.$val.'`';
 
2883
  return $result;
2884
  } else {
2885
  return '`'.$a_name.'`';
@@ -3685,8 +3689,8 @@ CREATE TABLE $wpdb->signups (
3685
  $result = get_option('IWP_backup_status');
3686
  $job_id = $params['params']['backup_id'];
3687
  $job_data = $this->jobdata_getarray($job_id);
 
3688
  if ($result == '1') {
3689
- $cron_disable = false;
3690
  $cron_params = array();
3691
  if (( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON )) {
3692
  $cron_disable = true;
@@ -3923,6 +3927,11 @@ CREATE TABLE $wpdb->signups (
3923
  if (!empty($params['args']['exclude_extensions']) && !defined('IWP_EXCLUDE_EXTENSIONS')) {
3924
  define('IWP_EXCLUDE_EXTENSIONS', $params['args']['exclude_extensions']);
3925
  }
 
 
 
 
 
3926
  if (!empty($params['args']['IWP_encryptionphrase'])) {
3927
  IWP_MMB_Backup_Options::update_iwp_backup_option('IWP_encryptionphrase', $params['args']['IWP_encryptionphrase']);
3928
  }else{
@@ -4499,6 +4508,9 @@ CREATE TABLE $wpdb->signups (
4499
  $dropbox_destination .= '/'.$backup_instance->site_name;
4500
  }
4501
  $folders = explode('/',$dropbox_destination);
 
 
 
4502
  foreach ($folders as $key => $name) {
4503
  $path.=trim($name).'/';
4504
  }
@@ -4514,6 +4526,12 @@ CREATE TABLE $wpdb->signups (
4514
 
4515
  }elseif ($type == 's3') {
4516
  extract($args['iwp_amazon_s3']);
 
 
 
 
 
 
4517
  if (isset($as3_site_folder) && $as3_site_folder == true){
4518
  $destination .= '/'.$backup_instance->site_name;
4519
  }
@@ -4530,6 +4548,12 @@ CREATE TABLE $wpdb->signups (
4530
  require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/amazon/autoload.php');
4531
  }
4532
  $new_s3_obj = new IWP_MMB_S3_MULTICALL();
 
 
 
 
 
 
4533
  return $new_s3_obj->postUploadS3Verification($backup_file, $destFile, $type, $as3_bucket, $as3_access_key, $as3_secure_key, $as3_bucket_region, $size1, $size2, $return_size = true);
4534
  }
4535
  else{
@@ -4542,6 +4566,9 @@ CREATE TABLE $wpdb->signups (
4542
  if (isset($ftp_site_folder) && $ftp_site_folder == true){
4543
  $destination .= '/'.$backup_instance->site_name;
4544
  }
 
 
 
4545
  $folders = explode('/',$destination);
4546
  foreach ($folders as $key => $name) {
4547
  $path.=trim($name).'/';
@@ -4836,11 +4863,12 @@ CREATE TABLE $wpdb->signups (
4836
  }
4837
 
4838
  public function kill_new_backup($params){
 
4839
  $this->activejobs_delete($params['result_id']);
4840
  $backups = $this->get_backup_history();
4841
  $this->delete_backup_by_id($params['result_id']);
4842
  delete_option('IWP_jobdata_'.$params['result_id']);
4843
- delete_option('IWP_backup_status', '0');
4844
  delete_option('IWP_semaphore_fd');
4845
  delete_option('IWP_locked_fd');
4846
  delete_option('IWP_unlocked_fd');
439
  $quota_free = '';
440
  }
441
 
442
+ $disk_free_space = function_exists('disk_free_space') ? @disk_free_space($iwp_backup_dir) : false;
443
  # == rather than === here is deliberate; support experience shows that a result of (int)0 is not reliable. i.e. 0 can be returned when the real result should be false.
444
  if ($disk_free_space == false) {
445
  call_user_func($logging_function, "Free space on disk containing InfiniteWP's temporary directory: Unknown".$quota_free);
1435
  }
1436
 
1437
  public function backup_resume($resumption_no, $bnonce, $first_call = false) {
1438
+ global $iwp_mmb_core;
1439
 
1440
  set_error_handler(array($this, 'php_error'), E_ALL & ~E_STRICT);
1441
  if ($first_call) {
1555
  // Argh. In fact, this has limited effect, as apparently (at least on another install seen), the saving of the updated transient via jobdata_set() also took no effect. Still, it does not hurt.
1556
  if ($resumption_no >= 1 && 'finished' == $this->jobdata_get('jobstatus')) {
1557
  $this->log('Terminate: This backup job is already finished (1).');
1558
+ $iwp_mmb_core->iwp_delete_option('IWP_backup_status');
1559
  die;
1560
  } elseif ('backup' == $job_type && !empty($this->backup_is_already_complete)) {
1561
  $this->jobdata_set('jobstatus', 'finished');
1562
  $this->log('Terminate: This backup job is already finished (2).');
1563
+ $iwp_mmb_core->iwp_delete_option('IWP_backup_status');
1564
  die;
1565
  }
1566
 
2003
  // This procedure initiates a backup run
2004
  // $backup_files/$backup_database: true/false = yes/no (over-write allowed); 1/0 = yes/no (force)
2005
  public function boot_backup($backup_files, $backup_database, $restrict_files_to_override = false, $one_shot = false, $service = false, $options = array()) {
2006
+ global $iwp_mmb_core;
2007
 
2008
  @ignore_user_abort(true);
2009
  @set_time_limit(IWP_SET_TIME_LIMIT);
2012
  // Generate backup information
2013
  $use_nonce = (empty($options['use_nonce'])) ? false : $options['use_nonce'];
2014
  $this->backup_time_nonce($use_nonce);
2015
+ $iwp_mmb_core->iwp_update_option($option_name = 'IWP_running_backupID',$this->nonce);
2016
  // The current_resumption is consulted within logfile_open()
2017
  $this->current_resumption = 0;
2018
  $this->logfile_open($this->nonce);
2020
  if (!is_file($this->logfile_name)) {
2021
  $this->log('Failed to open log file ('.$this->logfile_name.') - the directory ('.$iwp_backup_dir.') for creating files in is not writable, or you ran out of disk space). Backup aborted.');
2022
  $this->log(__('Could not create files in the backup directory. Backup aborted','InfiniteWP'), 'error');
2023
+ $this->save_last_backup($our_files = array());
2024
+ $iwp_mmb_core->iwp_delete_option('IWP_running_backupID');
2025
  return false;
2026
  }
2027
 
2070
  if (!IWP_MMB_Backup_Options::get_iwp_backup_option('IWP_debug_mode') && !empty($this->logfile_name) && file_exists($this->logfile_name)) {
2071
  unlink($this->logfile_name);
2072
  }
2073
+ $iwp_mmb_core->iwp_delete_option('IWP_running_backupID');
2074
  return $ret;
2075
  }
2076
 
2078
  // doing_action() was added in WP 3.9
2079
  // wp_cron() can be called from the 'init' action
2080
 
2081
+ if (function_exists('doing_action') && (doing_action('init') || defined('DOING_CRON') && DOING_CRON) && (doing_action('IWP_backup_database') || doing_action('IWP_backup'))) {
2082
  $last_scheduled_action_called_at = get_option("IWP_last_scheduled_$semaphore");
2083
  // 11 minutes - so, we're assuming that they haven't custom-modified their schedules to run scheduled backups more often than that. If they have, they need also to use the filter to over-ride this check.
2084
  $seconds_ago = time() - $last_scheduled_action_called_at;
2085
  if ($last_scheduled_action_called_at && $seconds_ago < 660 && apply_filters('IWP_check_repeated_scheduled_backups', true)) {
2086
  $this->log(sprintf('Scheduled backup aborted - another backup of this type was apparently invoked by the WordPress scheduler only %d seconds ago - the WordPress scheduler invoking events multiple times usually indicates a very overloaded server (or other plugins that mis-use the scheduler)', $seconds_ago));
2087
+ $iwp_mmb_core->iwp_delete_option('IWP_running_backupID');
2088
  return;
2089
  }
2090
  }
2436
  }
2437
 
2438
  private function backup_finish($cancel_event, $do_cleanup, $allow_email, $resumption_no, $force_abort = false) {
2439
+ global $wpdb,$iwp_mmb_core;
2440
 
2441
  if (!empty($this->semaphore)) $this->semaphore->unlock();
2442
 
2512
  $this->log('The backup apparently succeeded and is now complete');
2513
  }
2514
  delete_option('IWP_jobdata_'.$this->nonce);
2515
+ $iwp_mmb_core->iwp_update_option($option_name = 'IWP_backup_status',$option_value = '0');
2516
  $GLOBALS['iwp_mmb_activities_log']->iwp_mmb_save_iwp_activities('backup', 'multiCallNow', 'direct', array('what' => $what), $userid);
2517
  } else {
2518
  $final_message = __('The backup apparently succeeded (with warnings) and is now complete','InfiniteWP');
2521
  }
2522
  $GLOBALS['iwp_mmb_activities_log']->iwp_mmb_save_iwp_activities('backup', 'multiCallNow', 'direct', array('what' => $what), $userid);
2523
  delete_option('IWP_jobdata_'.$this->nonce);
2524
+ $iwp_mmb_core->iwp_update_option($option_name = 'IWP_backup_status',$option_value = '0');
2525
  }
2526
  if ($remote_sent && !$force_abort) $final_message .= '. '.__('To complete your migration/clone, you should now log in to the remote site and restore the backup set.', 'InfiniteWP');
2527
  if ($do_cleanup) $delete_jobdata = apply_filters('IWP_backup_complete', $delete_jobdata);
2548
  // This is left until last for the benefit of the front-end UI, which then gets maximum chance to display the 'finished' status
2549
  if ($delete_jobdata) {
2550
  delete_option('IWP_jobdata_'.$this->nonce);
2551
+ $iwp_mmb_core->iwp_update_option($option_name = 'IWP_backup_status',$option_value = '0');
2552
  }
2553
 
2554
  }
2878
 
2879
  // Add backquotes to tables and db-names in SQL queries. Taken from phpMyAdmin.
2880
  public function backquote($a_name) {
2881
+ if (!empty($a_name) && '*' != $a_name) {
2882
  if (is_array($a_name)) {
2883
  $result = array();
2884
+ foreach ($a_name as $key => $val) {
 
2885
  $result[$key] = '`'.$val.'`';
2886
+ }
2887
  return $result;
2888
  } else {
2889
  return '`'.$a_name.'`';
3689
  $result = get_option('IWP_backup_status');
3690
  $job_id = $params['params']['backup_id'];
3691
  $job_data = $this->jobdata_getarray($job_id);
3692
+ $cron_disable = false;
3693
  if ($result == '1') {
 
3694
  $cron_params = array();
3695
  if (( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON )) {
3696
  $cron_disable = true;
3927
  if (!empty($params['args']['exclude_extensions']) && !defined('IWP_EXCLUDE_EXTENSIONS')) {
3928
  define('IWP_EXCLUDE_EXTENSIONS', $params['args']['exclude_extensions']);
3929
  }
3930
+ if (!empty($params['args']['exclude_file_size']) && !defined('IWP_SKIP_FILE_OVER_SIZE')) {
3931
+ $exclude_file_size = $params['args']['exclude_file_size'] * 1048576; // 10*1048576
3932
+ define('IWP_SKIP_FILE_OVER_SIZE',$exclude_file_size);
3933
+ }
3934
+
3935
  if (!empty($params['args']['IWP_encryptionphrase'])) {
3936
  IWP_MMB_Backup_Options::update_iwp_backup_option('IWP_encryptionphrase', $params['args']['IWP_encryptionphrase']);
3937
  }else{
4508
  $dropbox_destination .= '/'.$backup_instance->site_name;
4509
  }
4510
  $folders = explode('/',$dropbox_destination);
4511
+ if(!isset($path)){
4512
+ $path = '';
4513
+ }
4514
  foreach ($folders as $key => $name) {
4515
  $path.=trim($name).'/';
4516
  }
4526
 
4527
  }elseif ($type == 's3') {
4528
  extract($args['iwp_amazon_s3']);
4529
+ if(!isset($destination)){
4530
+ $destination = '';
4531
+ }
4532
+ if(!isset($path)){
4533
+ $path = '';
4534
+ }
4535
  if (isset($as3_site_folder) && $as3_site_folder == true){
4536
  $destination .= '/'.$backup_instance->site_name;
4537
  }
4548
  require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/amazon/autoload.php');
4549
  }
4550
  $new_s3_obj = new IWP_MMB_S3_MULTICALL();
4551
+ if(!isset($size1)){
4552
+ $size1 = 0;
4553
+ }
4554
+ if(!isset($size2)){
4555
+ $size2 = 0;
4556
+ }
4557
  return $new_s3_obj->postUploadS3Verification($backup_file, $destFile, $type, $as3_bucket, $as3_access_key, $as3_secure_key, $as3_bucket_region, $size1, $size2, $return_size = true);
4558
  }
4559
  else{
4566
  if (isset($ftp_site_folder) && $ftp_site_folder == true){
4567
  $destination .= '/'.$backup_instance->site_name;
4568
  }
4569
+ if(!isset($path)){
4570
+ $path = '';
4571
+ }
4572
  $folders = explode('/',$destination);
4573
  foreach ($folders as $key => $name) {
4574
  $path.=trim($name).'/';
4863
  }
4864
 
4865
  public function kill_new_backup($params){
4866
+ global $iwp_mmb_core;
4867
  $this->activejobs_delete($params['result_id']);
4868
  $backups = $this->get_backup_history();
4869
  $this->delete_backup_by_id($params['result_id']);
4870
  delete_option('IWP_jobdata_'.$params['result_id']);
4871
+ $iwp_mmb_core->iwp_delete_option('IWP_backup_status');
4872
  delete_option('IWP_semaphore_fd');
4873
  delete_option('IWP_locked_fd');
4874
  delete_option('IWP_unlocked_fd');
backup/backup.php CHANGED
@@ -94,7 +94,7 @@ class IWP_MMB_Backup {
94
  if ($this->binzip === 0 && (!defined('IWP_PREFERPCLZIP') || IWP_PREFERPCLZIP != true) && (!defined('IWP_NO_BINZIP') || !IWP_NO_BINZIP) && $iwp_backup_core->current_resumption <9) {
95
 
96
  if (@file_exists('/proc/user_beancounters') && @file_exists('/proc/meminfo') && @is_readable('/proc/meminfo')) {
97
- $meminfo = @file_get_contents('/proc/meminfo', false, null, -1, 200);
98
  if (is_string($meminfo) && preg_match('/MemTotal:\s+(\d+) kB/', $meminfo, $matches)) {
99
  $memory_mb = $matches[1]/1024;
100
  # If the report is of a large amount, then we're probably getting the total memory on the hypervisor (this has been observed), and don't really know the VPS's memory
@@ -1466,7 +1466,7 @@ class IWP_MMB_Backup {
1466
  if ($sind % 100 == 0) $iwp_backup_core->something_useful_happened();
1467
  }
1468
 
1469
- if (@constant("DB_CHARSET")) {
1470
  $this->stow("/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
1471
  }
1472
 
@@ -1850,7 +1850,7 @@ class IWP_MMB_Backup {
1850
 
1851
  $this->stow("# --------------------------------------------------------\n");
1852
 
1853
- if (@constant("DB_CHARSET")) {
1854
  $this->stow("/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\n");
1855
  $this->stow("/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\n");
1856
  $this->stow("/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\n");
@@ -1859,7 +1859,7 @@ class IWP_MMB_Backup {
1859
  $this->stow("/*!40101 SET foreign_key_checks = 0 */;\n\n");
1860
  }
1861
 
1862
- private function makezip_recursive_add($fullpath, $use_path_when_storing, $original_fullpath, $startlevels = 1, &$exclude) {
1863
 
1864
  // $zipfile = $this->zip_basename.(($this->index == 0) ? '' : ($this->index+1)).'.zip.tmp';
1865
 
@@ -2559,7 +2559,7 @@ class IWP_MMB_Backup {
2559
 
2560
  $fsize = filesize($file);
2561
 
2562
- if (@constant('IWP_SKIP_FILE_OVER_SIZE') && $fsize > IWP_SKIP_FILE_OVER_SIZE) {
2563
  $iwp_backup_core->log("File is larger than the user-configured (IWP_SKIP_FILE_OVER_SIZE) maximum (is: ".round($fsize/1024, 1)." KB); will skip: ".$add_as);
2564
  continue;
2565
  } elseif ($fsize > IWP_WARN_FILE_SIZE) {
94
  if ($this->binzip === 0 && (!defined('IWP_PREFERPCLZIP') || IWP_PREFERPCLZIP != true) && (!defined('IWP_NO_BINZIP') || !IWP_NO_BINZIP) && $iwp_backup_core->current_resumption <9) {
95
 
96
  if (@file_exists('/proc/user_beancounters') && @file_exists('/proc/meminfo') && @is_readable('/proc/meminfo')) {
97
+ $meminfo = @file_get_contents('/proc/meminfo', false, null, 0, 200);
98
  if (is_string($meminfo) && preg_match('/MemTotal:\s+(\d+) kB/', $meminfo, $matches)) {
99
  $memory_mb = $matches[1]/1024;
100
  # If the report is of a large amount, then we're probably getting the total memory on the hypervisor (this has been observed), and don't really know the VPS's memory
1466
  if ($sind % 100 == 0) $iwp_backup_core->something_useful_happened();
1467
  }
1468
 
1469
+ if (defined('DB_CHARSET') && DB_CHARSET) {
1470
  $this->stow("/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
1471
  }
1472
 
1850
 
1851
  $this->stow("# --------------------------------------------------------\n");
1852
 
1853
+ if (defined("DB_CHARSET") && DB_CHARSET) {
1854
  $this->stow("/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\n");
1855
  $this->stow("/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\n");
1856
  $this->stow("/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\n");
1859
  $this->stow("/*!40101 SET foreign_key_checks = 0 */;\n\n");
1860
  }
1861
 
1862
+ private function makezip_recursive_add($fullpath, $use_path_when_storing, $original_fullpath, $startlevels, &$exclude) {
1863
 
1864
  // $zipfile = $this->zip_basename.(($this->index == 0) ? '' : ($this->index+1)).'.zip.tmp';
1865
 
2559
 
2560
  $fsize = filesize($file);
2561
 
2562
+ if (defined('IWP_SKIP_FILE_OVER_SIZE') && $fsize > IWP_SKIP_FILE_OVER_SIZE) {
2563
  $iwp_backup_core->log("File is larger than the user-configured (IWP_SKIP_FILE_OVER_SIZE) maximum (is: ".round($fsize/1024, 1)." KB); will skip: ".$add_as);
2564
  continue;
2565
  } elseif ($fsize > IWP_WARN_FILE_SIZE) {
backup/class.semaphore.php CHANGED
@@ -31,7 +31,7 @@ class IWP_MMB_Semaphore {
31
  * @return bool
32
  */
33
  public function lock() {
34
- global $wpdb, $iwp_backup_core;
35
 
36
  // Attempt to set the lock
37
  $affected = $wpdb->query("
@@ -77,8 +77,8 @@ class IWP_MMB_Semaphore {
77
  $iwp_backup_core->log('Set semaphore last lock ('.$this->lock_name.') time to '.current_time('mysql', 1));
78
 
79
  $iwp_backup_core->log('Semaphore lock ('.$this->lock_name.') complete');
80
- update_option('IWP_backup_status', '1');
81
- delete_option('IWP_running_backupID');
82
  return true;
83
  }
84
 
31
  * @return bool
32
  */
33
  public function lock() {
34
+ global $wpdb, $iwp_backup_core,$iwp_mmb_core;
35
 
36
  // Attempt to set the lock
37
  $affected = $wpdb->query("
77
  $iwp_backup_core->log('Set semaphore last lock ('.$this->lock_name.') time to '.current_time('mysql', 1));
78
 
79
  $iwp_backup_core->log('Semaphore lock ('.$this->lock_name.') complete');
80
+ $iwp_mmb_core->iwp_update_option($option_name = 'IWP_backup_status',$option_value = '1');
81
+ $iwp_mmb_core->iwp_delete_option('IWP_running_backupID');
82
  return true;
83
  }
84
 
backup/functions.php CHANGED
@@ -93,7 +93,7 @@ if (!function_exists('iwp_mmb_build_mysqldump_list')) {
93
  $drive_string = implode(',', $directories);
94
  return $drive_string;
95
 
96
- } else return "/usr/bin/mysqldump,/bin/mysqldump,/usr/local/bin/mysqldump,/usr/sfw/bin/mysqldump,/usr/xdg4/bin/mysqldump,/opt/bin/mysqldump";
97
  }
98
  }
99
 
93
  $drive_string = implode(',', $directories);
94
  return $drive_string;
95
 
96
+ } else return "/usr/bin/mysqldump,/bin/mysqldump,/usr/local/bin/mysqldump,/usr/sfw/bin/mysqldump,/usr/xdg4/bin/mysqldump,/opt/bin/mysqldump,/usr/local/opt/mysql@5.7/bin/mysqldump";
97
  }
98
  }
99
 
backup/s3.php CHANGED
@@ -316,7 +316,7 @@ class IWP_MMB_UploadModule_s3 extends IWP_MMB_UploadModule {
316
  $orig_file_size = filesize($fullpath);
317
 
318
  if (!file_exists($fullpath)) {
319
- $iwp_backup_core->log("File not found: $file: $whoweare: ".$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile());
320
  $iwp_backup_core->log("$file: ".sprintf(__('Error: %s', 'InfiniteWP'), __('File not found', 'InfiniteWP')), 'error');
321
  continue;
322
  }
316
  $orig_file_size = filesize($fullpath);
317
 
318
  if (!file_exists($fullpath)) {
319
+ $iwp_backup_core->log("File not found: $file: $whoweare: ");
320
  $iwp_backup_core->log("$file: ".sprintf(__('Error: %s', 'InfiniteWP'), __('File not found', 'InfiniteWP')), 'error');
321
  continue;
322
  }
core.class.php CHANGED
@@ -1085,7 +1085,7 @@ EOF;
1085
  $auto_login = isset($_GET['auto_login']) ? $_GET['auto_login'] : 0;
1086
  $page = isset($_GET['page']) ? '?page='.$_GET['page'] : '';
1087
  $action = isset($_GET['action']) ? '?action='.$_GET['action'] : '';
1088
- $post = isset($_GET['action']) ? '&post='.$_GET['post'] : '';
1089
  $_SERVER['HTTP_REFERER']='';
1090
  if( !function_exists('is_user_logged_in') )
1091
  include_once( ABSPATH.'wp-includes/pluggable.php' );
@@ -1503,6 +1503,59 @@ EOF;
1503
  }
1504
  }
1505
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1506
 
1507
  }
1508
  ?>
1085
  $auto_login = isset($_GET['auto_login']) ? $_GET['auto_login'] : 0;
1086
  $page = isset($_GET['page']) ? '?page='.$_GET['page'] : '';
1087
  $action = isset($_GET['action']) ? '?action='.$_GET['action'] : '';
1088
+ $post = isset($_GET['post']) ? '&post='.$_GET['post'] : '';
1089
  $_SERVER['HTTP_REFERER']='';
1090
  if( !function_exists('is_user_logged_in') )
1091
  include_once( ABSPATH.'wp-includes/pluggable.php' );
1503
  }
1504
  }
1505
  }
1506
+
1507
+ function iwp_delete_option($option_name){
1508
+ if(!empty($option_name)){
1509
+ global $wpdb;
1510
+
1511
+ $delete_query = "DELETE FROM $wpdb->options WHERE option_name = '".$option_name."'";
1512
+ $affected = $wpdb->query($delete_query);
1513
+ if(!$affected){
1514
+ global $iwp_backup_core;
1515
+ $iwp_backup_core->log("Failed to delete $option_name option");
1516
+ $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
1517
+ $log = $bt[0]['file'].'-- line--'.$bt[0]['line'].'--function--'.$bt[0]['function'];
1518
+ $iwp_backup_core->log("$log");
1519
+ $iwp_backup_core->log("Retry delete $option_name option");
1520
+ // retry operation
1521
+ $query = "SELECT * FROM $wpdb->options WHERE option_name = '".$option_name."'";
1522
+ $temp_row = $wpdb->get_row($query);
1523
+ if(!empty($temp_row)){
1524
+ $wpdb->query($delete_query);
1525
+ }
1526
+ }
1527
+ }
1528
+ }
1529
+
1530
+ function iwp_update_option($option_name,$option_value){
1531
+ if(!empty($option_name)){
1532
+ global $wpdb;
1533
+ $sql = "INSERT INTO `$wpdb->options` (option_name,option_value) VALUES (%s,%s) ON DUPLICATE KEY UPDATE option_value = %s";
1534
+ $sql = $wpdb->prepare($sql,$option_name,$option_value,$option_value);
1535
+ $affected = $wpdb->query($sql);
1536
+ if(!$affected){
1537
+ global $iwp_backup_core;
1538
+ $iwp_backup_core->log("Failed to update $option_name option and value $option_value");
1539
+ $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
1540
+ $log = $bt[0]['file'].'-- line--'.$bt[0]['line'].'--function--'.$bt[0]['function'];
1541
+ $iwp_backup_core->log("$log");
1542
+ // retry operation
1543
+ $affected = $wpdb->query($sql);
1544
+ }
1545
+ }
1546
+ }
1547
+
1548
+ function get_max_allowed_packet(){
1549
+ global $wpdb;
1550
+ $query = "SHOW VARIABLES LIKE 'max_allowed_packet'";
1551
+ $temp_row = $wpdb->get_row($query);
1552
+ if(!empty($temp_row)){
1553
+ return $temp_row->Value; //1048576
1554
+ // $temp_row->Value/(1024*1024); // 1M
1555
+ }else{
1556
+ return '128M'; //Default 8M, so we tried with increase max_allowed_packet size
1557
+ }
1558
+ }
1559
 
1560
  }
1561
  ?>
debug-chart/src/fusioncharts.php CHANGED
@@ -20,7 +20,7 @@
20
  ';
21
 
22
  // constructor
23
- function __construct($type, $id, $width = 400, $height = 300, $renderAt, $dataFormat, $dataSource) {
24
  isset($type) ? $this->constructorOptions['type'] = $type : '';
25
  isset($id) ? $this->constructorOptions['id'] = $id : 'php-fc-'.time();
26
  isset($width) ? $this->constructorOptions['width'] = $width : '';
20
  ';
21
 
22
  // constructor
23
+ function __construct($type, $id, $width = 400, $height = 300, $renderAt = null, $dataFormat = null, $dataSource = null) {
24
  isset($type) ? $this->constructorOptions['type'] = $type : '';
25
  isset($id) ? $this->constructorOptions['id'] = $id : 'php-fc-'.time();
26
  isset($width) ? $this->constructorOptions['width'] = $width : '';
init.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: InfiniteWP - Client
4
  Plugin URI: http://infinitewp.com/
5
  Description: This is the client plugin of InfiniteWP that communicates with the InfiniteWP Admin panel.
6
  Author: Revmakx
7
- Version: 1.9.4.8.2
8
  Author URI: http://www.revmakx.com
9
  Network: true
10
  */
@@ -29,7 +29,7 @@ if(basename($_SERVER['SCRIPT_FILENAME']) == "init.php"):
29
  exit;
30
  endif;
31
  if(!defined('IWP_MMB_CLIENT_VERSION'))
32
- define('IWP_MMB_CLIENT_VERSION', '1.9.4.8.2');
33
 
34
 
35
 
@@ -143,12 +143,23 @@ if( !function_exists ('iwp_mmb_parse_request')) {
143
  if(isset($request_data['params'])){
144
  $request_data['params'] = iwp_mmb_filter_params($request_data['params']);
145
  }
 
 
 
 
 
 
 
 
 
 
 
146
  if (isset($GLOBALS['IWP_JSON_COMMUNICATION']) && $GLOBALS['IWP_JSON_COMMUNICATION']) {
147
  $signature = base64_decode($request_data['signature']);
148
  }else{
149
  $signature = $request_data['signature'];
150
  }
151
-
152
  $iwp_action = $request_data['iwp_action'];
153
  $params = $request_data['params'];
154
  $id = $request_data['id'];
@@ -161,11 +172,10 @@ if( !function_exists ('iwp_mmb_parse_request')) {
161
  if(!defined('IWP_AUTHORISED_CALL')) define('IWP_AUTHORISED_CALL', 1);
162
  if(function_exists('register_shutdown_function')){ register_shutdown_function("iwp_mmb_shutdown"); }
163
  $GLOBALS['IWP_MMB_PROFILING']['ACTION_START'] = microtime(1);
164
-
165
- error_reporting(0);
166
- @ini_set("display_errors", 0);
167
-
168
-
169
  run_hash_change_process();
170
  iwp_plugin_compatibility_fix();
171
  $action = $iwp_action;
@@ -177,12 +187,18 @@ if( !function_exists ('iwp_mmb_parse_request')) {
177
 
178
  if ($action == 'add_site') {
179
  $params['iwp_action'] = $action;
 
 
 
180
  $iwp_mmb_core->request_params = $params;
181
  return;
182
  }elseif ($action == 'readd_site') {
183
  $params['id'] = $id;
184
  $params['iwp_action'] = $action;
185
  $params['signature'] = $signature;
 
 
 
186
  $iwp_mmb_core->request_params = $params;
187
  return;
188
  }
@@ -211,6 +227,23 @@ if( !function_exists ('iwp_mmb_parse_request')) {
211
 
212
  }
213
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  if (!function_exists ('iwp_mmb_add_readd_request')) {
215
  function iwp_mmb_add_readd_request(){
216
  global $current_user, $iwp_mmb_core, $new_actions, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache, $iwp_mmb_activities_log;
@@ -221,14 +254,12 @@ if (!function_exists ('iwp_mmb_add_readd_request')) {
221
  $action = $iwp_mmb_core->request_params['iwp_action'];
222
 
223
  if ($action == 'add_site') {
224
- $params['is_save_activity_log'] = $is_save_activity_log;
225
  iwp_mmb_add_site($params);
226
  iwp_mmb_response(array('error' => 'You should never see this.', 'error_code' => 'you_should_never_see_this'), false);
227
  }
228
  if ($action == 'readd_site') {
229
  $params['id'] = $params['id'];
230
  $params['signature'] = $params['signature'];
231
- $params['is_save_activity_log'] = $is_save_activity_log;
232
  iwp_mmb_readd_site($params);
233
  iwp_mmb_response(array('error' => 'You should never see this.', 'error_code' => 'you_should_never_see_this'), false);
234
  }
@@ -253,7 +284,9 @@ if (!function_exists ('iwp_mmb_set_request')) {
253
  iwp_mmb_maintain_site($params);
254
  iwp_mmb_response(array('error' => 'You should never see this.', 'error_code' => 'you_should_never_see_this'), false);
255
  }
256
- @ignore_user_abort(true);
 
 
257
  $GLOBALS['IWP_CLIENT_HISTORY_ID'] = $iwp_mmb_core->request_params['id'];
258
  iwp_mmb_backup_db_changes();
259
  if(isset($params['username']) && !is_user_logged_in()){
@@ -295,6 +328,8 @@ if (!function_exists ('iwp_mmb_set_request')) {
295
  }
296
  elseif(isset($params['secure']['account_info'])){
297
  $params['account_info'] = $params['secure']['account_info'];
 
 
298
  }
299
  }
300
 
@@ -451,11 +486,11 @@ if( !function_exists ( 'iwp_mmb_add_site' )) {
451
  $iwp_mmb_core->set_client_message_id($id);
452
  $iwp_mmb_core->set_admin_panel_public_key($public_key);
453
  $iwp_mmb_core->get_stats_instance();
454
- if(is_array($notifications) && !empty($notifications)){
455
  $iwp_mmb_core->stats_instance->set_notifications($notifications);
456
  }
457
 
458
- if(is_array($brand) && !empty($brand)){
459
  update_option('iwp_client_brand',$brand);
460
  }
461
  $iwp_mmb_activities_log->iwp_mmb_update_is_save_activity_log($params['is_save_activity_log']);
@@ -517,11 +552,11 @@ if( !function_exists ( 'iwp_mmb_readd_site' )) {
517
  $iwp_mmb_core->set_client_message_id($id);
518
  $iwp_mmb_core->set_admin_panel_public_key($public_key);
519
  $iwp_mmb_core->get_stats_instance();
520
- if(is_array($notifications) && !empty($notifications)){
521
  $iwp_mmb_core->stats_instance->set_notifications($notifications);
522
  }
523
 
524
- if(is_array($brand) && !empty($brand)){
525
  update_option('iwp_client_brand',$brand);
526
  }
527
  $iwp_mmb_activities_log->iwp_mmb_update_is_save_activity_log($params['is_save_activity_log']);
@@ -1837,7 +1872,7 @@ if( !function_exists('iwp_mmb_get_all_links')){
1837
  function iwp_mmb_get_all_links(){
1838
  global $iwp_mmb_core;
1839
  $iwp_mmb_core->wp_blc_get_blinks();
1840
- $return = $iwp_mmb_core->blc_get_blinks->blc_get_all_links($params);
1841
  if (is_array($return) && array_key_exists('error', $return))
1842
  iwp_mmb_response($return, false);
1843
  else {
@@ -2127,14 +2162,23 @@ if(!function_exists('checkOpenSSL')){
2127
  else{
2128
  //$ossl_err = @openssl_error_string();if($ossl_err!=false) return false;
2129
  $key = @openssl_pkey_new();
 
 
 
2130
 
2131
- //$ossl_err = @openssl_error_string();if($ossl_err!=false) return false;
2132
- @openssl_pkey_export($key, $privateKey);
 
 
 
2133
  $privateKey = base64_encode($privateKey);
2134
 
2135
- //$ossl_err = @openssl_error_string();if($ossl_err!=false) return false;
2136
  $publicKey = @openssl_pkey_get_details($key);
2137
-
 
 
 
2138
  //$ossl_err = @openssl_error_string();if($ossl_err!=false) return false;
2139
  $publicKey = $publicKey["key"];
2140
 
@@ -2142,7 +2186,7 @@ if(!function_exists('checkOpenSSL')){
2142
  return false;
2143
  }
2144
  $filename = getenv('HOME') . '/.rnd';
2145
- if (file_exists($filename)) {
2146
  @unlink($filename);
2147
  }
2148
  }
@@ -2186,7 +2230,9 @@ if(!function_exists('iwp_mmb_print_flush')){
2186
 
2187
  echo $print_string." ||| ";
2188
  echo "TT:".(microtime(1) - $GLOBALS['IWP_MMB_PROFILING']['ACTION_START'])."\n";
2189
- ob_flush();
 
 
2190
  flush();
2191
  }
2192
  }
@@ -2196,11 +2242,11 @@ if(!function_exists('iwp_mmb_auto_print')){
2196
  $print_every_x_secs = 5;
2197
 
2198
  $current_time = microtime(1);
2199
- if(!$GLOBALS['IWP_MMB_PROFILING']['TASKS'][$unique_task]['START']){
2200
  $GLOBALS['IWP_MMB_PROFILING']['TASKS'][$unique_task]['START'] = $current_time;
2201
  }
2202
 
2203
- if(!$GLOBALS['IWP_MMB_PROFILING']['LAST_PRINT'] || ($current_time - $GLOBALS['IWP_MMB_PROFILING']['LAST_PRINT']) > $print_every_x_secs){
2204
 
2205
  //$print_string = "TT:".($current_time - $GLOBALS['IWP_MMB_PROFILING']['ACTION_START'])."\n";
2206
  $print_string = $unique_task." TT:".($current_time - $GLOBALS['IWP_MMB_PROFILING']['TASKS'][$unique_task]['START']);
@@ -2498,7 +2544,14 @@ if(!function_exists('iwp_mmb_get_file_size')){
2498
  function iwp_mmb_get_file_size($file)
2499
  {
2500
  clearstatcache();
2501
- $normal_file_size = filesize($file);
 
 
 
 
 
 
 
2502
  if(($normal_file_size !== false)&&($normal_file_size >= 0))
2503
  {
2504
  return $normal_file_size;
4
  Plugin URI: http://infinitewp.com/
5
  Description: This is the client plugin of InfiniteWP that communicates with the InfiniteWP Admin panel.
6
  Author: Revmakx
7
+ Version: 1.9.4.11
8
  Author URI: http://www.revmakx.com
9
  Network: true
10
  */
29
  exit;
30
  endif;
31
  if(!defined('IWP_MMB_CLIENT_VERSION'))
32
+ define('IWP_MMB_CLIENT_VERSION', '1.9.4.11');
33
 
34
 
35
 
143
  if(isset($request_data['params'])){
144
  $request_data['params'] = iwp_mmb_filter_params($request_data['params']);
145
  }
146
+ $defaults = array(
147
+ 'id' => NULL,
148
+ 'activities_log_datetime' =>NULL,
149
+ 'is_save_activity_log' =>FALSE,
150
+ 'signature' => NULL,
151
+ 'params' => array(
152
+ 'numberOfRevisions' => '0'
153
+ ),
154
+ );
155
+ $request_data = iwp_recursive_parse_args( $request_data, $defaults );
156
+
157
  if (isset($GLOBALS['IWP_JSON_COMMUNICATION']) && $GLOBALS['IWP_JSON_COMMUNICATION']) {
158
  $signature = base64_decode($request_data['signature']);
159
  }else{
160
  $signature = $request_data['signature'];
161
  }
162
+
163
  $iwp_action = $request_data['iwp_action'];
164
  $params = $request_data['params'];
165
  $id = $request_data['id'];
172
  if(!defined('IWP_AUTHORISED_CALL')) define('IWP_AUTHORISED_CALL', 1);
173
  if(function_exists('register_shutdown_function')){ register_shutdown_function("iwp_mmb_shutdown"); }
174
  $GLOBALS['IWP_MMB_PROFILING']['ACTION_START'] = microtime(1);
175
+ if(!defined('IWP_DEBUG_MODE')){
176
+ error_reporting(0);
177
+ @ini_set("display_errors", 0);
178
+ }
 
179
  run_hash_change_process();
180
  iwp_plugin_compatibility_fix();
181
  $action = $iwp_action;
187
 
188
  if ($action == 'add_site') {
189
  $params['iwp_action'] = $action;
190
+ if(empty($params['is_save_activity_log'])) {
191
+ $params['is_save_activity_log'] = false;
192
+ }
193
  $iwp_mmb_core->request_params = $params;
194
  return;
195
  }elseif ($action == 'readd_site') {
196
  $params['id'] = $id;
197
  $params['iwp_action'] = $action;
198
  $params['signature'] = $signature;
199
+ if(empty($params['is_save_activity_log'])) {
200
+ $params['is_save_activity_log'] = false;
201
+ }
202
  $iwp_mmb_core->request_params = $params;
203
  return;
204
  }
227
 
228
  }
229
  }
230
+ if ( ! function_exists( 'iwp_recursive_parse_args' ) ) {
231
+ function iwp_recursive_parse_args( $args, $defaults ) {
232
+ $new_args = (array) $defaults;
233
+
234
+ foreach ( $args as $key => $value ) {
235
+ if ( is_array( $value ) && isset( $new_args[ $key ] ) ) {
236
+ $new_args[ $key ] = iwp_recursive_parse_args( $value, $new_args[ $key ] );
237
+ }
238
+ else {
239
+ $new_args[ $key ] = $value;
240
+ }
241
+ }
242
+
243
+ return $new_args;
244
+ }
245
+ }
246
+
247
  if (!function_exists ('iwp_mmb_add_readd_request')) {
248
  function iwp_mmb_add_readd_request(){
249
  global $current_user, $iwp_mmb_core, $new_actions, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache, $iwp_mmb_activities_log;
254
  $action = $iwp_mmb_core->request_params['iwp_action'];
255
 
256
  if ($action == 'add_site') {
 
257
  iwp_mmb_add_site($params);
258
  iwp_mmb_response(array('error' => 'You should never see this.', 'error_code' => 'you_should_never_see_this'), false);
259
  }
260
  if ($action == 'readd_site') {
261
  $params['id'] = $params['id'];
262
  $params['signature'] = $params['signature'];
 
263
  iwp_mmb_readd_site($params);
264
  iwp_mmb_response(array('error' => 'You should never see this.', 'error_code' => 'you_should_never_see_this'), false);
265
  }
284
  iwp_mmb_maintain_site($params);
285
  iwp_mmb_response(array('error' => 'You should never see this.', 'error_code' => 'you_should_never_see_this'), false);
286
  }
287
+ if(!defined('IWP_DEBUG_MODE')){
288
+ @ignore_user_abort(true);
289
+ }
290
  $GLOBALS['IWP_CLIENT_HISTORY_ID'] = $iwp_mmb_core->request_params['id'];
291
  iwp_mmb_backup_db_changes();
292
  if(isset($params['username']) && !is_user_logged_in()){
328
  }
329
  elseif(isset($params['secure']['account_info'])){
330
  $params['account_info'] = $params['secure']['account_info'];
331
+ }elseif(empty($params['secure']['account_info'])){
332
+ $params['account_info'] = NULL;
333
  }
334
  }
335
 
486
  $iwp_mmb_core->set_client_message_id($id);
487
  $iwp_mmb_core->set_admin_panel_public_key($public_key);
488
  $iwp_mmb_core->get_stats_instance();
489
+ if(isset($notifications) && is_array($notifications) && !empty($notifications)){
490
  $iwp_mmb_core->stats_instance->set_notifications($notifications);
491
  }
492
 
493
+ if(isset($brand) && is_array($brand) && !empty($brand)){
494
  update_option('iwp_client_brand',$brand);
495
  }
496
  $iwp_mmb_activities_log->iwp_mmb_update_is_save_activity_log($params['is_save_activity_log']);
552
  $iwp_mmb_core->set_client_message_id($id);
553
  $iwp_mmb_core->set_admin_panel_public_key($public_key);
554
  $iwp_mmb_core->get_stats_instance();
555
+ if(isset($notifications) && is_array($notifications) && !empty($notifications)){
556
  $iwp_mmb_core->stats_instance->set_notifications($notifications);
557
  }
558
 
559
+ if(isset($brand) && is_array($brand) && !empty($brand)){
560
  update_option('iwp_client_brand',$brand);
561
  }
562
  $iwp_mmb_activities_log->iwp_mmb_update_is_save_activity_log($params['is_save_activity_log']);
1872
  function iwp_mmb_get_all_links(){
1873
  global $iwp_mmb_core;
1874
  $iwp_mmb_core->wp_blc_get_blinks();
1875
+ $return = $iwp_mmb_core->blc_get_blinks->blc_get_all_links();
1876
  if (is_array($return) && array_key_exists('error', $return))
1877
  iwp_mmb_response($return, false);
1878
  else {
2162
  else{
2163
  //$ossl_err = @openssl_error_string();if($ossl_err!=false) return false;
2164
  $key = @openssl_pkey_new();
2165
+ if($key === false){
2166
+ return false;
2167
+ }
2168
 
2169
+ // $ossl_err = @openssl_error_string();if($ossl_err!=false) return false;
2170
+ $pkey = @openssl_pkey_export($key, $privateKey);
2171
+ if($pkey === false){
2172
+ return false;
2173
+ }
2174
  $privateKey = base64_encode($privateKey);
2175
 
2176
+ // $ossl_err = @openssl_error_string();if($ossl_err!=false) return false;
2177
  $publicKey = @openssl_pkey_get_details($key);
2178
+ if($publicKey === false){
2179
+ return false;
2180
+ }
2181
+
2182
  //$ossl_err = @openssl_error_string();if($ossl_err!=false) return false;
2183
  $publicKey = $publicKey["key"];
2184
 
2186
  return false;
2187
  }
2188
  $filename = getenv('HOME') . '/.rnd';
2189
+ if (@file_exists($filename)) {
2190
  @unlink($filename);
2191
  }
2192
  }
2230
 
2231
  echo $print_string." ||| ";
2232
  echo "TT:".(microtime(1) - $GLOBALS['IWP_MMB_PROFILING']['ACTION_START'])."\n";
2233
+ if (ob_get_length()){
2234
+ @ob_flush();
2235
+ }
2236
  flush();
2237
  }
2238
  }
2242
  $print_every_x_secs = 5;
2243
 
2244
  $current_time = microtime(1);
2245
+ if(empty($GLOBALS['IWP_MMB_PROFILING']['TASKS'][$unique_task]['START'])){
2246
  $GLOBALS['IWP_MMB_PROFILING']['TASKS'][$unique_task]['START'] = $current_time;
2247
  }
2248
 
2249
+ if(empty($GLOBALS['IWP_MMB_PROFILING']['LAST_PRINT']) || ($current_time - $GLOBALS['IWP_MMB_PROFILING']['LAST_PRINT']) > $print_every_x_secs){
2250
 
2251
  //$print_string = "TT:".($current_time - $GLOBALS['IWP_MMB_PROFILING']['ACTION_START'])."\n";
2252
  $print_string = $unique_task." TT:".($current_time - $GLOBALS['IWP_MMB_PROFILING']['TASKS'][$unique_task]['START']);
2544
  function iwp_mmb_get_file_size($file)
2545
  {
2546
  clearstatcache();
2547
+ if(!empty($file) && is_array($file)){
2548
+ // it will work on multipart mechanisam
2549
+ $key = key($file);
2550
+ $normal_file_size = filesize($file[$key]);
2551
+ }else{
2552
+ $normal_file_size = filesize($file);
2553
+ }
2554
+
2555
  if(($normal_file_size !== false)&&($normal_file_size >= 0))
2556
  {
2557
  return $normal_file_size;
installer.class.php CHANGED
@@ -532,7 +532,7 @@ class IWP_MMB_Installer extends IWP_MMB_Core
532
  }
533
  }
534
 
535
- function upgrade_plugins($plugins = false,$plugin_details = false,$userid)
536
  {
537
  global $iwp_activities_log_post_type, $iwp_mmb_activities_log;
538
  if (!$plugins || empty($plugins))
@@ -635,7 +635,7 @@ class IWP_MMB_Installer extends IWP_MMB_Core
635
  }
636
  }
637
 
638
- function upgrade_themes($themes = false,$theme_details = false,$userid)
639
  {
640
  global $iwp_activities_log_post_type, $iwp_mmb_activities_log;
641
  if (!$themes || empty($themes))
@@ -701,7 +701,7 @@ class IWP_MMB_Installer extends IWP_MMB_Core
701
  }
702
  }
703
 
704
- function upgrade_premium($premium = false,$premium_plugin_details = false,$premium_theme_details = false,$userid)
705
  {
706
  global $iwp_mmb_plugin_url;
707
 
532
  }
533
  }
534
 
535
+ function upgrade_plugins($plugins = false,$plugin_details = false,$userid = false)
536
  {
537
  global $iwp_activities_log_post_type, $iwp_mmb_activities_log;
538
  if (!$plugins || empty($plugins))
635
  }
636
  }
637
 
638
+ function upgrade_themes($themes = false,$theme_details = false,$userid = false)
639
  {
640
  global $iwp_activities_log_post_type, $iwp_mmb_activities_log;
641
  if (!$themes || empty($themes))
701
  }
702
  }
703
 
704
+ function upgrade_premium($premium = false,$premium_plugin_details = false,$premium_theme_details = false,$userid = false)
705
  {
706
  global $iwp_mmb_plugin_url;
707
 
iwp-file-iterator.php CHANGED
@@ -409,7 +409,12 @@ function IWP_is_dir($good_path){
409
 
410
  function skip_file($file){
411
  global $iwp_v_options, $archive;
412
- $exclude_data = $iwp_v_options[IWP_PCLZIP_OPT_IWP_EXCLUDE];
 
 
 
 
 
413
  if(!is_readable($file)){
414
  return true;
415
  }
409
 
410
  function skip_file($file){
411
  global $iwp_v_options, $archive;
412
+ if(!empty($iwp_v_options[IWP_PCLZIP_OPT_IWP_EXCLUDE])){
413
+ $exclude_data = $iwp_v_options[IWP_PCLZIP_OPT_IWP_EXCLUDE];
414
+ }else{
415
+ $exclude_data = array();
416
+ }
417
+
418
  if(!is_readable($file)){
419
  return true;
420
  }
lib/Dropbox2/OAuth/Storage/WordPress.php CHANGED
@@ -40,7 +40,7 @@ class Dropbox_WordPress implements Dropbox_StorageInterface
40
  * Check if an instance of the encrypter is passed, set the encryption object
41
  * @return void
42
  */
43
- public function __construct(Dropbox_Encrypter $encrypter = null, $option_name_prefix = 'dropbox_token', $option_array = 'dropbox', $backup_module_object)
44
  {
45
  if ($encrypter instanceof Dropbox_Encrypter) {
46
  $this->encrypter = $encrypter;
40
  * Check if an instance of the encrypter is passed, set the encryption object
41
  * @return void
42
  */
43
+ public function __construct(Dropbox_Encrypter $encrypter = null, $option_name_prefix = 'dropbox_token', $option_array = 'dropbox', $backup_module_object = null)
44
  {
45
  if ($encrypter instanceof Dropbox_Encrypter) {
46
  $this->encrypter = $encrypter;
lib/Google/Http/REST.php CHANGED
@@ -131,7 +131,7 @@ class IWP_google_Http_REST
131
  }
132
 
133
  if (count($queryVars)) {
134
- $requestUrl .= '?' . implode($queryVars, '&');
135
  }
136
 
137
  return $requestUrl;
131
  }
132
 
133
  if (count($queryVars)) {
134
+ $requestUrl .= '?' . implode('&', $queryVars);
135
  }
136
 
137
  return $requestUrl;
lib/Google/Utils.php CHANGED
@@ -64,7 +64,7 @@ class IWP_google_Utils
64
  $strlenVar = strlen($str);
65
  $d = $ret = 0;
66
  for ($count = 0; $count < $strlenVar; ++ $count) {
67
- $ordinalValue = ord($str{$ret});
68
  switch (true) {
69
  case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
70
  // characters U-00000000 - U-0000007F (same as ASCII)
64
  $strlenVar = strlen($str);
65
  $d = $ret = 0;
66
  for ($count = 0; $count < $strlenVar; ++ $count) {
67
+ $ordinalValue = ord($str[$ret]);
68
  switch (true) {
69
  case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
70
  // characters U-00000000 - U-0000007F (same as ASCII)
lib/Google2/Http/REST.php CHANGED
@@ -171,7 +171,7 @@ class Google_Http_REST
171
  }
172
 
173
  if (count($queryVars)) {
174
- $requestUrl .= '?' . implode($queryVars, '&');
175
  }
176
 
177
  return $requestUrl;
171
  }
172
 
173
  if (count($queryVars)) {
174
+ $requestUrl .= '?' . implode('&', $queryVars);
175
  }
176
 
177
  return $requestUrl;
lib/Google2/Utils.php CHANGED
@@ -62,7 +62,7 @@ class Google_Utils
62
  $strlenVar = strlen($str);
63
  $d = $ret = 0;
64
  for ($count = 0; $count < $strlenVar; ++ $count) {
65
- $ordinalValue = ord($str{$ret});
66
  switch (true) {
67
  case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
68
  // characters U-00000000 - U-0000007F (same as ASCII)
62
  $strlenVar = strlen($str);
63
  $d = $ret = 0;
64
  for ($count = 0; $count < $strlenVar; ++ $count) {
65
+ $ordinalValue = ord($str[$ret]);
66
  switch (true) {
67
  case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
68
  // characters U-00000000 - U-0000007F (same as ASCII)
lib/S3.php CHANGED
@@ -2258,7 +2258,7 @@ final class IWP_MMB_S3Request
2258
  elseif (strtolower($header) == 'content-type')
2259
  $this->response->headers['type'] = $value;
2260
  elseif (strtolower($header) == 'etag')
2261
- $this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
2262
  elseif (preg_match('/^x-amz-meta-.*$/i', $header))
2263
  $this->response->headers[strtolower($header)] = $value;
2264
  }
2258
  elseif (strtolower($header) == 'content-type')
2259
  $this->response->headers['type'] = $value;
2260
  elseif (strtolower($header) == 'etag')
2261
+ $this->response->headers['hash'] = $value[0] == '"' ? substr($value, 1, -1) : $value;
2262
  elseif (preg_match('/^x-amz-meta-.*$/i', $header))
2263
  $this->response->headers[strtolower($header)] = $value;
2264
  }
lib/amazon/autoload.php CHANGED
@@ -2,6 +2,6 @@
2
 
3
  // autoload.php @generated by Composer
4
 
5
- require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInitc0e9593f4594291c0bfbb43cf84f3f53::getLoader();
2
 
3
  // autoload.php @generated by Composer
4
 
5
+ require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInita18f93306907d0e5d733e09482ad91d6::getLoader();
lib/amazon/aws/aws-sdk-php/LICENSE.md ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Apache License
2
+ Version 2.0, January 2004
3
+
4
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
5
+
6
+ ## 1. Definitions.
7
+
8
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1
9
+ through 9 of this document.
10
+
11
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the
12
+ License.
13
+
14
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled
15
+ by, or are under common control with that entity. For the purposes of this definition, "control" means
16
+ (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract
17
+ or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial
18
+ ownership of such entity.
19
+
20
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
21
+
22
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software
23
+ source code, documentation source, and configuration files.
24
+
25
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form,
26
+ including but not limited to compiled object code, generated documentation, and conversions to other media
27
+ types.
28
+
29
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License,
30
+ as indicated by a copyright notice that is included in or attached to the work (an example is provided in the
31
+ Appendix below).
32
+
33
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from)
34
+ the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent,
35
+ as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not
36
+ include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work
37
+ and Derivative Works thereof.
38
+
39
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any
40
+ modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to
41
+ Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to
42
+ submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of
43
+ electronic, verbal, or written communication sent to the Licensor or its representatives, including but not
44
+ limited to communication on electronic mailing lists, source code control systems, and issue tracking systems
45
+ that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but
46
+ excluding communication that is conspicuously marked or otherwise designated in writing by the copyright
47
+ owner as "Not a Contribution."
48
+
49
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been
50
+ received by Licensor and subsequently incorporated within the Work.
51
+
52
+ ## 2. Grant of Copyright License.
53
+
54
+ Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,
55
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
56
+ Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such
57
+ Derivative Works in Source or Object form.
58
+
59
+ ## 3. Grant of Patent License.
60
+
61
+ Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,
62
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent
63
+ license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such
64
+ license applies only to those patent claims licensable by such Contributor that are necessarily infringed by
65
+ their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such
66
+ Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim
67
+ or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work
68
+ constitutes direct or contributory patent infringement, then any patent licenses granted to You under this
69
+ License for that Work shall terminate as of the date such litigation is filed.
70
+
71
+ ## 4. Redistribution.
72
+
73
+ You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without
74
+ modifications, and in Source or Object form, provided that You meet the following conditions:
75
+
76
+ 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
77
+
78
+ 2. You must cause any modified files to carry prominent notices stating that You changed the files; and
79
+
80
+ 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent,
81
+ trademark, and attribution notices from the Source form of the Work, excluding those notices that do
82
+ not pertain to any part of the Derivative Works; and
83
+
84
+ 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that
85
+ You distribute must include a readable copy of the attribution notices contained within such NOTICE
86
+ file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one
87
+ of the following places: within a NOTICE text file distributed as part of the Derivative Works; within
88
+ the Source form or documentation, if provided along with the Derivative Works; or, within a display
89
+ generated by the Derivative Works, if and wherever such third-party notices normally appear. The
90
+ contents of the NOTICE file are for informational purposes only and do not modify the License. You may
91
+ add Your own attribution notices within Derivative Works that You distribute, alongside or as an
92
+ addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be
93
+ construed as modifying the License.
94
+
95
+ You may add Your own copyright statement to Your modifications and may provide additional or different license
96
+ terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative
97
+ Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the
98
+ conditions stated in this License.
99
+
100
+ ## 5. Submission of Contributions.
101
+
102
+ Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by
103
+ You to the Licensor shall be under the terms and conditions of this License, without any additional terms or
104
+ conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate
105
+ license agreement you may have executed with Licensor regarding such Contributions.
106
+
107
+ ## 6. Trademarks.
108
+
109
+ This License does not grant permission to use the trade names, trademarks, service marks, or product names of
110
+ the Licensor, except as required for reasonable and customary use in describing the origin of the Work and
111
+ reproducing the content of the NOTICE file.
112
+
113
+ ## 7. Disclaimer of Warranty.
114
+
115
+ Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor
116
+ provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
117
+ or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
118
+ MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the
119
+ appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of
120
+ permissions under this License.
121
+
122
+ ## 8. Limitation of Liability.
123
+
124
+ In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless
125
+ required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any
126
+ Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential
127
+ damages of any character arising as a result of this License or out of the use or inability to use the Work
128
+ (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or
129
+ any and all other commercial damages or losses), even if such Contributor has been advised of the possibility
130
+ of such damages.
131
+
132
+ ## 9. Accepting Warranty or Additional Liability.
133
+
134
+ While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for,
135
+ acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this
136
+ License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole
137
+ responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold
138
+ each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason
139
+ of your accepting any such warranty or additional liability.
140
+
141
+ END OF TERMS AND CONDITIONS
lib/amazon/aws/aws-sdk-php/NOTICE.md ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AWS SDK for PHP
2
+
3
+ <http://aws.amazon.com/php>
4
+
5
+ Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License").
8
+ You may not use this file except in compliance with the License.
9
+ A copy of the License is located at
10
+
11
+ <http://aws.amazon.com/apache2.0>
12
+
13
+ or in the "license" file accompanying this file. This file is distributed
14
+ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
15
+ express or implied. See the License for the specific language governing
16
+ permissions and limitations under the License.
17
+
18
+ # Guzzle
19
+
20
+ <https://github.com/guzzle/guzzle>
21
+
22
+ Copyright (c) 2011 Michael Dowling, https://github.com/mtdowling
23
+
24
+ Permission is hereby granted, free of charge, to any person obtaining a copy
25
+ of this software and associated documentation files (the "Software"), to deal
26
+ in the Software without restriction, including without limitation the rights
27
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28
+ copies of the Software, and to permit persons to whom the Software is
29
+ furnished to do so, subject to the following conditions:
30
+
31
+ The above copyright notice and this permission notice shall be included in
32
+ all copies or substantial portions of the Software.
33
+
34
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40
+ THE SOFTWARE.
41
+
42
+ # Symfony
43
+
44
+ <https://github.com/symfony/symfony>
45
+
46
+ Copyright (c) 2004-2012 Fabien Potencier
47
+
48
+ Permission is hereby granted, free of charge, to any person obtaining a copy
49
+ of this software and associated documentation files (the "Software"), to deal
50
+ in the Software without restriction, including without limitation the rights
51
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
52
+ copies of the Software, and to permit persons to whom the Software is furnished
53
+ to do so, subject to the following conditions:
54
+
55
+ The above copyright notice and this permission notice shall be included in all
56
+ copies or substantial portions of the Software.
57
+
58
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64
+ THE SOFTWARE.
65
+
66
+ # Doctrine Common
67
+
68
+ <https://github.com/doctrine/common>
69
+
70
+ Copyright (c) 2006-2012 Doctrine Project
71
+
72
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
73
+ this software and associated documentation files (the "Software"), to deal in
74
+ the Software without restriction, including without limitation the rights to
75
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
76
+ of the Software, and to permit persons to whom the Software is furnished to do
77
+ so, subject to the following conditions:
78
+
79
+ The above copyright notice and this permission notice shall be included in all
80
+ copies or substantial portions of the Software.
81
+
82
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
83
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
84
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
85
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
86
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
87
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
88
+ SOFTWARE.
89
+
90
+ # Monolog
91
+
92
+ <https://github.com/Seldaek/monolog>
93
+
94
+ Copyright (c) Jordi Boggiano
95
+
96
+ Permission is hereby granted, free of charge, to any person obtaining a copy
97
+ of this software and associated documentation files (the "Software"), to deal
98
+ in the Software without restriction, including without limitation the rights
99
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
100
+ copies of the Software, and to permit persons to whom the Software is furnished
101
+ to do so, subject to the following conditions:
102
+
103
+ The above copyright notice and this permission notice shall be included in all
104
+ copies or substantial portions of the Software.
105
+
106
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
107
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
108
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
109
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
110
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
111
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
112
+ THE SOFTWARE.
lib/amazon/aws/aws-sdk-php/composer.json ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "aws/aws-sdk-php",
3
+ "homepage": "http://aws.amazon.com/sdkforphp",
4
+ "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
5
+ "keywords": ["aws","amazon","sdk","s3","ec2","dynamodb","cloud","glacier"],
6
+ "type": "library",
7
+ "license": "Apache-2.0",
8
+ "authors": [
9
+ {
10
+ "name": "Amazon Web Services",
11
+ "homepage": "http://aws.amazon.com"
12
+ }
13
+ ],
14
+ "support": {
15
+ "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
16
+ "issues": "https://github.com/aws/aws-sdk-php/issues"
17
+ },
18
+ "require": {
19
+ "php": ">=5.3.3",
20
+ "guzzle/guzzle": "~3.7"
21
+ },
22
+ "suggest": {
23
+ "doctrine/cache": "Adds support for caching of credentials and responses",
24
+ "ext-apc": "Allows service description opcode caching, request and response caching, and credentials caching",
25
+ "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages",
26
+ "monolog/monolog": "Adds support for logging HTTP requests and responses",
27
+ "symfony/yaml": "Eases the ability to write manifests for creating jobs in AWS Import/Export"
28
+ },
29
+ "require-dev": {
30
+ "ext-openssl": "*",
31
+ "doctrine/cache": "~1.0",
32
+ "monolog/monolog": "~1.4",
33
+ "phpunit/phpunit": "~4.0",
34
+ "phpunit/phpunit-mock-objects": "2.3.1",
35
+ "symfony/yaml": "~2.1"
36
+ },
37
+ "autoload": {
38
+ "psr-0": {
39
+ "Aws": "src/"
40
+ }
41
+ }
42
+ }
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Aws.php CHANGED
@@ -28,7 +28,7 @@ class Aws extends ServiceBuilder
28
  /**
29
  * @var string Current version of the SDK
30
  */
31
- const VERSION = '2.7.27';
32
 
33
  /**
34
  * Create a new service locator for the AWS SDK
@@ -95,6 +95,7 @@ class Aws extends ServiceBuilder
95
  * @param string|null $namespace The namespace that the facades should be mounted to. Defaults to global namespace
96
  *
97
  * @return Aws
 
98
  */
99
  public function enableFacades($namespace = null)
100
  {
28
  /**
29
  * @var string Current version of the SDK
30
  */
31
+ const VERSION = '2.8.31';
32
 
33
  /**
34
  * Create a new service locator for the AWS SDK
95
  * @param string|null $namespace The namespace that the facades should be mounted to. Defaults to global namespace
96
  *
97
  * @return Aws
98
+ * @deprecated "Facades" are being removed in version 3.0 of the SDK.
99
  */
100
  public function enableFacades($namespace = null)
101
  {
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Client/AbstractClient.php CHANGED
@@ -189,7 +189,7 @@ abstract class AbstractClient extends Client implements AwsClientInterface
189
  // Update the signature if necessary
190
  $signature = $this->getSignature();
191
  if ($signature instanceof EndpointSignatureInterface) {
192
- /** @var $signature EndpointSignatureInterface */
193
  $signature->setRegionName($region);
194
  }
195
 
189
  // Update the signature if necessary
190
  $signature = $this->getSignature();
191
  if ($signature instanceof EndpointSignatureInterface) {
192
+ /** @var EndpointSignatureInterface $signature */
193
  $signature->setRegionName($region);
194
  }
195
 
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Client/ClientBuilder.php CHANGED
@@ -235,7 +235,8 @@ class ClientBuilder
235
  // Resolve backoff strategy
236
  $backoff = $config->get(Options::BACKOFF);
237
  if ($backoff === null) {
238
- $backoff = $this->createDefaultBackoff();
 
239
  $config->set(Options::BACKOFF, $backoff);
240
  }
241
 
@@ -243,7 +244,7 @@ class ClientBuilder
243
  $this->addBackoffLogger($backoff, $config);
244
  }
245
 
246
- /** @var $client AwsClientInterface */
247
  $client = new $this->clientClass($credentials, $signature, $config);
248
  $client->setDescription($description);
249
 
@@ -489,11 +490,11 @@ class ClientBuilder
489
  }
490
  }
491
 
492
- private function createDefaultBackoff()
493
  {
494
  return new BackoffPlugin(
495
  // Retry failed requests up to 3 times if it is determined that the request can be retried
496
- new TruncatedBackoffStrategy(3,
497
  // Retry failed requests with 400-level responses due to throttling
498
  new ThrottlingErrorChecker($this->exceptionParser,
499
  // Retry failed requests due to transient network or cURL problems
235
  // Resolve backoff strategy
236
  $backoff = $config->get(Options::BACKOFF);
237
  if ($backoff === null) {
238
+ $retries = isset($config[Options::BACKOFF_RETRIES]) ? $config[Options::BACKOFF_RETRIES] : 3;
239
+ $backoff = $this->createDefaultBackoff($retries);
240
  $config->set(Options::BACKOFF, $backoff);
241
  }
242
 
244
  $this->addBackoffLogger($backoff, $config);
245
  }
246
 
247
+ /** @var AwsClientInterface $client */
248
  $client = new $this->clientClass($credentials, $signature, $config);
249
  $client->setDescription($description);
250
 
490
  }
491
  }
492
 
493
+ private function createDefaultBackoff($retries = 3)
494
  {
495
  return new BackoffPlugin(
496
  // Retry failed requests up to 3 times if it is determined that the request can be retried
497
+ new TruncatedBackoffStrategy($retries,
498
  // Retry failed requests with 400-level responses due to throttling
499
  new ThrottlingErrorChecker($this->exceptionParser,
500
  // Retry failed requests due to transient network or cURL problems
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Client/ExpiredCredentialsChecker.php CHANGED
@@ -63,7 +63,7 @@ class ExpiredCredentialsChecker extends AbstractBackoffStrategy
63
  return null;
64
  }
65
 
66
- /** @var $client AwsClientInterface */
67
  $client = $request->getClient();
68
  // Only retry if the credentials can be refreshed
69
  if (!($client->getCredentials() instanceof AbstractRefreshableCredentials)) {
63
  return null;
64
  }
65
 
66
+ /** @var AwsClientInterface $client */
67
  $client = $request->getClient();
68
  // Only retry if the credentials can be refreshed
69
  if (!($client->getCredentials() instanceof AbstractRefreshableCredentials)) {
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Client/UploadBodyListener.php CHANGED
@@ -71,7 +71,7 @@ class UploadBodyListener implements EventSubscriberInterface
71
  */
72
  public function onCommandBeforePrepare(Event $event)
73
  {
74
- /** @var $command Command */
75
  $command = $event['command'];
76
  if (in_array($command->getName(), $this->commands)) {
77
  // Get the interesting parameters
71
  */
72
  public function onCommandBeforePrepare(Event $event)
73
  {
74
+ /** @var Command $command */
75
  $command = $event['command'];
76
  if (in_array($command->getName(), $this->commands)) {
77
  // Get the interesting parameters
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Command/AwsQueryVisitor.php CHANGED
@@ -99,6 +99,9 @@ class AwsQueryVisitor extends AbstractRequestVisitor
99
  // For BC, serialize empty lists for specific operations
100
  if (!$value) {
101
  if (isset($serializeEmpty[$this->fqname])) {
 
 
 
102
  $query[$prefix] = '';
103
  }
104
  return;
99
  // For BC, serialize empty lists for specific operations
100
  if (!$value) {
101
  if (isset($serializeEmpty[$this->fqname])) {
102
+ if (substr($prefix, -7) === '.member') {
103
+ $prefix = substr($prefix, 0, -7);
104
+ }
105
  $query[$prefix] = '';
106
  }
107
  return;
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Credentials/AbstractRefreshableCredentials.php CHANGED
@@ -21,6 +21,25 @@ namespace Aws\Common\Credentials;
21
  */
22
  abstract class AbstractRefreshableCredentials extends AbstractCredentialsDecorator
23
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  /**
25
  * {@inheritdoc}
26
  */
21
  */
22
  abstract class AbstractRefreshableCredentials extends AbstractCredentialsDecorator
23
  {
24
+ /**
25
+ * Get the underlying credentials, refreshing if necessary.
26
+ *
27
+ * @return Credentials
28
+ */
29
+ public function getCredentials()
30
+ {
31
+ if ($this->credentials->isExpired()) {
32
+ $this->refresh();
33
+ }
34
+
35
+ return new Credentials(
36
+ $this->credentials->getAccessKeyId(),
37
+ $this->credentials->getSecretKey(),
38
+ $this->credentials->getSecurityToken(),
39
+ $this->credentials->getExpiration()
40
+ );
41
+ }
42
+
43
  /**
44
  * {@inheritdoc}
45
  */
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Credentials/CacheableCredentials.php CHANGED
@@ -42,9 +42,10 @@ class CacheableCredentials extends AbstractRefreshableCredentials
42
  */
43
  public function __construct(CredentialsInterface $credentials, CacheAdapterInterface $cache, $cacheKey)
44
  {
45
- $this->credentials = $credentials;
46
  $this->cache = $cache;
47
  $this->cacheKey = $cacheKey;
 
 
48
  }
49
 
50
  /**
42
  */
43
  public function __construct(CredentialsInterface $credentials, CacheAdapterInterface $cache, $cacheKey)
44
  {
 
45
  $this->cache = $cache;
46
  $this->cacheKey = $cacheKey;
47
+
48
+ parent::__construct($credentials);
49
  }
50
 
51
  /**
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Credentials/Credentials.php CHANGED
@@ -87,14 +87,22 @@ class Credentials implements CredentialsInterface, FromConfigInterface
87
  }
88
  }
89
 
90
- // Start tracking the cache key
91
- $cacheKey = $config[Options::CREDENTIALS_CACHE_KEY];
 
 
 
 
 
 
 
 
 
 
92
 
93
  // Create the credentials object
94
  if (!$config[Options::KEY] || !$config[Options::SECRET]) {
95
  $credentials = self::createFromEnvironment($config);
96
- // If no cache key was set, use the crc32 hostname of the server
97
- $cacheKey = $cacheKey ?: 'credentials_' . crc32(gethostname());
98
  } else {
99
  // Instantiate using short or long term credentials
100
  $credentials = new static(
@@ -103,8 +111,6 @@ class Credentials implements CredentialsInterface, FromConfigInterface
103
  $config[Options::TOKEN],
104
  $config[Options::TOKEN_TTD]
105
  );
106
- // If no cache key was set, use the access key ID
107
- $cacheKey = $cacheKey ?: 'credentials_' . $config[Options::KEY];
108
  }
109
 
110
  // Check if the credentials are refreshable, and if so, configure caching
@@ -143,11 +149,11 @@ class Credentials implements CredentialsInterface, FromConfigInterface
143
  $profile = self::getEnvVar(self::ENV_PROFILE) ?: 'default';
144
  }
145
 
146
- if (!file_exists($filename) || !($data = parse_ini_file($filename, true))) {
147
  throw new \RuntimeException("Invalid AWS credentials file: {$filename}.");
148
  }
149
 
150
- if (empty($data[$profile])) {
151
  throw new \RuntimeException("Invalid AWS credentials profile {$profile} in {$filename}.");
152
  }
153
 
@@ -262,7 +268,7 @@ class Credentials implements CredentialsInterface, FromConfigInterface
262
  // Get key and secret from ENV variables
263
  $envKey = self::getEnvVar(self::ENV_KEY);
264
  if (!($envSecret = self::getEnvVar(self::ENV_SECRET))) {
265
- // Use AWS_SECRET_ACCESS_KEY if AWS_SECRET_KEY was not set.
266
  $envSecret = self::getEnvVar(self::ENV_SECRET_ACCESS_KEY);
267
  }
268
 
@@ -271,17 +277,26 @@ class Credentials implements CredentialsInterface, FromConfigInterface
271
  return new static($envKey, $envSecret);
272
  }
273
 
274
- // Use credentials from the ini file in HOME directory if available
275
- $home = self::getHomeDir();
276
- if ($home && file_exists("{$home}/.aws/credentials")) {
277
- return self::fromIni($config[Options::PROFILE], "{$home}/.aws/credentials");
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  }
279
 
280
- // Use instance profile credentials (available on EC2 instances)
281
- return new RefreshableInstanceProfileCredentials(
282
- new static('', '', '', 1),
283
- $config[Options::CREDENTIALS_CLIENT]
284
- );
285
  }
286
 
287
  private static function createCache(CredentialsInterface $credentials, $cache, $cacheKey)
87
  }
88
  }
89
 
90
+ // Set up the cache
91
+ $cache = $config[Options::CREDENTIALS_CACHE];
92
+ $cacheKey = $config[Options::CREDENTIALS_CACHE_KEY] ?:
93
+ 'credentials_' . ($config[Options::KEY] ?: crc32(gethostname()));
94
+
95
+ if (
96
+ $cacheKey &&
97
+ $cache instanceof CacheAdapterInterface &&
98
+ $cached = self::createFromCache($cache, $cacheKey)
99
+ ) {
100
+ return $cached;
101
+ }
102
 
103
  // Create the credentials object
104
  if (!$config[Options::KEY] || !$config[Options::SECRET]) {
105
  $credentials = self::createFromEnvironment($config);
 
 
106
  } else {
107
  // Instantiate using short or long term credentials
108
  $credentials = new static(
111
  $config[Options::TOKEN],
112
  $config[Options::TOKEN_TTD]
113
  );
 
 
114
  }
115
 
116
  // Check if the credentials are refreshable, and if so, configure caching
149
  $profile = self::getEnvVar(self::ENV_PROFILE) ?: 'default';
150
  }
151
 
152
+ if (!is_readable($filename) || ($data = parse_ini_file($filename, true)) === false) {
153
  throw new \RuntimeException("Invalid AWS credentials file: {$filename}.");
154
  }
155
 
156
+ if (!isset($data[$profile]['aws_access_key_id']) || !isset($data[$profile]['aws_secret_access_key'])) {
157
  throw new \RuntimeException("Invalid AWS credentials profile {$profile} in {$filename}.");
158
  }
159
 
268
  // Get key and secret from ENV variables
269
  $envKey = self::getEnvVar(self::ENV_KEY);
270
  if (!($envSecret = self::getEnvVar(self::ENV_SECRET))) {
271
+ // Use AWS_SECRET_ACCESS_KEY if AWS_SECRET_KEY was not set
272
  $envSecret = self::getEnvVar(self::ENV_SECRET_ACCESS_KEY);
273
  }
274
 
277
  return new static($envKey, $envSecret);
278
  }
279
 
280
+ try {
281
+ // Use credentials from the INI file in HOME directory if available
282
+ return self::fromIni($config[Options::PROFILE]);
283
+ } catch (\RuntimeException $e) {
284
+ // Otherwise, try using instance profile credentials (available on EC2 instances)
285
+ return new RefreshableInstanceProfileCredentials(
286
+ new static('', '', '', 1),
287
+ $config[Options::CREDENTIALS_CLIENT]
288
+ );
289
+ }
290
+ }
291
+
292
+ private static function createFromCache(CacheAdapterInterface $cache, $cacheKey)
293
+ {
294
+ $cached = $cache->fetch($cacheKey);
295
+ if ($cached instanceof CredentialsInterface && !$cached->isExpired()) {
296
+ return new CacheableCredentials($cached, $cache, $cacheKey);
297
  }
298
 
299
+ return null;
 
 
 
 
300
  }
301
 
302
  private static function createCache(CredentialsInterface $credentials, $cache, $cacheKey)
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Credentials/RefreshableInstanceProfileCredentials.php CHANGED
@@ -29,6 +29,8 @@ class RefreshableInstanceProfileCredentials extends AbstractRefreshableCredentia
29
  * @var InstanceMetadataClient
30
  */
31
  protected $client;
 
 
32
 
33
  /**
34
  * Constructs a new instance profile credentials decorator
@@ -38,10 +40,40 @@ class RefreshableInstanceProfileCredentials extends AbstractRefreshableCredentia
38
  */
39
  public function __construct(CredentialsInterface $credentials, InstanceMetadataClient $client = null)
40
  {
41
- $this->credentials = $credentials;
 
 
 
 
 
 
42
  $this->client = $client ?: InstanceMetadataClient::factory();
43
  }
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  /**
46
  * Attempt to get new credentials from the instance profile
47
  *
@@ -50,10 +82,10 @@ class RefreshableInstanceProfileCredentials extends AbstractRefreshableCredentia
50
  protected function refresh()
51
  {
52
  $credentials = $this->client->getInstanceProfileCredentials();
53
- // Expire the token 1 minute before it actually expires to pre-fetch before expiring
54
  $this->credentials->setAccessKeyId($credentials->getAccessKeyId())
55
  ->setSecretKey($credentials->getSecretKey())
56
  ->setSecurityToken($credentials->getSecurityToken())
57
- ->setExpiration($credentials->getExpiration());
58
  }
59
  }
29
  * @var InstanceMetadataClient
30
  */
31
  protected $client;
32
+ /** @var bool */
33
+ private $customClient;
34
 
35
  /**
36
  * Constructs a new instance profile credentials decorator
40
  */
41
  public function __construct(CredentialsInterface $credentials, InstanceMetadataClient $client = null)
42
  {
43
+ parent::__construct($credentials);
44
+ $this->setClient($client);
45
+ }
46
+
47
+ public function setClient(InstanceMetadataClient $client = null)
48
+ {
49
+ $this->customClient = null !== $client;
50
  $this->client = $client ?: InstanceMetadataClient::factory();
51
  }
52
 
53
+ public function serialize()
54
+ {
55
+ $serializable = array(
56
+ 'credentials' => parent::serialize(),
57
+ 'customClient' => $this->customClient,
58
+ );
59
+
60
+ if ($this->customClient) {
61
+ $serializable['client'] = serialize($this->client);
62
+ }
63
+
64
+ return json_encode($serializable);
65
+ }
66
+
67
+ public function unserialize($value)
68
+ {
69
+ $serialized = json_decode($value, true);
70
+ parent::unserialize($serialized['credentials']);
71
+ $this->customClient = $serialized['customClient'];
72
+ $this->client = $this->customClient ?
73
+ unserialize($serialized['client'])
74
+ : InstanceMetadataClient::factory();
75
+ }
76
+
77
  /**
78
  * Attempt to get new credentials from the instance profile
79
  *
82
  protected function refresh()
83
  {
84
  $credentials = $this->client->getInstanceProfileCredentials();
85
+ // Expire the token 5 minutes early to pre-fetch before expiring.
86
  $this->credentials->setAccessKeyId($credentials->getAccessKeyId())
87
  ->setSecretKey($credentials->getSecretKey())
88
  ->setSecurityToken($credentials->getSecurityToken())
89
+ ->setExpiration($credentials->getExpiration() - 300);
90
  }
91
  }
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Enum/ClientOptions.php CHANGED
@@ -120,6 +120,11 @@ class ClientOptions extends Enum
120
  */
121
  const BACKOFF = 'client.backoff';
122
 
 
 
 
 
 
123
  /**
124
  * @var string `Guzzle\Log\LogAdapterInterface` object used to log backoff retries. Use 'debug' to emit PHP
125
  * warnings when a retry is issued.
120
  */
121
  const BACKOFF = 'client.backoff';
122
 
123
+ /**
124
+ * @var string Option key holding the exponential backoff retries
125
+ */
126
+ const BACKOFF_RETRIES = 'client.backoff.retries';
127
+
128
  /**
129
  * @var string `Guzzle\Log\LogAdapterInterface` object used to log backoff retries. Use 'debug' to emit PHP
130
  * warnings when a retry is issued.
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Exception/Parser/DefaultXmlExceptionParser.php CHANGED
@@ -24,9 +24,6 @@ use Guzzle\Http\Message\Response;
24
  */
25
  class DefaultXmlExceptionParser implements ExceptionParserInterface
26
  {
27
- /**
28
- * {@inheritdoc}
29
- */
30
  public function parse(RequestInterface $request, Response $response)
31
  {
32
  $data = array(
@@ -37,13 +34,25 @@ class DefaultXmlExceptionParser implements ExceptionParserInterface
37
  'parsed' => null
38
  );
39
 
40
- if ($body = $response->getBody(true)) {
41
- $this->parseBody(new \SimpleXMLElement($body), $data);
42
- } else {
43
  $this->parseHeaders($request, $response, $data);
 
44
  }
45
 
46
- return $data;
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
  /**
24
  */
25
  class DefaultXmlExceptionParser implements ExceptionParserInterface
26
  {
 
 
 
27
  public function parse(RequestInterface $request, Response $response)
28
  {
29
  $data = array(
34
  'parsed' => null
35
  );
36
 
37
+ $body = $response->getBody(true);
38
+
39
+ if (!$body) {
40
  $this->parseHeaders($request, $response, $data);
41
+ return $data;
42
  }
43
 
44
+ try {
45
+ $xml = new \SimpleXMLElement($body);
46
+ $this->parseBody($xml, $data);
47
+ return $data;
48
+ } catch (\Exception $e) {
49
+ // Gracefully handle parse errors. This could happen when the
50
+ // server responds with a non-XML response (e.g., private beta
51
+ // services).
52
+ $data['code'] = 'PhpInternalXmlParseError';
53
+ $data['message'] = 'A non-XML response was received';
54
+ return $data;
55
+ }
56
  }
57
 
58
  /**
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Exception/ServiceResponseException.php CHANGED
@@ -180,4 +180,42 @@ class ServiceResponseException extends RuntimeException
180
 
181
  return $message;
182
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  }
180
 
181
  return $message;
182
  }
183
+
184
+ /**
185
+ * Get the request ID of the error. This value is only present if a
186
+ * response was received, and is not present in the event of a networking
187
+ * error.
188
+ *
189
+ * Same as `getRequestId()` method, but matches the interface for SDKv3.
190
+ *
191
+ * @return string|null Returns null if no response was received
192
+ */
193
+ public function getAwsRequestId()
194
+ {
195
+ return $this->requestId;
196
+ }
197
+
198
+ /**
199
+ * Get the AWS error type.
200
+ *
201
+ * Same as `getExceptionType()` method, but matches the interface for SDKv3.
202
+ *
203
+ * @return string|null Returns null if no response was received
204
+ */
205
+ public function getAwsErrorType()
206
+ {
207
+ return $this->exceptionType;
208
+ }
209
+
210
+ /**
211
+ * Get the AWS error code.
212
+ *
213
+ * Same as `getExceptionCode()` method, but matches the interface for SDKv3.
214
+ *
215
+ * @return string|null Returns null if no response was received
216
+ */
217
+ public function getAwsErrorCode()
218
+ {
219
+ return $this->exceptionCode;
220
+ }
221
  }
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Facade/Facade.php CHANGED
@@ -20,6 +20,8 @@ use Aws\Common\Aws;
20
 
21
  /**
22
  * Base facade class that handles the delegation logic
 
 
23
  */
24
  abstract class Facade implements FacadeInterface
25
  {
20
 
21
  /**
22
  * Base facade class that handles the delegation logic
23
+ *
24
+ * @deprecated "Facades" are being removed in version 3.0 of the SDK.
25
  */
26
  abstract class Facade implements FacadeInterface
27
  {
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Facade/FacadeInterface.php CHANGED
@@ -20,6 +20,8 @@ namespace Aws\Common\Facade;
20
  * Interface that defines a client facade. Facades are convenient static classes that allow you to run client methods
21
  * statically on a default instance from the service builder. The facades themselves are aliased into the global
22
  * namespace for ease of use.
 
 
23
  */
24
  interface FacadeInterface
25
  {
20
  * Interface that defines a client facade. Facades are convenient static classes that allow you to run client methods
21
  * statically on a default instance from the service builder. The facades themselves are aliased into the global
22
  * namespace for ease of use.
23
+ *
24
+ * @deprecated "Facades" are being removed in version 3.0 of the SDK.
25
  */
26
  interface FacadeInterface
27
  {
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Resources/aws-config.php CHANGED
@@ -106,12 +106,24 @@ return array(
106
 
107
  'cognitosync' => array('extends' => 'cognito-sync'),
108
 
 
 
 
 
 
 
109
  'codedeploy' => array(
110
  'alias' => 'CodeDeploy',
111
  'extends' => 'default_settings',
112
  'class' => 'Aws\CodeDeploy\CodeDeployClient'
113
  ),
114
 
 
 
 
 
 
 
115
  'config' => array(
116
  'alias' => 'ConfigService',
117
  'extends' => 'default_settings',
@@ -124,12 +136,24 @@ return array(
124
  'class' => 'Aws\DataPipeline\DataPipelineClient'
125
  ),
126
 
 
 
 
 
 
 
127
  'directconnect' => array(
128
  'alias' => 'DirectConnect',
129
  'extends' => 'default_settings',
130
  'class' => 'Aws\DirectConnect\DirectConnectClient'
131
  ),
132
 
 
 
 
 
 
 
133
  'dynamodb' => array(
134
  'alias' => 'DynamoDb',
135
  'extends' => 'default_settings',
@@ -143,6 +167,12 @@ return array(
143
  )
144
  ),
145
 
 
 
 
 
 
 
146
  'ec2' => array(
147
  'alias' => 'Ec2',
148
  'extends' => 'default_settings',
@@ -167,6 +197,12 @@ return array(
167
  'class' => 'Aws\ElasticBeanstalk\ElasticBeanstalkClient'
168
  ),
169
 
 
 
 
 
 
 
170
  'elasticloadbalancing' => array(
171
  'alias' => 'ElasticLoadBalancing',
172
  'extends' => 'default_settings',
@@ -221,6 +257,12 @@ return array(
221
  'class' => 'Aws\ImportExport\ImportExportClient'
222
  ),
223
 
 
 
 
 
 
 
224
  'opsworks' => array(
225
  'alias' => 'OpsWorks',
226
  'extends' => 'default_settings',
@@ -310,5 +352,11 @@ return array(
310
  'extends' => 'default_settings',
311
  'class' => 'Aws\Swf\SwfClient'
312
  ),
 
 
 
 
 
 
313
  )
314
  );
106
 
107
  'cognitosync' => array('extends' => 'cognito-sync'),
108
 
109
+ 'codecommit' => array(
110
+ 'alias' => 'CodeCommit',
111
+ 'extends' => 'default_settings',
112
+ 'class' => 'Aws\CodeCommit\CodeCommitClient'
113
+ ),
114
+
115
  'codedeploy' => array(
116
  'alias' => 'CodeDeploy',
117
  'extends' => 'default_settings',
118
  'class' => 'Aws\CodeDeploy\CodeDeployClient'
119
  ),
120
 
121
+ 'codepipeline' => array(
122
+ 'alias' => 'CodePipeline',
123
+ 'extends' => 'default_settings',
124
+ 'class' => 'Aws\CodePipeline\CodePipelineClient'
125
+ ),
126
+
127
  'config' => array(
128
  'alias' => 'ConfigService',
129
  'extends' => 'default_settings',
136
  'class' => 'Aws\DataPipeline\DataPipelineClient'
137
  ),
138
 
139
+ 'devicefarm' => array(
140
+ 'alias' => 'DeviceFarm',
141
+ 'extends' => 'default_settings',
142
+ 'class' => 'Aws\DeviceFarm\DeviceFarmClient'
143
+ ),
144
+
145
  'directconnect' => array(
146
  'alias' => 'DirectConnect',
147
  'extends' => 'default_settings',
148
  'class' => 'Aws\DirectConnect\DirectConnectClient'
149
  ),
150
 
151
+ 'ds' => array(
152
+ 'alias' => 'DirectoryService',
153
+ 'extends' => 'default_settings',
154
+ 'class' => 'Aws\DirectoryService\DirectoryServiceClient'
155
+ ),
156
+
157
  'dynamodb' => array(
158
  'alias' => 'DynamoDb',
159
  'extends' => 'default_settings',
167
  )
168
  ),
169
 
170
+ 'dynamodbstreams' => array(
171
+ 'alias' => 'DynamoDbStreams',
172
+ 'extends' => 'default_settings',
173
+ 'class' => 'Aws\DynamoDbStreams\DynamoDbStreamsClient'
174
+ ),
175
+
176
  'ec2' => array(
177
  'alias' => 'Ec2',
178
  'extends' => 'default_settings',
197
  'class' => 'Aws\ElasticBeanstalk\ElasticBeanstalkClient'
198
  ),
199
 
200
+ 'efs' => array(
201
+ 'alias' => 'Efs',
202
+ 'extends' => 'default_settings',
203
+ 'class' => 'Aws\Efs\EfsClient'
204
+ ),
205
+
206
  'elasticloadbalancing' => array(
207
  'alias' => 'ElasticLoadBalancing',
208
  'extends' => 'default_settings',
257
  'class' => 'Aws\ImportExport\ImportExportClient'
258
  ),
259
 
260
+ 'machinelearning' => array(
261
+ 'alias' => 'MachineLearning',
262
+ 'extends' => 'default_settings',
263
+ 'class' => 'Aws\MachineLearning\MachineLearningClient'
264
+ ),
265
+
266
  'opsworks' => array(
267
  'alias' => 'OpsWorks',
268
  'extends' => 'default_settings',
352
  'extends' => 'default_settings',
353
  'class' => 'Aws\Swf\SwfClient'
354
  ),
355
+
356
+ 'workspaces' => array(
357
+ 'alias' => 'WorkSpaces',
358
+ 'extends' => 'default_settings',
359
+ 'class' => 'Aws\WorkSpaces\WorkSpacesClient'
360
+ ),
361
  )
362
  );
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureListener.php CHANGED
@@ -16,6 +16,7 @@
16
 
17
  namespace Aws\Common\Signature;
18
 
 
19
  use Aws\Common\Credentials\CredentialsInterface;
20
  use Aws\Common\Credentials\NullCredentials;
21
  use Guzzle\Common\Event;
@@ -76,8 +77,12 @@ class SignatureListener implements EventSubscriberInterface
76
  */
77
  public function onRequestBeforeSend(Event $event)
78
  {
79
- if(!$this->credentials instanceof NullCredentials) {
80
- $this->signature->signRequest($event['request'], $this->credentials);
 
 
 
 
81
  }
82
  }
83
  }
16
 
17
  namespace Aws\Common\Signature;
18
 
19
+ use Aws\Common\Credentials\AbstractRefreshableCredentials;
20
  use Aws\Common\Credentials\CredentialsInterface;
21
  use Aws\Common\Credentials\NullCredentials;
22
  use Guzzle\Common\Event;
77
  */
78
  public function onRequestBeforeSend(Event $event)
79
  {
80
+ $creds = $this->credentials instanceof AbstractRefreshableCredentials
81
+ ? $this->credentials->getCredentials()
82
+ : $this->credentials;
83
+
84
+ if(!$creds instanceof NullCredentials) {
85
+ $this->signature->signRequest($event['request'], $creds);
86
  }
87
  }
88
  }
lib/amazon/aws/aws-sdk-php/src/Aws/Common/Signature/SignatureV4.php CHANGED
@@ -270,13 +270,20 @@ class SignatureV4 extends AbstractSignature implements EndpointSignatureInterfac
270
  RequestInterface $request,
271
  CredentialsInterface $credentials
272
  ) {
273
- $sr = RequestFactory::getInstance()->cloneRequestWithMethod($request, 'GET');
274
-
275
- // Move POST fields to the query if they are present
276
- if ($request instanceof EntityEnclosingRequestInterface) {
 
 
 
 
 
277
  foreach ($request->getPostFields() as $name => $value) {
278
  $sr->getQuery()->set($name, $value);
279
  }
 
 
280
  }
281
 
282
  // Make sure to handle temporary credentials
270
  RequestInterface $request,
271
  CredentialsInterface $credentials
272
  ) {
273
+ // POST requests can be sent as GET requests instead by moving the
274
+ // POST fields into the query string.
275
+ if ($request instanceof EntityEnclosingRequestInterface
276
+ && $request->getMethod() === 'POST'
277
+ && strpos($request->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === 0
278
+ ) {
279
+ $sr = RequestFactory::getInstance()
280
+ ->cloneRequestWithMethod($request, 'GET');
281
+ // Move POST fields to the query if they are present
282
  foreach ($request->getPostFields() as $name => $value) {
283
  $sr->getQuery()->set($name, $value);
284
  }
285
+ } else {
286
+ $sr = clone $request;
287
  }
288
 
289
  // Make sure to handle temporary credentials
lib/amazon/aws/aws-sdk-php/src/Aws/S3/AcpListener.php CHANGED
@@ -43,7 +43,7 @@ class AcpListener implements EventSubscriberInterface
43
  */
44
  public function onCommandBeforePrepare(Event $event)
45
  {
46
- /** @var $command \Guzzle\Service\Command\AbstractCommand */
47
  $command = $event['command'];
48
  $operation = $command->getOperation();
49
  if ($operation->hasParam('ACP') && $command->hasKey('ACP')) {
43
  */
44
  public function onCommandBeforePrepare(Event $event)
45
  {
46
+ /** @var \Guzzle\Service\Command\AbstractCommand $command */
47
  $command = $event['command'];
48
  $operation = $command->getOperation();
49
  if ($operation->hasParam('ACP') && $command->hasKey('ACP')) {
lib/amazon/aws/aws-sdk-php/src/Aws/S3/Exception/NoSuchTagSetException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://aws.amazon.com/apache2.0
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ namespace Aws\S3\Exception;
18
+
19
+ /**
20
+ * There is no TagSet associated with the bucket.
21
+ */
22
+ class NoSuchTagSetException extends S3Exception {}
lib/amazon/aws/aws-sdk-php/src/Aws/S3/IncompleteMultipartUploadChecker.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aws\S3;
4
+
5
+ use Guzzle\Http\Exception\HttpException;
6
+ use Guzzle\Http\Message\RequestInterface;
7
+ use Guzzle\Http\Message\EntityEnclosingRequestInterface;
8
+ use Guzzle\Http\Message\Response;
9
+ use Guzzle\Plugin\Backoff\BackoffStrategyInterface;
10
+ use Guzzle\Plugin\Backoff\AbstractBackoffStrategy;
11
+
12
+ /**
13
+ * Retries CompleteMultipartUpload requests in the case of failure.
14
+ *
15
+ * From the S3 API Documentation:
16
+ *
17
+ * Processing of a Complete Multipart Upload request could take several
18
+ * minutes to complete. After Amazon S3 begins processing the request, it
19
+ * sends an HTTP response header that specifies a 200 OK response. While
20
+ * processing is in progress, Amazon S3 periodically sends whitespace
21
+ * characters to keep the connection from timing out. Because a request
22
+ * could fail after the initial 200 OK response has been sent, it is
23
+ * important that you check the response body to determine whether the
24
+ * request succeeded. Note that if Complete Multipart Upload fails,
25
+ * applications should be prepared to retry the failed requests.
26
+ */
27
+ class IncompleteMultipartUploadChecker extends AbstractBackoffStrategy
28
+ {
29
+ public function __construct(BackoffStrategyInterface $next = null)
30
+ {
31
+ if ($next) {
32
+ $this->setNext($next);
33
+ }
34
+ }
35
+
36
+ public function makesDecision()
37
+ {
38
+ return true;
39
+ }
40
+
41
+ protected function getDelay(
42
+ $retries,
43
+ RequestInterface $request,
44
+ Response $response = null,
45
+ HttpException $e = null
46
+ ) {
47
+ if ($response && $request->getMethod() === 'POST'
48
+ && $request instanceof EntityEnclosingRequestInterface
49
+ && $response->getStatusCode() == 200
50
+ && strpos($request->getBody(), '<CompleteMultipartUpload xmlns') !== false
51
+ && strpos($response->getBody(), '<CompleteMultipartUploadResult xmlns') === false
52
+ ) {
53
+ return true;
54
+ }
55
+ }
56
+ }
lib/amazon/aws/aws-sdk-php/src/Aws/S3/Model/Acp.php CHANGED
@@ -140,7 +140,7 @@ class Acp implements ToArrayInterface, \IteratorAggregate, \Countable
140
 
141
  if ($grants) {
142
  if (is_array($grants) || $grants instanceof \Traversable) {
143
- /** @var $grant Grant */
144
  foreach ($grants as $grant) {
145
  $this->addGrant($grant);
146
  }
@@ -211,7 +211,7 @@ class Acp implements ToArrayInterface, \IteratorAggregate, \Countable
211
  {
212
  $parameters = array();
213
  foreach ($this->grants as $grant) {
214
- /** @var $grant Grant */
215
  $parameters = array_merge_recursive($parameters, $grant->getParameterArray());
216
  }
217
 
140
 
141
  if ($grants) {
142
  if (is_array($grants) || $grants instanceof \Traversable) {
143
+ /** @var Grant $grant */
144
  foreach ($grants as $grant) {
145
  $this->addGrant($grant);
146
  }
211
  {
212
  $parameters = array();
213
  foreach ($this->grants as $grant) {
214
+ /** @var Grant $grant */
215
  $parameters = array_merge_recursive($parameters, $grant->getParameterArray());
216
  }
217
 
lib/amazon/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/AbstractTransfer.php CHANGED
@@ -70,7 +70,7 @@ abstract class AbstractTransfer extends CommonAbstractTransfer
70
  */
71
  protected function complete()
72
  {
73
- /** @var $part UploadPart */
74
  $parts = array();
75
  foreach ($this->state as $part) {
76
  $parts[] = array(
@@ -95,7 +95,7 @@ abstract class AbstractTransfer extends CommonAbstractTransfer
95
  $params = $this->state->getUploadId()->toParams();
96
  $params[Ua::OPTION] = Ua::MULTIPART_UPLOAD;
97
 
98
- /** @var $command OperationCommand */
99
  $command = $this->client->getCommand('AbortMultipartUpload', $params);
100
 
101
  return $command;
70
  */
71
  protected function complete()
72
  {
73
+ /** @var UploadPart $part */
74
  $parts = array();
75
  foreach ($this->state as $part) {
76
  $parts[] = array(
95
  $params = $this->state->getUploadId()->toParams();
96
  $params[Ua::OPTION] = Ua::MULTIPART_UPLOAD;
97
 
98
+ /** @var OperationCommand $command */
99
  $command = $this->client->getCommand('AbortMultipartUpload', $params);
100
 
101
  return $command;
lib/amazon/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/ParallelTransfer.php CHANGED
@@ -87,12 +87,12 @@ class ParallelTransfer extends AbstractTransfer
87
  }
88
 
89
  // Execute each command, iterate over the results, and add to the transfer state
90
- /** @var $command \Guzzle\Service\Command\OperationCommand */
91
  foreach ($this->client->execute($commands) as $command) {
92
  $this->state->addPart(UploadPart::fromArray(array(
93
- 'PartNumber' => count($this->state) + 1,
94
  'ETag' => $command->getResponse()->getEtag(),
95
- 'Size' => (int) $command->getResponse()->getContentLength(),
96
  'LastModified' => gmdate(DateFormat::RFC2822)
97
  )));
98
  $eventData['command'] = $command;
87
  }
88
 
89
  // Execute each command, iterate over the results, and add to the transfer state
90
+ /** @var \Guzzle\Service\Command\OperationCommand $command */
91
  foreach ($this->client->execute($commands) as $command) {
92
  $this->state->addPart(UploadPart::fromArray(array(
93
+ 'PartNumber' => $command['PartNumber'],
94
  'ETag' => $command->getResponse()->getEtag(),
95
+ 'Size' => (int) $command->getRequest()->getBody()->getContentLength(),
96
  'LastModified' => gmdate(DateFormat::RFC2822)
97
  )));
98
  $eventData['command'] = $command;
lib/amazon/aws/aws-sdk-php/src/Aws/S3/Model/MultipartUpload/SerialTransfer.php CHANGED
@@ -73,7 +73,7 @@ class SerialTransfer extends AbstractTransfer
73
  $response = $command->getResponse();
74
 
75
  $this->state->addPart(UploadPart::fromArray(array(
76
- 'PartNumber' => count($this->state) + 1,
77
  'ETag' => $response->getEtag(),
78
  'Size' => $body->getContentLength(),
79
  'LastModified' => gmdate(DateFormat::RFC2822)
73
  $response = $command->getResponse();
74
 
75
  $this->state->addPart(UploadPart::fromArray(array(
76
+ 'PartNumber' => $command['PartNumber'],
77
  'ETag' => $response->getEtag(),
78
  'Size' => $body->getContentLength(),
79
  'LastModified' => gmdate(DateFormat::RFC2822)
lib/amazon/aws/aws-sdk-php/src/Aws/S3/Resources/s3-2006-03-01.php CHANGED
@@ -99,6 +99,7 @@ return array (
99
  'required' => true,
100
  'type' => 'string',
101
  'location' => 'uri',
 
102
  'filters' => array(
103
  'Aws\\S3\\S3Client::explodeKey',
104
  ),
@@ -147,6 +148,7 @@ return array (
147
  'required' => true,
148
  'type' => 'string',
149
  'location' => 'uri',
 
150
  'filters' => array(
151
  'Aws\\S3\\S3Client::explodeKey',
152
  ),
@@ -308,6 +310,7 @@ return array (
308
  'required' => true,
309
  'type' => 'string',
310
  'location' => 'uri',
 
311
  'filters' => array(
312
  'Aws\\S3\\S3Client::explodeKey',
313
  ),
@@ -547,6 +550,7 @@ return array (
547
  'required' => true,
548
  'type' => 'string',
549
  'location' => 'uri',
 
550
  'filters' => array(
551
  'Aws\\S3\\S3Client::explodeKey',
552
  ),
@@ -730,6 +734,7 @@ return array (
730
  'required' => true,
731
  'type' => 'string',
732
  'location' => 'uri',
 
733
  'filters' => array(
734
  'Aws\\S3\\S3Client::explodeKey',
735
  ),
@@ -788,6 +793,7 @@ return array (
788
  'Key' => array(
789
  'required' => true,
790
  'type' => 'string',
 
791
  ),
792
  'VersionId' => array(
793
  'type' => 'string',
@@ -873,6 +879,24 @@ return array (
873
  ),
874
  ),
875
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
876
  'GetBucketLocation' => array(
877
  'httpMethod' => 'GET',
878
  'uri' => '/{Bucket}?location',
@@ -911,7 +935,7 @@ return array (
911
  'httpMethod' => 'GET',
912
  'uri' => '/{Bucket}?notification',
913
  'class' => 'Aws\\S3\\Command\\S3Command',
914
- 'responseClass' => 'GetBucketNotificationOutput',
915
  'responseType' => 'model',
916
  'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETnotification.html',
917
  'parameters' => array(
@@ -926,6 +950,24 @@ return array (
926
  ),
927
  ),
928
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
929
  'GetBucketPolicy' => array(
930
  'httpMethod' => 'GET',
931
  'uri' => '/{Bucket}?policy',
@@ -1082,6 +1124,7 @@ return array (
1082
  'required' => true,
1083
  'type' => 'string',
1084
  'location' => 'uri',
 
1085
  'filters' => array(
1086
  'Aws\\S3\\S3Client::explodeKey',
1087
  ),
@@ -1178,6 +1221,7 @@ return array (
1178
  'required' => true,
1179
  'type' => 'string',
1180
  'location' => 'uri',
 
1181
  'filters' => array(
1182
  'Aws\\S3\\S3Client::explodeKey',
1183
  ),
@@ -1221,6 +1265,7 @@ return array (
1221
  'required' => true,
1222
  'type' => 'string',
1223
  'location' => 'uri',
 
1224
  'filters' => array(
1225
  'Aws\\S3\\S3Client::explodeKey',
1226
  ),
@@ -1300,6 +1345,7 @@ return array (
1300
  'required' => true,
1301
  'type' => 'string',
1302
  'location' => 'uri',
 
1303
  'filters' => array(
1304
  'Aws\\S3\\S3Client::explodeKey',
1305
  ),
@@ -1520,6 +1566,7 @@ return array (
1520
  'required' => true,
1521
  'type' => 'string',
1522
  'location' => 'uri',
 
1523
  'filters' => array(
1524
  'Aws\\S3\\S3Client::explodeKey',
1525
  ),
@@ -1683,6 +1730,7 @@ return array (
1683
  'location' => 'uri',
1684
  ),
1685
  'CORSRules' => array(
 
1686
  'type' => 'array',
1687
  'location' => 'xml',
1688
  'data' => array(
@@ -1705,6 +1753,7 @@ return array (
1705
  ),
1706
  ),
1707
  'AllowedMethods' => array(
 
1708
  'type' => 'array',
1709
  'data' => array(
1710
  'xmlFlattened' => true,
@@ -1716,6 +1765,7 @@ return array (
1716
  ),
1717
  ),
1718
  'AllowedOrigins' => array(
 
1719
  'type' => 'array',
1720
  'data' => array(
1721
  'xmlFlattened' => true,
@@ -1849,6 +1899,124 @@ return array (
1849
  ),
1850
  ),
1851
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1852
  'PutBucketLogging' => array(
1853
  'httpMethod' => 'PUT',
1854
  'uri' => '/{Bucket}?logging',
@@ -1937,6 +2105,7 @@ return array (
1937
  'http://s3.amazonaws.com/doc/2006-03-01/',
1938
  ),
1939
  ),
 
1940
  ),
1941
  'parameters' => array(
1942
  'Bucket' => array(
@@ -2024,6 +2193,220 @@ return array (
2024
  ),
2025
  ),
2026
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2027
  'PutBucketPolicy' => array(
2028
  'httpMethod' => 'PUT',
2029
  'uri' => '/{Bucket}?policy',
@@ -2111,6 +2494,9 @@ return array (
2111
  'required' => true,
2112
  'type' => 'string',
2113
  ),
 
 
 
2114
  ),
2115
  ),
2116
  ),
@@ -2179,6 +2565,7 @@ return array (
2179
  'Key' => array(
2180
  'required' => true,
2181
  'type' => 'string',
 
2182
  ),
2183
  'Value' => array(
2184
  'required' => true,
@@ -2255,6 +2642,7 @@ return array (
2255
  'Key' => array(
2256
  'required' => true,
2257
  'type' => 'string',
 
2258
  ),
2259
  ),
2260
  ),
@@ -2429,6 +2817,7 @@ return array (
2429
  'required' => true,
2430
  'type' => 'string',
2431
  'location' => 'uri',
 
2432
  'filters' => array(
2433
  'Aws\\S3\\S3Client::explodeKey',
2434
  ),
@@ -2594,6 +2983,7 @@ return array (
2594
  'required' => true,
2595
  'type' => 'string',
2596
  'location' => 'uri',
 
2597
  'filters' => array(
2598
  'Aws\\S3\\S3Client::explodeKey',
2599
  ),
@@ -2640,6 +3030,7 @@ return array (
2640
  'required' => true,
2641
  'type' => 'string',
2642
  'location' => 'uri',
 
2643
  'filters' => array(
2644
  'Aws\\S3\\S3Client::explodeKey',
2645
  ),
@@ -2712,6 +3103,7 @@ return array (
2712
  'required' => true,
2713
  'type' => 'string',
2714
  'location' => 'uri',
 
2715
  'filters' => array(
2716
  'Aws\\S3\\S3Client::explodeKey',
2717
  ),
@@ -2728,6 +3120,11 @@ return array (
2728
  'location' => 'query',
2729
  'sentAs' => 'uploadId',
2730
  ),
 
 
 
 
 
2731
  'SSECustomerAlgorithm' => array(
2732
  'type' => 'string',
2733
  'location' => 'header',
@@ -2816,6 +3213,7 @@ return array (
2816
  'required' => true,
2817
  'type' => 'string',
2818
  'location' => 'uri',
 
2819
  'filters' => array(
2820
  'Aws\\S3\\S3Client::explodeKey',
2821
  ),
@@ -2963,6 +3361,11 @@ return array (
2963
  'location' => 'header',
2964
  'sentAs' => 'x-amz-copy-source-version-id',
2965
  ),
 
 
 
 
 
2966
  'ServerSideEncryption' => array(
2967
  'type' => 'string',
2968
  'location' => 'header',
@@ -3434,6 +3837,102 @@ return array (
3434
  ),
3435
  ),
3436
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3437
  'GetBucketLocationOutput' => array(
3438
  'type' => 'object',
3439
  'additionalProperties' => true,
@@ -3509,7 +4008,7 @@ return array (
3509
  ),
3510
  ),
3511
  ),
3512
- 'GetBucketNotificationOutput' => array(
3513
  'type' => 'object',
3514
  'additionalProperties' => true,
3515
  'properties' => array(
@@ -3603,6 +4102,211 @@ return array (
3603
  ),
3604
  ),
3605
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3606
  'GetBucketPolicyOutput' => array(
3607
  'type' => 'object',
3608
  'additionalProperties' => true,
@@ -3653,6 +4357,9 @@ return array (
3653
  'Bucket' => array(
3654
  'type' => 'string',
3655
  ),
 
 
 
3656
  ),
3657
  ),
3658
  ),
@@ -3879,6 +4586,11 @@ return array (
3879
  'location' => 'header',
3880
  'sentAs' => 'Content-Language',
3881
  ),
 
 
 
 
 
3882
  'ContentType' => array(
3883
  'type' => 'string',
3884
  'location' => 'header',
@@ -3921,6 +4633,11 @@ return array (
3921
  'location' => 'header',
3922
  'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id',
3923
  ),
 
 
 
 
 
3924
  'RequestCharged' => array(
3925
  'type' => 'string',
3926
  'location' => 'header',
@@ -4144,6 +4861,11 @@ return array (
4144
  'location' => 'header',
4145
  'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id',
4146
  ),
 
 
 
 
 
4147
  'RequestCharged' => array(
4148
  'type' => 'string',
4149
  'location' => 'header',
@@ -4690,6 +5412,16 @@ return array (
4690
  ),
4691
  ),
4692
  ),
 
 
 
 
 
 
 
 
 
 
4693
  'PutBucketLoggingOutput' => array(
4694
  'type' => 'object',
4695
  'additionalProperties' => true,
@@ -4710,6 +5442,16 @@ return array (
4710
  ),
4711
  ),
4712
  ),
 
 
 
 
 
 
 
 
 
 
4713
  'PutBucketPolicyOutput' => array(
4714
  'type' => 'object',
4715
  'additionalProperties' => true,
@@ -5018,5 +5760,10 @@ return array (
5018
  'NoSuchKey',
5019
  ),
5020
  ),
 
 
 
 
 
5021
  ),
5022
  );
99
  'required' => true,
100
  'type' => 'string',
101
  'location' => 'uri',
102
+ 'minLength' => 1,
103
  'filters' => array(
104
  'Aws\\S3\\S3Client::explodeKey',
105
  ),
148
  'required' => true,
149
  'type' => 'string',
150
  'location' => 'uri',
151
+ 'minLength' => 1,
152
  'filters' => array(
153
  'Aws\\S3\\S3Client::explodeKey',
154
  ),
310
  'required' => true,
311
  'type' => 'string',
312
  'location' => 'uri',
313
+ 'minLength' => 1,
314
  'filters' => array(
315
  'Aws\\S3\\S3Client::explodeKey',
316
  ),
550
  'required' => true,
551
  'type' => 'string',
552
  'location' => 'uri',
553
+ 'minLength' => 1,
554
  'filters' => array(
555
  'Aws\\S3\\S3Client::explodeKey',
556
  ),
734
  'required' => true,
735
  'type' => 'string',
736
  'location' => 'uri',
737
+ 'minLength' => 1,
738
  'filters' => array(
739
  'Aws\\S3\\S3Client::explodeKey',
740
  ),
793
  'Key' => array(
794
  'required' => true,
795
  'type' => 'string',
796
+ 'minLength' => 1,
797
  ),
798
  'VersionId' => array(
799
  'type' => 'string',
879
  ),
880
  ),
881
  ),
882
+ 'GetBucketLifecycleConfiguration' => array(
883
+ 'httpMethod' => 'GET',
884
+ 'uri' => '/{Bucket}?lifecycle',
885
+ 'class' => 'Aws\\S3\\Command\\S3Command',
886
+ 'responseClass' => 'GetBucketLifecycleConfigurationOutput',
887
+ 'responseType' => 'model',
888
+ 'parameters' => array(
889
+ 'Bucket' => array(
890
+ 'required' => true,
891
+ 'type' => 'string',
892
+ 'location' => 'uri',
893
+ ),
894
+ 'command.expects' => array(
895
+ 'static' => true,
896
+ 'default' => 'application/xml',
897
+ ),
898
+ ),
899
+ ),
900
  'GetBucketLocation' => array(
901
  'httpMethod' => 'GET',
902
  'uri' => '/{Bucket}?location',
935
  'httpMethod' => 'GET',
936
  'uri' => '/{Bucket}?notification',
937
  'class' => 'Aws\\S3\\Command\\S3Command',
938
+ 'responseClass' => 'NotificationConfigurationDeprecated',
939
  'responseType' => 'model',
940
  'documentationUrl' => 'http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETnotification.html',
941
  'parameters' => array(
950
  ),
951
  ),
952
  ),
953
+ 'GetBucketNotificationConfiguration' => array(
954
+ 'httpMethod' => 'GET',
955
+ 'uri' => '/{Bucket}?notification',
956
+ 'class' => 'Aws\\S3\\Command\\S3Command',
957
+ 'responseClass' => 'NotificationConfiguration',
958
+ 'responseType' => 'model',
959
+ 'parameters' => array(
960
+ 'Bucket' => array(
961
+ 'required' => true,
962
+ 'type' => 'string',
963
+ 'location' => 'uri',
964
+ ),
965
+ 'command.expects' => array(
966
+ 'static' => true,
967
+ 'default' => 'application/xml',
968
+ ),
969
+ ),
970
+ ),
971
  'GetBucketPolicy' => array(
972
  'httpMethod' => 'GET',
973
  'uri' => '/{Bucket}?policy',
1124
  'required' => true,
1125
  'type' => 'string',
1126
  'location' => 'uri',
1127
+ 'minLength' => 1,
1128
  'filters' => array(
1129
  'Aws\\S3\\S3Client::explodeKey',
1130
  ),
1221
  'required' => true,
1222
  'type' => 'string',
1223
  'location' => 'uri',
1224
+ 'minLength' => 1,
1225
  'filters' => array(
1226
  'Aws\\S3\\S3Client::explodeKey',
1227
  ),
1265
  'required' => true,
1266
  'type' => 'string',
1267
  'location' => 'uri',
1268
+ 'minLength' => 1,
1269
  'filters' => array(
1270
  'Aws\\S3\\S3Client::explodeKey',
1271
  ),
1345
  'required' => true,
1346
  'type' => 'string',
1347
  'location' => 'uri',
1348
+ 'minLength' => 1,
1349
  'filters' => array(
1350
  'Aws\\S3\\S3Client::explodeKey',
1351
  ),
1566
  'required' => true,
1567
  'type' => 'string',
1568
  'location' => 'uri',
1569
+ 'minLength' => 1,
1570
  'filters' => array(
1571
  'Aws\\S3\\S3Client::explodeKey',
1572
  ),
1730
  'location' => 'uri',
1731
  ),
1732
  'CORSRules' => array(
1733
+ 'required' => true,
1734
  'type' => 'array',
1735
  'location' => 'xml',
1736
  'data' => array(
1753
  ),
1754
  ),
1755
  'AllowedMethods' => array(
1756
+ 'required' => true,
1757
  'type' => 'array',
1758
  'data' => array(
1759
  'xmlFlattened' => true,
1765
  ),
1766
  ),
1767
  'AllowedOrigins' => array(
1768
+ 'required' => true,
1769
  'type' => 'array',
1770
  'data' => array(
1771
  'xmlFlattened' => true,
1899
  ),
1900
  ),
1901
  ),
1902
+ 'PutBucketLifecycleConfiguration' => array(
1903
+ 'httpMethod' => 'PUT',
1904
+ 'uri' => '/{Bucket}?lifecycle',
1905
+ 'class' => 'Aws\\S3\\Command\\S3Command',
1906
+ 'responseClass' => 'PutBucketLifecycleConfigurationOutput',
1907
+ 'responseType' => 'model',
1908
+ 'data' => array(
1909
+ 'xmlRoot' => array(
1910
+ 'name' => 'LifecycleConfiguration',
1911
+ 'namespaces' => array(
1912
+ 'http://s3.amazonaws.com/doc/2006-03-01/',
1913
+ ),
1914
+ ),
1915
+ ),
1916
+ 'parameters' => array(
1917
+ 'Bucket' => array(
1918
+ 'required' => true,
1919
+ 'type' => 'string',
1920
+ 'location' => 'uri',
1921
+ ),
1922
+ 'Rules' => array(
1923
+ 'required' => true,
1924
+ 'type' => 'array',
1925
+ 'location' => 'xml',
1926
+ 'data' => array(
1927
+ 'xmlFlattened' => true,
1928
+ ),
1929
+ 'items' => array(
1930
+ 'name' => 'LifecycleRule',
1931
+ 'type' => 'object',
1932
+ 'sentAs' => 'Rule',
1933
+ 'properties' => array(
1934
+ 'Expiration' => array(
1935
+ 'type' => 'object',
1936
+ 'properties' => array(
1937
+ 'Date' => array(
1938
+ 'type' => array(
1939
+ 'object',
1940
+ 'string',
1941
+ 'integer',
1942
+ ),
1943
+ 'format' => 'date-time-http',
1944
+ ),
1945
+ 'Days' => array(
1946
+ 'type' => 'numeric',
1947
+ ),
1948
+ ),
1949
+ ),
1950
+ 'ID' => array(
1951
+ 'type' => 'string',
1952
+ ),
1953
+ 'Prefix' => array(
1954
+ 'required' => true,
1955
+ 'type' => 'string',
1956
+ ),
1957
+ 'Status' => array(
1958
+ 'required' => true,
1959
+ 'type' => 'string',
1960
+ ),
1961
+ 'Transitions' => array(
1962
+ 'type' => 'array',
1963
+ 'data' => array(
1964
+ 'xmlFlattened' => true,
1965
+ ),
1966
+ 'items' => array(
1967
+ 'name' => 'Transition',
1968
+ 'type' => 'object',
1969
+ 'sentAs' => 'Transition',
1970
+ 'properties' => array(
1971
+ 'Date' => array(
1972
+ 'type' => array(
1973
+ 'object',
1974
+ 'string',
1975
+ 'integer',
1976
+ ),
1977
+ 'format' => 'date-time-http',
1978
+ ),
1979
+ 'Days' => array(
1980
+ 'type' => 'numeric',
1981
+ ),
1982
+ 'StorageClass' => array(
1983
+ 'type' => 'string',
1984
+ ),
1985
+ ),
1986
+ ),
1987
+ ),
1988
+ 'NoncurrentVersionTransitions' => array(
1989
+ 'type' => 'array',
1990
+ 'data' => array(
1991
+ 'xmlFlattened' => true,
1992
+ ),
1993
+ 'items' => array(
1994
+ 'name' => 'NoncurrentVersionTransition',
1995
+ 'type' => 'object',
1996
+ 'sentAs' => 'NoncurrentVersionTransition',
1997
+ 'properties' => array(
1998
+ 'NoncurrentDays' => array(
1999
+ 'type' => 'numeric',
2000
+ ),
2001
+ 'StorageClass' => array(
2002
+ 'type' => 'string',
2003
+ ),
2004
+ ),
2005
+ ),
2006
+ ),
2007
+ 'NoncurrentVersionExpiration' => array(
2008
+ 'type' => 'object',
2009
+ 'properties' => array(
2010
+ 'NoncurrentDays' => array(
2011
+ 'type' => 'numeric',
2012
+ ),
2013
+ ),
2014
+ ),
2015
+ ),
2016
+ ),
2017
+ ),
2018
+ ),
2019
+ ),
2020
  'PutBucketLogging' => array(
2021
  'httpMethod' => 'PUT',
2022
  'uri' => '/{Bucket}?logging',
2105
  'http://s3.amazonaws.com/doc/2006-03-01/',
2106
  ),
2107
  ),
2108
+ 'xmlAllowEmpty' => true,
2109
  ),
2110
  'parameters' => array(
2111
  'Bucket' => array(
2193
  ),
2194
  ),
2195
  ),
2196
+ 'PutBucketNotificationConfiguration' => array(
2197
+ 'httpMethod' => 'PUT',
2198
+ 'uri' => '/{Bucket}?notification',
2199
+ 'class' => 'Aws\\S3\\Command\\S3Command',
2200
+ 'responseClass' => 'PutBucketNotificationConfigurationOutput',
2201
+ 'responseType' => 'model',
2202
+ 'data' => array(
2203
+ 'xmlRoot' => array(
2204
+ 'name' => 'NotificationConfiguration',
2205
+ 'namespaces' => array(
2206
+ 'http://s3.amazonaws.com/doc/2006-03-01/',
2207
+ ),
2208
+ ),
2209
+ ),
2210
+ 'parameters' => array(
2211
+ 'Bucket' => array(
2212
+ 'required' => true,
2213
+ 'type' => 'string',
2214
+ 'location' => 'uri',
2215
+ ),
2216
+ 'TopicConfigurations' => array(
2217
+ 'type' => 'array',
2218
+ 'location' => 'xml',
2219
+ 'data' => array(
2220
+ 'xmlFlattened' => true,
2221
+ ),
2222
+ 'items' => array(
2223
+ 'name' => 'TopicConfiguration',
2224
+ 'type' => 'object',
2225
+ 'sentAs' => 'TopicConfiguration',
2226
+ 'properties' => array(
2227
+ 'Id' => array(
2228
+ 'type' => 'string',
2229
+ ),
2230
+ 'TopicArn' => array(
2231
+ 'required' => true,
2232
+ 'type' => 'string',
2233
+ 'sentAs' => 'Topic',
2234
+ ),
2235
+ 'Events' => array(
2236
+ 'required' => true,
2237
+ 'type' => 'array',
2238
+ 'data' => array(
2239
+ 'xmlFlattened' => true,
2240
+ ),
2241
+ 'items' => array(
2242
+ 'name' => 'Event',
2243
+ 'type' => 'string',
2244
+ 'sentAs' => 'Event',
2245
+ ),
2246
+ ),
2247
+ 'Filter' => array(
2248
+ 'type' => 'object',
2249
+ 'properties' => array(
2250
+ 'Key' => array(
2251
+ 'type' => 'object',
2252
+ 'sentAs' => 'S3Key',
2253
+ 'properties' => array(
2254
+ 'FilterRules' => array(
2255
+ 'type' => 'array',
2256
+ 'data' => array(
2257
+ 'xmlFlattened' => true,
2258
+ ),
2259
+ 'items' => array(
2260
+ 'name' => 'FilterRule',
2261
+ 'type' => 'object',
2262
+ 'sentAs' => 'FilterRule',
2263
+ 'properties' => array(
2264
+ 'Name' => array(
2265
+ 'type' => 'string',
2266
+ ),
2267
+ 'Value' => array(
2268
+ 'type' => 'string',
2269
+ ),
2270
+ ),
2271
+ ),
2272
+ ),
2273
+ ),
2274
+ ),
2275
+ ),
2276
+ ),
2277
+ ),
2278
+ ),
2279
+ ),
2280
+ 'QueueConfigurations' => array(
2281
+ 'type' => 'array',
2282
+ 'location' => 'xml',
2283
+ 'data' => array(
2284
+ 'xmlFlattened' => true,
2285
+ ),
2286
+ 'items' => array(
2287
+ 'name' => 'QueueConfiguration',
2288
+ 'type' => 'object',
2289
+ 'sentAs' => 'QueueConfiguration',
2290
+ 'properties' => array(
2291
+ 'Id' => array(
2292
+ 'type' => 'string',
2293
+ ),
2294
+ 'QueueArn' => array(
2295
+ 'required' => true,
2296
+ 'type' => 'string',
2297
+ 'sentAs' => 'Queue',
2298
+ ),
2299
+ 'Events' => array(
2300
+ 'required' => true,
2301
+ 'type' => 'array',
2302
+ 'data' => array(
2303
+ 'xmlFlattened' => true,
2304
+ ),
2305
+ 'items' => array(
2306
+ 'name' => 'Event',
2307
+ 'type' => 'string',
2308
+ 'sentAs' => 'Event',
2309
+ ),
2310
+ ),
2311
+ 'Filter' => array(
2312
+ 'type' => 'object',
2313
+ 'properties' => array(
2314
+ 'Key' => array(
2315
+ 'type' => 'object',
2316
+ 'sentAs' => 'S3Key',
2317
+ 'properties' => array(
2318
+ 'FilterRules' => array(
2319
+ 'type' => 'array',
2320
+ 'data' => array(
2321
+ 'xmlFlattened' => true,
2322
+ ),
2323
+ 'items' => array(
2324
+ 'name' => 'FilterRule',
2325
+ 'type' => 'object',
2326
+ 'sentAs' => 'FilterRule',
2327
+ 'properties' => array(
2328
+ 'Name' => array(
2329
+ 'type' => 'string',
2330
+ ),
2331
+ 'Value' => array(
2332
+ 'type' => 'string',
2333
+ ),
2334
+ ),
2335
+ ),
2336
+ ),
2337
+ ),
2338
+ ),
2339
+ ),
2340
+ ),
2341
+ ),
2342
+ ),
2343
+ ),
2344
+ 'LambdaFunctionConfigurations' => array(
2345
+ 'type' => 'array',
2346
+ 'location' => 'xml',
2347
+ 'data' => array(
2348
+ 'xmlFlattened' => true,
2349
+ ),
2350
+ 'items' => array(
2351
+ 'name' => 'LambdaFunctionConfiguration',
2352
+ 'type' => 'object',
2353
+ 'sentAs' => 'CloudFunctionConfiguration',
2354
+ 'properties' => array(
2355
+ 'Id' => array(
2356
+ 'type' => 'string',
2357
+ ),
2358
+ 'LambdaFunctionArn' => array(
2359
+ 'required' => true,
2360
+ 'type' => 'string',
2361
+ 'sentAs' => 'CloudFunction',
2362
+ ),
2363
+ 'Events' => array(
2364
+ 'required' => true,
2365
+ 'type' => 'array',
2366
+ 'data' => array(
2367
+ 'xmlFlattened' => true,
2368
+ ),
2369
+ 'items' => array(
2370
+ 'name' => 'Event',
2371
+ 'type' => 'string',
2372
+ 'sentAs' => 'Event',
2373
+ ),
2374
+ ),
2375
+ 'Filter' => array(
2376
+ 'type' => 'object',
2377
+ 'properties' => array(
2378
+ 'Key' => array(
2379
+ 'type' => 'object',
2380
+ 'sentAs' => 'S3Key',
2381
+ 'properties' => array(
2382
+ 'FilterRules' => array(
2383
+ 'type' => 'array',
2384
+ 'data' => array(
2385
+ 'xmlFlattened' => true,
2386
+ ),
2387
+ 'items' => array(
2388
+ 'name' => 'FilterRule',
2389
+ 'type' => 'object',
2390
+ 'sentAs' => 'FilterRule',
2391
+ 'properties' => array(
2392
+ 'Name' => array(
2393
+ 'type' => 'string',
2394
+ ),
2395
+ 'Value' => array(
2396
+ 'type' => 'string',
2397
+ ),
2398
+ ),
2399
+ ),
2400
+ ),
2401
+ ),
2402
+ ),
2403
+ ),
2404
+ ),
2405
+ ),
2406
+ ),
2407
+ ),
2408
+ ),
2409
+ ),
2410
  'PutBucketPolicy' => array(
2411
  'httpMethod' => 'PUT',
2412
  'uri' => '/{Bucket}?policy',
2494
  'required' => true,
2495
  'type' => 'string',
2496
  ),
2497
+ 'StorageClass' => array(
2498
+ 'type' => 'string',
2499
+ ),
2500
  ),
2501
  ),
2502
  ),
2565
  'Key' => array(
2566
  'required' => true,
2567
  'type' => 'string',
2568
+ 'minLength' => 1,
2569
  ),
2570
  'Value' => array(
2571
  'required' => true,
2642
  'Key' => array(
2643
  'required' => true,
2644
  'type' => 'string',
2645
+ 'minLength' => 1,
2646
  ),
2647
  ),
2648
  ),
2817
  'required' => true,
2818
  'type' => 'string',
2819
  'location' => 'uri',
2820
+ 'minLength' => 1,
2821
  'filters' => array(
2822
  'Aws\\S3\\S3Client::explodeKey',
2823
  ),
2983
  'required' => true,
2984
  'type' => 'string',
2985
  'location' => 'uri',
2986
+ 'minLength' => 1,
2987
  'filters' => array(
2988
  'Aws\\S3\\S3Client::explodeKey',
2989
  ),
3030
  'required' => true,
3031
  'type' => 'string',
3032
  'location' => 'uri',
3033
+ 'minLength' => 1,
3034
  'filters' => array(
3035
  'Aws\\S3\\S3Client::explodeKey',
3036
  ),
3103
  'required' => true,
3104
  'type' => 'string',
3105
  'location' => 'uri',
3106
+ 'minLength' => 1,
3107
  'filters' => array(
3108
  'Aws\\S3\\S3Client::explodeKey',
3109
  ),
3120
  'location' => 'query',
3121
  'sentAs' => 'uploadId',
3122
  ),
3123
+ 'ServerSideEncryption' => array(
3124
+ 'type' => 'string',
3125
+ 'location' => 'header',
3126
+ 'sentAs' => 'x-amz-server-side-encryption',
3127
+ ),
3128
  'SSECustomerAlgorithm' => array(
3129
  'type' => 'string',
3130
  'location' => 'header',
3213
  'required' => true,
3214
  'type' => 'string',
3215
  'location' => 'uri',
3216
+ 'minLength' => 1,
3217
  'filters' => array(
3218
  'Aws\\S3\\S3Client::explodeKey',
3219
  ),
3361
  'location' => 'header',
3362
  'sentAs' => 'x-amz-copy-source-version-id',
3363
  ),
3364
+ 'VersionId' => array(
3365
+ 'type' => 'string',
3366
+ 'location' => 'header',
3367
+ 'sentAs' => 'x-amz-version-id',
3368
+ ),
3369
  'ServerSideEncryption' => array(
3370
  'type' => 'string',
3371
  'location' => 'header',
3837
  ),
3838
  ),
3839
  ),
3840
+ 'GetBucketLifecycleConfigurationOutput' => array(
3841
+ 'type' => 'object',
3842
+ 'additionalProperties' => true,
3843
+ 'properties' => array(
3844
+ 'Rules' => array(
3845
+ 'type' => 'array',
3846
+ 'location' => 'xml',
3847
+ 'sentAs' => 'Rule',
3848
+ 'data' => array(
3849
+ 'xmlFlattened' => true,
3850
+ ),
3851
+ 'items' => array(
3852
+ 'name' => 'LifecycleRule',
3853
+ 'type' => 'object',
3854
+ 'sentAs' => 'Rule',
3855
+ 'properties' => array(
3856
+ 'Expiration' => array(
3857
+ 'type' => 'object',
3858
+ 'properties' => array(
3859
+ 'Date' => array(
3860
+ 'type' => 'string',
3861
+ ),
3862
+ 'Days' => array(
3863
+ 'type' => 'numeric',
3864
+ ),
3865
+ ),
3866
+ ),
3867
+ 'ID' => array(
3868
+ 'type' => 'string',
3869
+ ),
3870
+ 'Prefix' => array(
3871
+ 'type' => 'string',
3872
+ ),
3873
+ 'Status' => array(
3874
+ 'type' => 'string',
3875
+ ),
3876
+ 'Transitions' => array(
3877
+ 'type' => 'array',
3878
+ 'sentAs' => 'Transition',
3879
+ 'data' => array(
3880
+ 'xmlFlattened' => true,
3881
+ ),
3882
+ 'items' => array(
3883
+ 'name' => 'Transition',
3884
+ 'type' => 'object',
3885
+ 'sentAs' => 'Transition',
3886
+ 'properties' => array(
3887
+ 'Date' => array(
3888
+ 'type' => 'string',
3889
+ ),
3890
+ 'Days' => array(
3891
+ 'type' => 'numeric',
3892
+ ),
3893
+ 'StorageClass' => array(
3894
+ 'type' => 'string',
3895
+ ),
3896
+ ),
3897
+ ),
3898
+ ),
3899
+ 'NoncurrentVersionTransitions' => array(
3900
+ 'type' => 'array',
3901
+ 'sentAs' => 'NoncurrentVersionTransition',
3902
+ 'data' => array(
3903
+ 'xmlFlattened' => true,
3904
+ ),
3905
+ 'items' => array(
3906
+ 'name' => 'NoncurrentVersionTransition',
3907
+ 'type' => 'object',
3908
+ 'sentAs' => 'NoncurrentVersionTransition',
3909
+ 'properties' => array(
3910
+ 'NoncurrentDays' => array(
3911
+ 'type' => 'numeric',
3912
+ ),
3913
+ 'StorageClass' => array(
3914
+ 'type' => 'string',
3915
+ ),
3916
+ ),
3917
+ ),
3918
+ ),
3919
+ 'NoncurrentVersionExpiration' => array(
3920
+ 'type' => 'object',
3921
+ 'properties' => array(
3922
+ 'NoncurrentDays' => array(
3923
+ 'type' => 'numeric',
3924
+ ),
3925
+ ),
3926
+ ),
3927
+ ),
3928
+ ),
3929
+ ),
3930
+ 'RequestId' => array(
3931
+ 'location' => 'header',
3932
+ 'sentAs' => 'x-amz-request-id',
3933
+ ),
3934
+ ),
3935
+ ),
3936
  'GetBucketLocationOutput' => array(
3937
  'type' => 'object',
3938
  'additionalProperties' => true,
4008
  ),
4009
  ),
4010
  ),
4011
+ 'NotificationConfigurationDeprecated' => array(
4012
  'type' => 'object',
4013
  'additionalProperties' => true,
4014
  'properties' => array(
4102
  ),
4103
  ),
4104
  ),
4105
+ 'NotificationConfiguration' => array(
4106
+ 'type' => 'object',
4107
+ 'additionalProperties' => true,
4108
+ 'properties' => array(
4109
+ 'TopicConfigurations' => array(
4110
+ 'type' => 'array',
4111
+ 'location' => 'xml',
4112
+ 'sentAs' => 'TopicConfiguration',
4113
+ 'data' => array(
4114
+ 'xmlFlattened' => true,
4115
+ ),
4116
+ 'items' => array(
4117
+ 'name' => 'TopicConfiguration',
4118
+ 'type' => 'object',
4119
+ 'sentAs' => 'TopicConfiguration',
4120
+ 'properties' => array(
4121
+ 'Id' => array(
4122
+ 'type' => 'string',
4123
+ ),
4124
+ 'TopicArn' => array(
4125
+ 'type' => 'string',
4126
+ 'sentAs' => 'Topic',
4127
+ ),
4128
+ 'Events' => array(
4129
+ 'type' => 'array',
4130
+ 'sentAs' => 'Event',
4131
+ 'data' => array(
4132
+ 'xmlFlattened' => true,
4133
+ ),
4134
+ 'items' => array(
4135
+ 'name' => 'Event',
4136
+ 'type' => 'string',
4137
+ 'sentAs' => 'Event',
4138
+ ),
4139
+ ),
4140
+ 'Filter' => array(
4141
+ 'type' => 'object',
4142
+ 'properties' => array(
4143
+ 'Key' => array(
4144
+ 'type' => 'object',
4145
+ 'sentAs' => 'S3Key',
4146
+ 'properties' => array(
4147
+ 'FilterRules' => array(
4148
+ 'type' => 'array',
4149
+ 'sentAs' => 'FilterRule',
4150
+ 'data' => array(
4151
+ 'xmlFlattened' => true,
4152
+ ),
4153
+ 'items' => array(
4154
+ 'name' => 'FilterRule',
4155
+ 'type' => 'object',
4156
+ 'sentAs' => 'FilterRule',
4157
+ 'properties' => array(
4158
+ 'Name' => array(
4159
+ 'type' => 'string',
4160
+ ),
4161
+ 'Value' => array(
4162
+ 'type' => 'string',
4163
+ ),
4164
+ ),
4165
+ ),
4166
+ ),
4167
+ ),
4168
+ ),
4169
+ ),
4170
+ ),
4171
+ ),
4172
+ ),
4173
+ ),
4174
+ 'QueueConfigurations' => array(
4175
+ 'type' => 'array',
4176
+ 'location' => 'xml',
4177
+ 'sentAs' => 'QueueConfiguration',
4178
+ 'data' => array(
4179
+ 'xmlFlattened' => true,
4180
+ ),
4181
+ 'items' => array(
4182
+ 'name' => 'QueueConfiguration',
4183
+ 'type' => 'object',
4184
+ 'sentAs' => 'QueueConfiguration',
4185
+ 'properties' => array(
4186
+ 'Id' => array(
4187
+ 'type' => 'string',
4188
+ ),
4189
+ 'QueueArn' => array(
4190
+ 'type' => 'string',
4191
+ 'sentAs' => 'Queue',
4192
+ ),
4193
+ 'Events' => array(
4194
+ 'type' => 'array',
4195
+ 'sentAs' => 'Event',
4196
+ 'data' => array(
4197
+ 'xmlFlattened' => true,
4198
+ ),
4199
+ 'items' => array(
4200
+ 'name' => 'Event',
4201
+ 'type' => 'string',
4202
+ 'sentAs' => 'Event',
4203
+ ),
4204
+ ),
4205
+ 'Filter' => array(
4206
+ 'type' => 'object',
4207
+ 'properties' => array(
4208
+ 'Key' => array(
4209
+ 'type' => 'object',
4210
+ 'sentAs' => 'S3Key',
4211
+ 'properties' => array(
4212
+ 'FilterRules' => array(
4213
+ 'type' => 'array',
4214
+ 'sentAs' => 'FilterRule',
4215
+ 'data' => array(
4216
+ 'xmlFlattened' => true,
4217
+ ),
4218
+ 'items' => array(
4219
+ 'name' => 'FilterRule',
4220
+ 'type' => 'object',
4221
+ 'sentAs' => 'FilterRule',
4222
+ 'properties' => array(
4223
+ 'Name' => array(
4224
+ 'type' => 'string',
4225
+ ),
4226
+ 'Value' => array(
4227
+ 'type' => 'string',
4228
+ ),
4229
+ ),
4230
+ ),
4231
+ ),
4232
+ ),
4233
+ ),
4234
+ ),
4235
+ ),
4236
+ ),
4237
+ ),
4238
+ ),
4239
+ 'LambdaFunctionConfigurations' => array(
4240
+ 'type' => 'array',
4241
+ 'location' => 'xml',
4242
+ 'sentAs' => 'CloudFunctionConfiguration',
4243
+ 'data' => array(
4244
+ 'xmlFlattened' => true,
4245
+ ),
4246
+ 'items' => array(
4247
+ 'name' => 'LambdaFunctionConfiguration',
4248
+ 'type' => 'object',
4249
+ 'sentAs' => 'CloudFunctionConfiguration',
4250
+ 'properties' => array(
4251
+ 'Id' => array(
4252
+ 'type' => 'string',
4253
+ ),
4254
+ 'LambdaFunctionArn' => array(
4255
+ 'type' => 'string',
4256
+ 'sentAs' => 'CloudFunction',
4257
+ ),
4258
+ 'Events' => array(
4259
+ 'type' => 'array',
4260
+ 'sentAs' => 'Event',
4261
+ 'data' => array(
4262
+ 'xmlFlattened' => true,
4263
+ ),
4264
+ 'items' => array(
4265
+ 'name' => 'Event',
4266
+ 'type' => 'string',
4267
+ 'sentAs' => 'Event',
4268
+ ),
4269
+ ),
4270
+ 'Filter' => array(
4271
+ 'type' => 'object',
4272
+ 'properties' => array(
4273
+ 'Key' => array(
4274
+ 'type' => 'object',
4275
+ 'sentAs' => 'S3Key',
4276
+ 'properties' => array(
4277
+ 'FilterRules' => array(
4278
+ 'type' => 'array',
4279
+ 'sentAs' => 'FilterRule',
4280
+ 'data' => array(
4281
+ 'xmlFlattened' => true,
4282
+ ),
4283
+ 'items' => array(
4284
+ 'name' => 'FilterRule',
4285
+ 'type' => 'object',
4286
+ 'sentAs' => 'FilterRule',
4287
+ 'properties' => array(
4288
+ 'Name' => array(
4289
+ 'type' => 'string',
4290
+ ),
4291
+ 'Value' => array(
4292
+ 'type' => 'string',
4293
+ ),
4294
+ ),
4295
+ ),
4296
+ ),
4297
+ ),
4298
+ ),
4299
+ ),
4300
+ ),
4301
+ ),
4302
+ ),
4303
+ ),
4304
+ 'RequestId' => array(
4305
+ 'location' => 'header',
4306
+ 'sentAs' => 'x-amz-request-id',
4307
+ ),
4308
+ ),
4309
+ ),
4310
  'GetBucketPolicyOutput' => array(
4311
  'type' => 'object',
4312
  'additionalProperties' => true,
4357
  'Bucket' => array(
4358
  'type' => 'string',
4359
  ),
4360
+ 'StorageClass' => array(
4361
+ 'type' => 'string',
4362
+ ),
4363
  ),
4364
  ),
4365
  ),
4586
  'location' => 'header',
4587
  'sentAs' => 'Content-Language',
4588
  ),
4589
+ 'ContentRange' => array(
4590
+ 'type' => 'string',
4591
+ 'location' => 'header',
4592
+ 'sentAs' => 'Content-Range',
4593
+ ),
4594
  'ContentType' => array(
4595
  'type' => 'string',
4596
  'location' => 'header',
4633
  'location' => 'header',
4634
  'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id',
4635
  ),
4636
+ 'StorageClass' => array(
4637
+ 'type' => 'string',
4638
+ 'location' => 'header',
4639
+ 'sentAs' => 'x-amz-storage-class',
4640
+ ),
4641
  'RequestCharged' => array(
4642
  'type' => 'string',
4643
  'location' => 'header',
4861
  'location' => 'header',
4862
  'sentAs' => 'x-amz-server-side-encryption-aws-kms-key-id',
4863
  ),
4864
+ 'StorageClass' => array(
4865
+ 'type' => 'string',
4866
+ 'location' => 'header',
4867
+ 'sentAs' => 'x-amz-storage-class',
4868
+ ),
4869
  'RequestCharged' => array(
4870
  'type' => 'string',
4871
  'location' => 'header',
5412
  ),
5413
  ),
5414
  ),
5415
+ 'PutBucketLifecycleConfigurationOutput' => array(
5416
+ 'type' => 'object',
5417
+ 'additionalProperties' => true,
5418
+ 'properties' => array(
5419
+ 'RequestId' => array(
5420
+ 'location' => 'header',
5421
+ 'sentAs' => 'x-amz-request-id',
5422
+ ),
5423
+ ),
5424
+ ),
5425
  'PutBucketLoggingOutput' => array(
5426
  'type' => 'object',
5427
  'additionalProperties' => true,
5442
  ),
5443
  ),
5444
  ),
5445
+ 'PutBucketNotificationConfigurationOutput' => array(
5446
+ 'type' => 'object',
5447
+ 'additionalProperties' => true,
5448
+ 'properties' => array(
5449
+ 'RequestId' => array(
5450
+ 'location' => 'header',
5451
+ 'sentAs' => 'x-amz-request-id',
5452
+ ),
5453
+ ),
5454
+ ),
5455
  'PutBucketPolicyOutput' => array(
5456
  'type' => 'object',
5457
  'additionalProperties' => true,
5760
  'NoSuchKey',
5761
  ),
5762
  ),
5763
+ 'ObjectNotExists' => array(
5764
+ 'operation' => 'HeadObject',
5765
+ 'success.type' => 'error',
5766
+ 'success.value' => 'NoSuchKey'
5767
+ ),
5768
  ),
5769
  );
lib/amazon/aws/aws-sdk-php/src/Aws/S3/ResumableDownload.php CHANGED
@@ -34,13 +34,13 @@ class ResumableDownload
34
  /** @var S3Client The S3 client to use to download objects and issue HEAD requests */
35
  protected $client;
36
 
37
- /** @var \Guzzle\Service\Resource\Model Model object returned when the initial HeadObject operation was called */
38
  protected $meta;
39
 
40
  /** @var array Array of parameters to pass to a GetObject operation */
41
  protected $params;
42
 
43
- /** @var \Guzzle\Http\EntityBody Where the object will be downloaded */
44
  protected $target;
45
 
46
  /**
34
  /** @var S3Client The S3 client to use to download objects and issue HEAD requests */
35
  protected $client;
36
 
37
+ /** @var Model Model object returned when the initial HeadObject operation was called */
38
  protected $meta;
39
 
40
  /** @var array Array of parameters to pass to a GetObject operation */
41
  protected $params;
42
 
43
+ /** @var EntityBody Where the object will be downloaded */
44
  protected $target;
45
 
46
  /**
lib/amazon/aws/aws-sdk-php/src/Aws/S3/S3Client.php CHANGED
@@ -69,9 +69,11 @@ use Guzzle\Service\Resource\ResourceIteratorInterface;
69
  * @method Model getBucketAcl(array $args = array()) {@command S3 GetBucketAcl}
70
  * @method Model getBucketCors(array $args = array()) {@command S3 GetBucketCors}
71
  * @method Model getBucketLifecycle(array $args = array()) {@command S3 GetBucketLifecycle}
 
72
  * @method Model getBucketLocation(array $args = array()) {@command S3 GetBucketLocation}
73
  * @method Model getBucketLogging(array $args = array()) {@command S3 GetBucketLogging}
74
  * @method Model getBucketNotification(array $args = array()) {@command S3 GetBucketNotification}
 
75
  * @method Model getBucketPolicy(array $args = array()) {@command S3 GetBucketPolicy}
76
  * @method Model getBucketReplication(array $args = array()) {@command S3 GetBucketReplication}
77
  * @method Model getBucketRequestPayment(array $args = array()) {@command S3 GetBucketRequestPayment}
@@ -91,8 +93,10 @@ use Guzzle\Service\Resource\ResourceIteratorInterface;
91
  * @method Model putBucketAcl(array $args = array()) {@command S3 PutBucketAcl}
92
  * @method Model putBucketCors(array $args = array()) {@command S3 PutBucketCors}
93
  * @method Model putBucketLifecycle(array $args = array()) {@command S3 PutBucketLifecycle}
 
94
  * @method Model putBucketLogging(array $args = array()) {@command S3 PutBucketLogging}
95
  * @method Model putBucketNotification(array $args = array()) {@command S3 PutBucketNotification}
 
96
  * @method Model putBucketPolicy(array $args = array()) {@command S3 PutBucketPolicy}
97
  * @method Model putBucketReplication(array $args = array()) {@command S3 PutBucketReplication}
98
  * @method Model putBucketRequestPayment(array $args = array()) {@command S3 PutBucketRequestPayment}
@@ -167,7 +171,8 @@ class S3Client extends AbstractClient
167
 
168
  // Configure the custom exponential backoff plugin for retrying S3 specific errors
169
  if (!isset($config[Options::BACKOFF])) {
170
- $config[Options::BACKOFF] = static::createBackoffPlugin($exceptionParser);
 
171
  }
172
 
173
  $config[Options::SIGNATURE] = $signature = static::createSignature($config);
@@ -239,15 +244,17 @@ class S3Client extends AbstractClient
239
  *
240
  * @return BackoffPlugin
241
  */
242
- private static function createBackoffPlugin(S3ExceptionParser $exceptionParser)
243
  {
244
  return new BackoffPlugin(
245
- new TruncatedBackoffStrategy(3,
246
- new CurlBackoffStrategy(null,
247
- new HttpBackoffStrategy(null,
248
- new SocketTimeoutChecker(
249
- new ExpiredCredentialsChecker($exceptionParser,
250
- new ExponentialBackoffStrategy()
 
 
251
  )
252
  )
253
  )
@@ -344,6 +351,12 @@ class S3Client extends AbstractClient
344
  * Returns the URL to an object identified by its bucket and key. If an expiration time is provided, the URL will
345
  * be signed and set to expire at the provided time.
346
  *
 
 
 
 
 
 
347
  * @param string $bucket The name of the bucket where the object is located
348
  * @param string $key The key of the object
349
  * @param mixed $expires The time at which the URL should expire
69
  * @method Model getBucketAcl(array $args = array()) {@command S3 GetBucketAcl}
70
  * @method Model getBucketCors(array $args = array()) {@command S3 GetBucketCors}
71
  * @method Model getBucketLifecycle(array $args = array()) {@command S3 GetBucketLifecycle}
72
+ * @method Model getBucketLifecycleConfiguration(array $args = array()) {@command S3 GetBucketLifecycleConfiguration}
73
  * @method Model getBucketLocation(array $args = array()) {@command S3 GetBucketLocation}
74
  * @method Model getBucketLogging(array $args = array()) {@command S3 GetBucketLogging}
75
  * @method Model getBucketNotification(array $args = array()) {@command S3 GetBucketNotification}
76
+ * @method Model getBucketNotificationConfiguration(array $args = array()) {@command S3 GetBucketNotificationConfiguration}
77
  * @method Model getBucketPolicy(array $args = array()) {@command S3 GetBucketPolicy}
78
  * @method Model getBucketReplication(array $args = array()) {@command S3 GetBucketReplication}
79
  * @method Model getBucketRequestPayment(array $args = array()) {@command S3 GetBucketRequestPayment}
93
  * @method Model putBucketAcl(array $args = array()) {@command S3 PutBucketAcl}
94
  * @method Model putBucketCors(array $args = array()) {@command S3 PutBucketCors}
95
  * @method Model putBucketLifecycle(array $args = array()) {@command S3 PutBucketLifecycle}
96
+ * @method Model putBucketLifecycleConfiguration(array $args = array()) {@command S3 PutBucketLifecycleConfiguration}
97
  * @method Model putBucketLogging(array $args = array()) {@command S3 PutBucketLogging}
98
  * @method Model putBucketNotification(array $args = array()) {@command S3 PutBucketNotification}
99
+ * @method Model putBucketNotificationConfiguration(array $args = array()) {@command S3 PutBucketNotificationConfiguration}
100
  * @method Model putBucketPolicy(array $args = array()) {@command S3 PutBucketPolicy}
101
  * @method Model putBucketReplication(array $args = array()) {@command S3 PutBucketReplication}
102
  * @method Model putBucketRequestPayment(array $args = array()) {@command S3 PutBucketRequestPayment}
171
 
172
  // Configure the custom exponential backoff plugin for retrying S3 specific errors
173
  if (!isset($config[Options::BACKOFF])) {
174
+ $retries = isset($config[Options::BACKOFF_RETRIES]) ? $config[Options::BACKOFF_RETRIES] : 3;
175
+ $config[Options::BACKOFF] = static::createBackoffPlugin($exceptionParser, $retries);
176
  }
177
 
178
  $config[Options::SIGNATURE] = $signature = static::createSignature($config);
244
  *
245
  * @return BackoffPlugin
246
  */
247
+ private static function createBackoffPlugin(S3ExceptionParser $exceptionParser, $retries = 3)
248
  {
249
  return new BackoffPlugin(
250
+ new TruncatedBackoffStrategy($retries,
251
+ new IncompleteMultipartUploadChecker(
252
+ new CurlBackoffStrategy(null,
253
+ new HttpBackoffStrategy(null,
254
+ new SocketTimeoutChecker(
255
+ new ExpiredCredentialsChecker($exceptionParser,
256
+ new ExponentialBackoffStrategy()
257
+ )
258
  )
259
  )
260
  )
351
  * Returns the URL to an object identified by its bucket and key. If an expiration time is provided, the URL will
352
  * be signed and set to expire at the provided time.
353
  *
354
+ * Note: This method does not ensure that the generated URL is valid. For example, the bucket referenced may not
355
+ * exist, the key referenced may not exist, and the URL might include parameters that require it to be signed.
356
+ * If you need to use parameters that require a signed URL (e.g., ResponseCacheControl), then you must sign the
357
+ * URL either by providing an $expires argument or by signing the URL returned by this method in some other
358
+ * manner.
359
+ *
360
  * @param string $bucket The name of the bucket where the object is located
361
  * @param string $key The key of the object
362
  * @param mixed $expires The time at which the URL should expire
lib/amazon/aws/aws-sdk-php/src/Aws/S3/StreamWrapper.php CHANGED
@@ -178,15 +178,15 @@ class StreamWrapper
178
 
179
  if (!$errors) {
180
  if ($mode == 'r') {
181
- $this->openReadStream($params, $errors);
182
  } elseif ($mode == 'a') {
183
- $this->openAppendStream($params, $errors);
184
  } else {
185
- $this->openWriteStream($params, $errors);
186
  }
187
  }
188
 
189
- return $errors ? $this->triggerError($errors) : true;
190
  }
191
 
192
  /**
@@ -691,6 +691,19 @@ class StreamWrapper
691
  $factory = $this->getOption('stream_factory') ?: new PhpStreamRequestFactory();
692
  $this->body = $factory->fromRequest($request, array(), array('stream_class' => 'Guzzle\Http\EntityBody'));
693
 
 
 
 
 
 
 
 
 
 
 
 
 
 
694
  // Wrap the body in a caching entity body if seeking is allowed
695
  if ($this->getOption('seekable')) {
696
  $this->body = new CachingEntityBody($this->body);
@@ -710,6 +723,8 @@ class StreamWrapper
710
  protected function openWriteStream(array $params, array &$errors)
711
  {
712
  $this->body = new EntityBody(fopen('php://temp', 'r+'));
 
 
713
  }
714
 
715
  /**
178
 
179
  if (!$errors) {
180
  if ($mode == 'r') {
181
+ return $this->openReadStream($params, $errors);
182
  } elseif ($mode == 'a') {
183
+ return $this->openAppendStream($params, $errors);
184
  } else {
185
+ return $this->openWriteStream($params, $errors);
186
  }
187
  }
188
 
189
+ return $this->triggerError($errors);
190
  }
191
 
192
  /**
691
  $factory = $this->getOption('stream_factory') ?: new PhpStreamRequestFactory();
692
  $this->body = $factory->fromRequest($request, array(), array('stream_class' => 'Guzzle\Http\EntityBody'));
693
 
694
+ // Headers are placed in the "wrapper_data" array. The array of headers
695
+ // is simply an array of header lines of which the first line is the
696
+ // status line of the HTTP response.
697
+ $headers = $this->body->getMetaData('wrapper_data');
698
+
699
+ if ($headers && isset($headers[0])) {
700
+ $statusParts = explode(' ', $headers[0]);
701
+ $status = $statusParts[1];
702
+ if ($status != 200) {
703
+ return $this->triggerError('Cannot open file: ' . $this->body);
704
+ }
705
+ }
706
+
707
  // Wrap the body in a caching entity body if seeking is allowed
708
  if ($this->getOption('seekable')) {
709
  $this->body = new CachingEntityBody($this->body);
723
  protected function openWriteStream(array $params, array &$errors)
724
  {
725
  $this->body = new EntityBody(fopen('php://temp', 'r+'));
726
+
727
+ return true;
728
  }
729
 
730
  /**
lib/amazon/aws/aws-sdk-php/src/Aws/S3/Sync/AbstractSyncBuilder.php CHANGED
@@ -18,7 +18,6 @@ namespace Aws\S3\Sync;
18
 
19
  use Aws\Common\Exception\RuntimeException;
20
  use Aws\Common\Exception\UnexpectedValueException;
21
- use Aws\Common\Model\MultipartUpload\TransferInterface;
22
  use Aws\S3\S3Client;
23
  use Aws\S3\Iterator\OpendirIterator;
24
  use Guzzle\Common\Event;
18
 
19
  use Aws\Common\Exception\RuntimeException;
20
  use Aws\Common\Exception\UnexpectedValueException;
 
21
  use Aws\S3\S3Client;
22
  use Aws\S3\Iterator\OpendirIterator;
23
  use Guzzle\Common\Event;
lib/amazon/aws/aws-sdk-php/src/Aws/S3/Sync/UploadSyncBuilder.php CHANGED
@@ -16,7 +16,7 @@
16
 
17
  namespace Aws\S3\Sync;
18
 
19
- use \FilesystemIterator as FI;
20
  use Aws\Common\Model\MultipartUpload\AbstractTransfer;
21
  use Aws\S3\Model\Acp;
22
  use Guzzle\Common\HasDispatcherInterface;
16
 
17
  namespace Aws\S3\Sync;
18
 
19
+ use FilesystemIterator as FI;
20
  use Aws\Common\Model\MultipartUpload\AbstractTransfer;
21
  use Aws\S3\Model\Acp;
22
  use Guzzle\Common\HasDispatcherInterface;
lib/amazon/composer/ClassLoader.php CHANGED
@@ -13,9 +13,7 @@
13
  namespace Composer\Autoload;
14
 
15
  /**
16
- * ClassLoader implements a PSR-0 class loader
17
- *
18
- * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
19
  *
20
  * $loader = new \Composer\Autoload\ClassLoader();
21
  *
@@ -39,6 +37,8 @@ namespace Composer\Autoload;
39
  *
40
  * @author Fabien Potencier <fabien@symfony.com>
41
  * @author Jordi Boggiano <j.boggiano@seld.be>
 
 
42
  */
43
  class ClassLoader
44
  {
@@ -53,13 +53,14 @@ class ClassLoader
53
 
54
  private $useIncludePath = false;
55
  private $classMap = array();
56
-
57
  private $classMapAuthoritative = false;
 
 
58
 
59
  public function getPrefixes()
60
  {
61
  if (!empty($this->prefixesPsr0)) {
62
- return call_user_func_array('array_merge', $this->prefixesPsr0);
63
  }
64
 
65
  return array();
@@ -147,7 +148,7 @@ class ClassLoader
147
  * appending or prepending to the ones previously set for this namespace.
148
  *
149
  * @param string $prefix The prefix/namespace, with trailing '\\'
150
- * @param array|string $paths The PSR-0 base directories
151
  * @param bool $prepend Whether to prepend the directories
152
  *
153
  * @throws \InvalidArgumentException
@@ -271,6 +272,26 @@ class ClassLoader
271
  return $this->classMapAuthoritative;
272
  }
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  /**
275
  * Registers this instance as an autoloader.
276
  *
@@ -313,29 +334,34 @@ class ClassLoader
313
  */
314
  public function findFile($class)
315
  {
316
- // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
- if ('\\' == $class[0]) {
318
- $class = substr($class, 1);
319
- }
320
-
321
  // class map lookup
322
  if (isset($this->classMap[$class])) {
323
  return $this->classMap[$class];
324
  }
325
- if ($this->classMapAuthoritative) {
326
  return false;
327
  }
 
 
 
 
 
 
328
 
329
  $file = $this->findFileWithExtension($class, '.php');
330
 
331
  // Search for Hack files if we are running on HHVM
332
- if ($file === null && defined('HHVM_VERSION')) {
333
  $file = $this->findFileWithExtension($class, '.hh');
334
  }
335
 
336
- if ($file === null) {
 
 
 
 
337
  // Remember that this class does not exist.
338
- return $this->classMap[$class] = false;
339
  }
340
 
341
  return $file;
@@ -348,10 +374,14 @@ class ClassLoader
348
 
349
  $first = $class[0];
350
  if (isset($this->prefixLengthsPsr4[$first])) {
351
- foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
- if (0 === strpos($class, $prefix)) {
353
- foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
 
 
 
 
355
  return $file;
356
  }
357
  }
@@ -361,7 +391,7 @@ class ClassLoader
361
 
362
  // PSR-4 fallback dirs
363
  foreach ($this->fallbackDirsPsr4 as $dir) {
364
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365
  return $file;
366
  }
367
  }
@@ -380,7 +410,7 @@ class ClassLoader
380
  foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381
  if (0 === strpos($class, $prefix)) {
382
  foreach ($dirs as $dir) {
383
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384
  return $file;
385
  }
386
  }
@@ -390,7 +420,7 @@ class ClassLoader
390
 
391
  // PSR-0 fallback dirs
392
  foreach ($this->fallbackDirsPsr0 as $dir) {
393
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394
  return $file;
395
  }
396
  }
@@ -399,6 +429,8 @@ class ClassLoader
399
  if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400
  return $file;
401
  }
 
 
402
  }
403
  }
404
 
13
  namespace Composer\Autoload;
14
 
15
  /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 
 
17
  *
18
  * $loader = new \Composer\Autoload\ClassLoader();
19
  *
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see https://www.php-fig.org/psr/psr-0/
41
+ * @see https://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
53
 
54
  private $useIncludePath = false;
55
  private $classMap = array();
 
56
  private $classMapAuthoritative = false;
57
+ private $missingClasses = array();
58
+ private $apcuPrefix;
59
 
60
  public function getPrefixes()
61
  {
62
  if (!empty($this->prefixesPsr0)) {
63
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
64
  }
65
 
66
  return array();
148
  * appending or prepending to the ones previously set for this namespace.
149
  *
150
  * @param string $prefix The prefix/namespace, with trailing '\\'
151
+ * @param array|string $paths The PSR-4 base directories
152
  * @param bool $prepend Whether to prepend the directories
153
  *
154
  * @throws \InvalidArgumentException
272
  return $this->classMapAuthoritative;
273
  }
274
 
275
+ /**
276
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
+ *
278
+ * @param string|null $apcuPrefix
279
+ */
280
+ public function setApcuPrefix($apcuPrefix)
281
+ {
282
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
283
+ }
284
+
285
+ /**
286
+ * The APCu prefix in use, or null if APCu caching is not enabled.
287
+ *
288
+ * @return string|null
289
+ */
290
+ public function getApcuPrefix()
291
+ {
292
+ return $this->apcuPrefix;
293
+ }
294
+
295
  /**
296
  * Registers this instance as an autoloader.
297
  *
334
  */
335
  public function findFile($class)
336
  {
 
 
 
 
 
337
  // class map lookup
338
  if (isset($this->classMap[$class])) {
339
  return $this->classMap[$class];
340
  }
341
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
342
  return false;
343
  }
344
+ if (null !== $this->apcuPrefix) {
345
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
346
+ if ($hit) {
347
+ return $file;
348
+ }
349
+ }
350
 
351
  $file = $this->findFileWithExtension($class, '.php');
352
 
353
  // Search for Hack files if we are running on HHVM
354
+ if (false === $file && defined('HHVM_VERSION')) {
355
  $file = $this->findFileWithExtension($class, '.hh');
356
  }
357
 
358
+ if (null !== $this->apcuPrefix) {
359
+ apcu_add($this->apcuPrefix.$class, $file);
360
+ }
361
+
362
+ if (false === $file) {
363
  // Remember that this class does not exist.
364
+ $this->missingClasses[$class] = true;
365
  }
366
 
367
  return $file;
374
 
375
  $first = $class[0];
376
  if (isset($this->prefixLengthsPsr4[$first])) {
377
+ $subPath = $class;
378
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
379
+ $subPath = substr($subPath, 0, $lastPos);
380
+ $search = $subPath . '\\';
381
+ if (isset($this->prefixDirsPsr4[$search])) {
382
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
384
+ if (file_exists($file = $dir . $pathEnd)) {
385
  return $file;
386
  }
387
  }
391
 
392
  // PSR-4 fallback dirs
393
  foreach ($this->fallbackDirsPsr4 as $dir) {
394
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
395
  return $file;
396
  }
397
  }
410
  foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
411
  if (0 === strpos($class, $prefix)) {
412
  foreach ($dirs as $dir) {
413
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
414
  return $file;
415
  }
416
  }
420
 
421
  // PSR-0 fallback dirs
422
  foreach ($this->fallbackDirsPsr0 as $dir) {
423
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
424
  return $file;
425
  }
426
  }
429
  if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
430
  return $file;
431
  }
432
+
433
+ return false;
434
  }
435
  }
436
 
lib/amazon/composer/InstalledVersions.php ADDED
@@ -0,0 +1,400 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+ namespace Composer;
14
+
15
+ use Composer\Semver\VersionParser;
16
+
17
+
18
+
19
+
20
+
21
+
22
+ class InstalledVersions
23
+ {
24
+ private static $installed = array (
25
+ 'root' =>
26
+ array (
27
+ 'pretty_version' => '1.0.0+no-version-set',
28
+ 'version' => '1.0.0.0',
29
+ 'aliases' =>
30
+ array (
31
+ ),
32
+ 'reference' => NULL,
33
+ 'name' => '__root__',
34
+ ),
35
+ 'versions' =>
36
+ array (
37
+ '__root__' =>
38
+ array (
39
+ 'pretty_version' => '1.0.0+no-version-set',
40
+ 'version' => '1.0.0.0',
41
+ 'aliases' =>
42
+ array (
43
+ ),
44
+ 'reference' => NULL,
45
+ ),
46
+ 'aws/aws-sdk-php' =>
47
+ array (
48
+ 'pretty_version' => '2.8.31',
49
+ 'version' => '2.8.31.0',
50
+ 'aliases' =>
51
+ array (
52
+ ),
53
+ 'reference' => '64fa4b07f056e338a5f0f29eece75babaa83af68',
54
+ ),
55
+ 'guzzle/batch' =>
56
+ array (
57
+ 'replaced' =>
58
+ array (
59
+ 0 => 'v3.9.3',
60
+ ),
61
+ ),
62
+ 'guzzle/cache' =>
63
+ array (
64
+ 'replaced' =>
65
+ array (
66
+ 0 => 'v3.9.3',
67
+ ),
68
+ ),
69
+ 'guzzle/common' =>
70
+ array (
71
+ 'replaced' =>
72
+ array (
73
+ 0 => 'v3.9.3',
74
+ ),
75
+ ),
76
+ 'guzzle/guzzle' =>
77
+ array (
78
+ 'pretty_version' => 'v3.9.3',
79
+ 'version' => '3.9.3.0',
80
+ 'aliases' =>
81
+ array (
82
+ ),
83
+ 'reference' => '0645b70d953bc1c067bbc8d5bc53194706b628d9',
84
+ ),
85
+ 'guzzle/http' =>
86
+ array (
87
+ 'replaced' =>
88
+ array (
89
+ 0 => 'v3.9.3',
90
+ ),
91
+ ),
92
+ 'guzzle/inflection' =>
93
+ array (
94
+ 'replaced' =>
95
+ array (
96
+ 0 => 'v3.9.3',
97
+ ),
98
+ ),
99
+ 'guzzle/iterator' =>
100
+ array (
101
+ 'replaced' =>
102
+ array (
103
+ 0 => 'v3.9.3',
104
+ ),
105
+ ),
106
+ 'guzzle/log' =>
107
+ array (
108
+ 'replaced' =>
109
+ array (
110
+ 0 => 'v3.9.3',
111
+ ),
112
+ ),
113
+ 'guzzle/parser' =>
114
+ array (
115
+ 'replaced' =>
116
+ array (
117
+ 0 => 'v3.9.3',
118
+ ),
119
+ ),
120
+ 'guzzle/plugin' =>
121
+ array (
122
+ 'replaced' =>
123
+ array (
124
+ 0 => 'v3.9.3',
125
+ ),
126
+ ),
127
+ 'guzzle/plugin-async' =>
128
+ array (
129
+ 'replaced' =>
130
+ array (
131
+ 0 => 'v3.9.3',
132
+ ),
133
+ ),
134
+ 'guzzle/plugin-backoff' =>
135
+ array (
136
+ 'replaced' =>
137
+ array (
138
+ 0 => 'v3.9.3',
139
+ ),
140
+ ),
141
+ 'guzzle/plugin-cache' =>
142
+ array (
143
+ 'replaced' =>
144
+ array (
145
+ 0 => 'v3.9.3',
146
+ ),
147
+ ),
148
+ 'guzzle/plugin-cookie' =>
149
+ array (
150
+ 'replaced' =>
151
+ array (
152
+ 0 => 'v3.9.3',
153
+ ),
154
+ ),
155
+ 'guzzle/plugin-curlauth' =>
156
+ array (
157
+ 'replaced' =>
158
+ array (
159
+ 0 => 'v3.9.3',
160
+ ),
161
+ ),
162
+ 'guzzle/plugin-error-response' =>
163
+ array (
164
+ 'replaced' =>
165
+ array (
166
+ 0 => 'v3.9.3',
167
+ ),
168
+ ),
169
+ 'guzzle/plugin-history' =>
170
+ array (
171
+ 'replaced' =>
172
+ array (
173
+ 0 => 'v3.9.3',
174
+ ),
175
+ ),
176
+ 'guzzle/plugin-log' =>
177
+ array (
178
+ 'replaced' =>
179
+ array (
180
+ 0 => 'v3.9.3',
181
+ ),
182
+ ),
183
+ 'guzzle/plugin-md5' =>
184
+ array (
185
+ 'replaced' =>
186
+ array (
187
+ 0 => 'v3.9.3',
188
+ ),
189
+ ),
190
+ 'guzzle/plugin-mock' =>
191
+ array (
192
+ 'replaced' =>
193
+ array (
194
+ 0 => 'v3.9.3',
195
+ ),
196
+ ),
197
+ 'guzzle/plugin-oauth' =>
198
+ array (
199
+ 'replaced' =>
200
+ array (
201
+ 0 => 'v3.9.3',
202
+ ),
203
+ ),
204
+ 'guzzle/service' =>
205
+ array (
206
+ 'replaced' =>
207
+ array (
208
+ 0 => 'v3.9.3',
209
+ ),
210
+ ),
211
+ 'guzzle/stream' =>
212
+ array (
213
+ 'replaced' =>
214
+ array (
215
+ 0 => 'v3.9.3',
216
+ ),
217
+ ),
218
+ 'symfony/event-dispatcher' =>
219
+ array (
220
+ 'pretty_version' => 'v2.8.52',
221
+ 'version' => '2.8.52.0',
222
+ 'aliases' =>
223
+ array (
224
+ ),
225
+ 'reference' => 'a77e974a5fecb4398833b0709210e3d5e334ffb0',
226
+ ),
227
+ ),
228
+ );
229
+
230
+
231
+
232
+
233
+
234
+
235
+
236
+ public static function getInstalledPackages()
237
+ {
238
+ return array_keys(self::$installed['versions']);
239
+ }
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+
248
+
249
+ public static function isInstalled($packageName)
250
+ {
251
+ return isset(self::$installed['versions'][$packageName]);
252
+ }
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+
266
+
267
+ public static function satisfies(VersionParser $parser, $packageName, $constraint)
268
+ {
269
+ $constraint = $parser->parseConstraints($constraint);
270
+ $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
271
+
272
+ return $provided->matches($constraint);
273
+ }
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+ public static function getVersionRanges($packageName)
285
+ {
286
+ if (!isset(self::$installed['versions'][$packageName])) {
287
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
288
+ }
289
+
290
+ $ranges = array();
291
+ if (isset(self::$installed['versions'][$packageName]['pretty_version'])) {
292
+ $ranges[] = self::$installed['versions'][$packageName]['pretty_version'];
293
+ }
294
+ if (array_key_exists('aliases', self::$installed['versions'][$packageName])) {
295
+ $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']);
296
+ }
297
+ if (array_key_exists('replaced', self::$installed['versions'][$packageName])) {
298
+ $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']);
299
+ }
300
+ if (array_key_exists('provided', self::$installed['versions'][$packageName])) {
301
+ $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']);
302
+ }
303
+
304
+ return implode(' || ', $ranges);
305
+ }
306
+
307
+
308
+
309
+
310
+
311
+ public static function getVersion($packageName)
312
+ {
313
+ if (!isset(self::$installed['versions'][$packageName])) {
314
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
315
+ }
316
+
317
+ if (!isset(self::$installed['versions'][$packageName]['version'])) {
318
+ return null;
319
+ }
320
+
321
+ return self::$installed['versions'][$packageName]['version'];
322
+ }
323
+
324
+
325
+
326
+
327
+
328
+ public static function getPrettyVersion($packageName)
329
+ {
330
+ if (!isset(self::$installed['versions'][$packageName])) {
331
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
332
+ }
333
+
334
+ if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) {
335
+ return null;
336
+ }
337
+
338
+ return self::$installed['versions'][$packageName]['pretty_version'];
339
+ }
340
+
341
+
342
+
343
+
344
+
345
+ public static function getReference($packageName)
346
+ {
347
+ if (!isset(self::$installed['versions'][$packageName])) {
348
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
349
+ }
350
+
351
+ if (!isset(self::$installed['versions'][$packageName]['reference'])) {
352
+ return null;
353
+ }
354
+
355
+ return self::$installed['versions'][$packageName]['reference'];
356
+ }
357
+
358
+
359
+
360
+
361
+
362
+ public static function getRootPackage()
363
+ {
364
+ return self::$installed['root'];
365
+ }
366
+
367
+
368
+
369
+
370
+
371
+
372
+
373
+ public static function getRawData()
374
+ {
375
+ return self::$installed;
376
+ }
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+
387
+
388
+
389
+
390
+
391
+
392
+
393
+
394
+
395
+
396
+ public static function reload($data)
397
+ {
398
+ self::$installed = $data;
399
+ }
400
+ }
lib/amazon/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
lib/amazon/composer/autoload_classmap.php CHANGED
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
  );
lib/amazon/composer/autoload_files.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_files.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'ce89ac35a6c330c55f4710717db9ff78' => $vendorDir . '/kriswallsmith/assetic/src/functions.php',
10
+ 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
11
+ '3919eeb97e98d4648304477f8ef734ba' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php',
12
+ );
lib/amazon/composer/autoload_namespaces.php CHANGED
@@ -6,7 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
10
  'Guzzle\\Tests' => array($vendorDir . '/guzzle/guzzle/tests'),
11
  'Guzzle' => array($vendorDir . '/guzzle/guzzle/src'),
12
  'Aws' => array($vendorDir . '/aws/aws-sdk-php/src'),
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  'Guzzle\\Tests' => array($vendorDir . '/guzzle/guzzle/tests'),
10
  'Guzzle' => array($vendorDir . '/guzzle/guzzle/src'),
11
  'Aws' => array($vendorDir . '/aws/aws-sdk-php/src'),
lib/amazon/composer/autoload_psr4.php CHANGED
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
10
  );
lib/amazon/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInitc0e9593f4594291c0bfbb43cf84f3f53
6
  {
7
  private static $loader;
8
 
@@ -13,29 +13,41 @@ class ComposerAutoloaderInitc0e9593f4594291c0bfbb43cf84f3f53
13
  }
14
  }
15
 
 
 
 
16
  public static function getLoader()
17
  {
18
  if (null !== self::$loader) {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInitc0e9593f4594291c0bfbb43cf84f3f53', 'loadClassLoader'), true, true);
23
- self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInitc0e9593f4594291c0bfbb43cf84f3f53', 'loadClassLoader'));
25
-
26
- $map = require __DIR__ . '/autoload_namespaces.php';
27
- foreach ($map as $namespace => $path) {
28
- $loader->set($namespace, $path);
29
- }
30
-
31
- $map = require __DIR__ . '/autoload_psr4.php';
32
- foreach ($map as $namespace => $path) {
33
- $loader->setPsr4($namespace, $path);
34
- }
35
 
36
- $classMap = require __DIR__ . '/autoload_classmap.php';
37
- if ($classMap) {
38
- $loader->addClassMap($classMap);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
  $loader->register(true);
@@ -43,8 +55,3 @@ class ComposerAutoloaderInitc0e9593f4594291c0bfbb43cf84f3f53
43
  return $loader;
44
  }
45
  }
46
-
47
- function composerRequirec0e9593f4594291c0bfbb43cf84f3f53($file)
48
- {
49
- require $file;
50
- }
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInita18f93306907d0e5d733e09482ad91d6
6
  {
7
  private static $loader;
8
 
13
  }
14
  }
15
 
16
+ /**
17
+ * @return \Composer\Autoload\ClassLoader
18
+ */
19
  public static function getLoader()
20
  {
21
  if (null !== self::$loader) {
22
  return self::$loader;
23
  }
24
 
25
+ require __DIR__ . '/platform_check.php';
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ spl_autoload_register(array('ComposerAutoloaderInita18f93306907d0e5d733e09482ad91d6', 'loadClassLoader'), true, true);
28
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
29
+ spl_autoload_unregister(array('ComposerAutoloaderInita18f93306907d0e5d733e09482ad91d6', 'loadClassLoader'));
30
+
31
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
32
+ if ($useStaticLoader) {
33
+ require __DIR__ . '/autoload_static.php';
34
+
35
+ call_user_func(\Composer\Autoload\ComposerStaticInita18f93306907d0e5d733e09482ad91d6::getInitializer($loader));
36
+ } else {
37
+ $map = require __DIR__ . '/autoload_namespaces.php';
38
+ foreach ($map as $namespace => $path) {
39
+ $loader->set($namespace, $path);
40
+ }
41
+
42
+ $map = require __DIR__ . '/autoload_psr4.php';
43
+ foreach ($map as $namespace => $path) {
44
+ $loader->setPsr4($namespace, $path);
45
+ }
46
+
47
+ $classMap = require __DIR__ . '/autoload_classmap.php';
48
+ if ($classMap) {
49
+ $loader->addClassMap($classMap);
50
+ }
51
  }
52
 
53
  $loader->register(true);
55
  return $loader;
56
  }
57
  }
 
 
 
 
 
lib/amazon/composer/autoload_static.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_static.php @generated by Composer
4
+
5
+ namespace Composer\Autoload;
6
+
7
+ class ComposerStaticInita18f93306907d0e5d733e09482ad91d6
8
+ {
9
+ public static $prefixLengthsPsr4 = array (
10
+ 'S' =>
11
+ array (
12
+ 'Symfony\\Component\\EventDispatcher\\' => 34,
13
+ ),
14
+ );
15
+
16
+ public static $prefixDirsPsr4 = array (
17
+ 'Symfony\\Component\\EventDispatcher\\' =>
18
+ array (
19
+ 0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
20
+ ),
21
+ );
22
+
23
+ public static $prefixesPsr0 = array (
24
+ 'G' =>
25
+ array (
26
+ 'Guzzle\\Tests' =>
27
+ array (
28
+ 0 => __DIR__ . '/..' . '/guzzle/guzzle/tests',
29
+ ),
30
+ 'Guzzle' =>
31
+ array (
32
+ 0 => __DIR__ . '/..' . '/guzzle/guzzle/src',
33
+ ),
34
+ ),
35
+ 'A' =>
36
+ array (
37
+ 'Aws' =>
38
+ array (
39
+ 0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src',
40
+ ),
41
+ ),
42
+ );
43
+
44
+ public static $classMap = array (
45
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
46
+ );
47
+
48
+ public static function getInitializer(ClassLoader $loader)
49
+ {
50
+ return \Closure::bind(function () use ($loader) {
51
+ $loader->prefixLengthsPsr4 = ComposerStaticInita18f93306907d0e5d733e09482ad91d6::$prefixLengthsPsr4;
52
+ $loader->prefixDirsPsr4 = ComposerStaticInita18f93306907d0e5d733e09482ad91d6::$prefixDirsPsr4;
53
+ $loader->prefixesPsr0 = ComposerStaticInita18f93306907d0e5d733e09482ad91d6::$prefixesPsr0;
54
+ $loader->classMap = ComposerStaticInita18f93306907d0e5d733e09482ad91d6::$classMap;
55
+
56
+ }, null, ClassLoader::class);
57
+ }
58
+ }
lib/amazon/composer/include_paths.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // include_paths.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ $vendorDir . '/phpseclib/phpseclib/phpseclib',
10
+ );
lib/amazon/composer/installed.json ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "packages": [
3
+ {
4
+ "name": "aws/aws-sdk-php",
5
+ "version": "2.8.31",
6
+ "version_normalized": "2.8.31.0",
7
+ "source": {
8
+ "type": "git",
9
+ "url": "https://github.com/aws/aws-sdk-php.git",
10
+ "reference": "64fa4b07f056e338a5f0f29eece75babaa83af68"
11
+ },
12
+ "dist": {
13
+ "type": "zip",
14
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/64fa4b07f056e338a5f0f29eece75babaa83af68",
15
+ "reference": "64fa4b07f056e338a5f0f29eece75babaa83af68",
16
+ "shasum": ""
17
+ },
18
+ "require": {
19
+ "guzzle/guzzle": "~3.7",
20
+ "php": ">=5.3.3"
21
+ },
22
+ "require-dev": {
23
+ "doctrine/cache": "~1.0",
24
+ "ext-openssl": "*",
25
+ "monolog/monolog": "~1.4",
26
+ "phpunit/phpunit": "~4.0",
27
+ "phpunit/phpunit-mock-objects": "2.3.1",
28
+ "symfony/yaml": "~2.1"
29
+ },
30
+ "suggest": {
31
+ "doctrine/cache": "Adds support for caching of credentials and responses",
32
+ "ext-apc": "Allows service description opcode caching, request and response caching, and credentials caching",
33
+ "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages",
34
+ "monolog/monolog": "Adds support for logging HTTP requests and responses",
35
+ "symfony/yaml": "Eases the ability to write manifests for creating jobs in AWS Import/Export"
36
+ },
37
+ "time": "2016-07-25T18:03:20+00:00",
38
+ "type": "library",
39
+ "installation-source": "dist",
40
+ "autoload": {
41
+ "psr-0": {
42
+ "Aws": "src/"
43
+ }
44
+ },
45
+ "notification-url": "https://packagist.org/downloads/",
46
+ "license": [
47
+ "Apache-2.0"
48
+ ],
49
+ "authors": [
50
+ {
51
+ "name": "Amazon Web Services",
52
+ "homepage": "http://aws.amazon.com"
53
+ }
54
+ ],
55
+ "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
56
+ "homepage": "http://aws.amazon.com/sdkforphp",
57
+ "keywords": [
58
+ "amazon",
59
+ "aws",
60
+ "cloud",
61
+ "dynamodb",
62
+ "ec2",
63
+ "glacier",
64
+ "s3",
65
+ "sdk"
66
+ ],
67
+ "support": {
68
+ "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
69
+ "issues": "https://github.com/aws/aws-sdk-php/issues",
70
+ "source": "https://github.com/aws/aws-sdk-php/tree/2.8.31"
71
+ },
72
+ "install-path": "../aws/aws-sdk-php"
73
+ },
74
+ {
75
+ "name": "guzzle/guzzle",
76
+ "version": "v3.9.3",
77
+ "version_normalized": "3.9.3.0",
78
+ "source": {
79
+ "type": "git",
80
+ "url": "https://github.com/guzzle/guzzle3.git",
81
+ "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9"
82
+ },
83
+ "dist": {
84
+ "type": "zip",
85
+ "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9",
86
+ "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9",
87
+ "shasum": ""
88
+ },
89
+ "require": {
90
+ "ext-curl": "*",
91
+ "php": ">=5.3.3",
92
+ "symfony/event-dispatcher": "~2.1"
93
+ },
94
+ "replace": {
95
+ "guzzle/batch": "self.version",
96
+ "guzzle/cache": "self.version",
97
+ "guzzle/common": "self.version",
98
+ "guzzle/http": "self.version",
99
+ "guzzle/inflection": "self.version",
100
+ "guzzle/iterator": "self.version",
101
+ "guzzle/log": "self.version",
102
+ "guzzle/parser": "self.version",
103
+ "guzzle/plugin": "self.version",
104
+ "guzzle/plugin-async": "self.version",
105
+ "guzzle/plugin-backoff": "self.version",
106
+ "guzzle/plugin-cache": "self.version",
107
+ "guzzle/plugin-cookie": "self.version",
108
+ "guzzle/plugin-curlauth": "self.version",
109
+ "guzzle/plugin-error-response": "self.version",
110
+ "guzzle/plugin-history": "self.version",
111
+ "guzzle/plugin-log": "self.version",
112
+ "guzzle/plugin-md5": "self.version",
113
+ "guzzle/plugin-mock": "self.version",
114
+ "guzzle/plugin-oauth": "self.version",
115
+ "guzzle/service": "self.version",
116
+ "guzzle/stream": "self.version"
117
+ },
118
+ "require-dev": {
119
+ "doctrine/cache": "~1.3",
120
+ "monolog/monolog": "~1.0",
121
+ "phpunit/phpunit": "3.7.*",
122
+ "psr/log": "~1.0",
123
+ "symfony/class-loader": "~2.1",
124
+ "zendframework/zend-cache": "2.*,<2.3",
125
+ "zendframework/zend-log": "2.*,<2.3"
126
+ },
127
+ "suggest": {
128
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
129
+ },
130
+ "time": "2015-03-18T18:23:50+00:00",
131
+ "type": "library",
132
+ "extra": {
133
+ "branch-alias": {
134
+ "dev-master": "3.9-dev"
135
+ }
136
+ },
137
+ "installation-source": "dist",
138
+ "autoload": {
139
+ "psr-0": {
140
+ "Guzzle": "src/",
141
+ "Guzzle\\Tests": "tests/"
142
+ }
143
+ },
144
+ "notification-url": "https://packagist.org/downloads/",
145
+ "license": [
146
+ "MIT"
147
+ ],
148
+ "authors": [
149
+ {
150
+ "name": "Michael Dowling",
151
+ "email": "mtdowling@gmail.com",
152
+ "homepage": "https://github.com/mtdowling"
153
+ },
154
+ {
155
+ "name": "Guzzle Community",
156
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
157
+ }
158
+ ],
159
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
160
+ "homepage": "http://guzzlephp.org/",
161
+ "keywords": [
162
+ "client",
163
+ "curl",
164
+ "framework",
165
+ "http",
166
+ "http client",
167
+ "rest",
168
+ "web service"
169
+ ],
170
+ "support": {
171
+ "issues": "https://github.com/guzzle/guzzle3/issues",
172
+ "source": "https://github.com/guzzle/guzzle3/tree/master"
173
+ },
174
+ "abandoned": "guzzlehttp/guzzle",
175
+ "install-path": "../guzzle/guzzle"
176
+ },
177
+ {
178
+ "name": "symfony/event-dispatcher",
179
+ "version": "v2.8.52",
180
+ "version_normalized": "2.8.52.0",
181
+ "source": {
182
+ "type": "git",
183
+ "url": "https://github.com/symfony/event-dispatcher.git",
184
+ "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0"
185
+ },
186
+ "dist": {
187
+ "type": "zip",
188
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0",
189
+ "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0",
190
+ "shasum": ""
191
+ },
192
+ "require": {
193
+ "php": ">=5.3.9"
194
+ },
195
+ "require-dev": {
196
+ "psr/log": "~1.0",
197
+ "symfony/config": "^2.0.5|~3.0.0",
198
+ "symfony/dependency-injection": "~2.6|~3.0.0",
199
+ "symfony/expression-language": "~2.6|~3.0.0",
200
+ "symfony/stopwatch": "~2.3|~3.0.0"
201
+ },
202
+ "suggest": {
203
+ "symfony/dependency-injection": "",
204
+ "symfony/http-kernel": ""
205
+ },
206
+ "time": "2018-11-21T14:20:20+00:00",
207
+ "type": "library",
208
+ "extra": {
209
+ "branch-alias": {
210
+ "dev-master": "2.8-dev"
211
+ }
212
+ },
213
+ "installation-source": "dist",
214
+ "autoload": {
215
+ "psr-4": {
216
+ "Symfony\\Component\\EventDispatcher\\": ""
217
+ },
218
+ "exclude-from-classmap": [
219
+ "/Tests/"
220
+ ]
221
+ },
222
+ "notification-url": "https://packagist.org/downloads/",
223
+ "license": [
224
+ "MIT"
225
+ ],
226
+ "authors": [
227
+ {
228
+ "name": "Fabien Potencier",
229
+ "email": "fabien@symfony.com"
230
+ },
231
+ {
232
+ "name": "Symfony Community",
233
+ "homepage": "https://symfony.com/contributors"
234
+ }
235
+ ],
236
+ "description": "Symfony EventDispatcher Component",
237
+ "homepage": "https://symfony.com",
238
+ "support": {
239
+ "source": "https://github.com/symfony/event-dispatcher/tree/v2.8.50"
240
+ },
241
+ "install-path": "../symfony/event-dispatcher"
242
+ }
243
+ ],
244
+ "dev": true,
245
+ "dev-package-names": []
246
+ }
lib/amazon/composer/installed.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php return array (
2
+ 'root' =>
3
+ array (
4
+ 'pretty_version' => '1.0.0+no-version-set',
5
+ 'version' => '1.0.0.0',
6
+ 'aliases' =>
7
+ array (
8
+ ),
9
+ 'reference' => NULL,
10
+ 'name' => '__root__',
11
+ ),
12
+ 'versions' =>
13
+ array (
14
+ '__root__' =>
15
+ array (
16
+ 'pretty_version' => '1.0.0+no-version-set',
17
+ 'version' => '1.0.0.0',
18
+ 'aliases' =>
19
+ array (
20
+ ),
21
+ 'reference' => NULL,
22
+ ),
23
+ 'aws/aws-sdk-php' =>
24
+ array (
25
+ 'pretty_version' => '2.8.31',
26
+ 'version' => '2.8.31.0',
27
+ 'aliases' =>
28
+ array (
29
+ ),
30
+ 'reference' => '64fa4b07f056e338a5f0f29eece75babaa83af68',
31
+ ),
32
+ 'guzzle/batch' =>
33
+ array (
34
+ 'replaced' =>
35
+ array (
36
+ 0 => 'v3.9.3',
37
+ ),
38
+ ),
39
+ 'guzzle/cache' =>
40
+ array (
41
+ 'replaced' =>
42
+ array (
43
+ 0 => 'v3.9.3',
44
+ ),
45
+ ),
46
+ 'guzzle/common' =>
47
+ array (
48
+ 'replaced' =>
49
+ array (
50
+ 0 => 'v3.9.3',
51
+ ),
52
+ ),
53
+ 'guzzle/guzzle' =>
54
+ array (
55
+ 'pretty_version' => 'v3.9.3',
56
+ 'version' => '3.9.3.0',
57
+ 'aliases' =>
58
+ array (
59
+ ),
60
+ 'reference' => '0645b70d953bc1c067bbc8d5bc53194706b628d9',
61
+ ),
62
+ 'guzzle/http' =>
63
+ array (
64
+ 'replaced' =>
65
+ array (
66
+ 0 => 'v3.9.3',
67
+ ),
68
+ ),
69
+ 'guzzle/inflection' =>
70
+ array (
71
+ 'replaced' =>
72
+ array (
73
+ 0 => 'v3.9.3',
74
+ ),
75
+ ),
76
+ 'guzzle/iterator' =>
77
+ array (
78
+ 'replaced' =>
79
+ array (
80
+ 0 => 'v3.9.3',
81
+ ),
82
+ ),
83
+ 'guzzle/log' =>
84
+ array (
85
+ 'replaced' =>
86
+ array (
87
+ 0 => 'v3.9.3',
88
+ ),
89
+ ),
90
+ 'guzzle/parser' =>
91
+ array (
92
+ 'replaced' =>
93
+ array (
94
+ 0 => 'v3.9.3',
95
+ ),
96
+ ),
97
+ 'guzzle/plugin' =>
98
+ array (
99
+ 'replaced' =>
100
+ array (
101
+ 0 => 'v3.9.3',
102
+ ),
103
+ ),
104
+ 'guzzle/plugin-async' =>
105
+ array (
106
+ 'replaced' =>
107
+ array (
108
+ 0 => 'v3.9.3',
109
+ ),
110
+ ),
111
+ 'guzzle/plugin-backoff' =>
112
+ array (
113
+ 'replaced' =>
114
+ array (
115
+ 0 => 'v3.9.3',
116
+ ),
117
+ ),
118
+ 'guzzle/plugin-cache' =>
119
+ array (
120
+ 'replaced' =>
121
+ array (
122
+ 0 => 'v3.9.3',
123
+ ),
124
+ ),
125
+ 'guzzle/plugin-cookie' =>
126
+ array (
127
+ 'replaced' =>
128
+ array (
129
+ 0 => 'v3.9.3',
130
+ ),
131
+ ),
132
+ 'guzzle/plugin-curlauth' =>
133
+ array (
134
+ 'replaced' =>
135
+ array (
136
+ 0 => 'v3.9.3',
137
+ ),
138
+ ),
139
+ 'guzzle/plugin-error-response' =>
140
+ array (
141
+ 'replaced' =>
142
+ array (
143
+ 0 => 'v3.9.3',
144
+ ),
145
+ ),
146
+ 'guzzle/plugin-history' =>
147
+ array (
148
+ 'replaced' =>
149
+ array (
150
+ 0 => 'v3.9.3',
151
+ ),
152
+ ),
153
+ 'guzzle/plugin-log' =>
154
+ array (
155
+ 'replaced' =>
156
+ array (
157
+ 0 => 'v3.9.3',
158
+ ),
159
+ ),
160
+ 'guzzle/plugin-md5' =>
161
+ array (
162
+ 'replaced' =>
163
+ array (
164
+ 0 => 'v3.9.3',
165
+ ),
166
+ ),
167
+ 'guzzle/plugin-mock' =>
168
+ array (
169
+ 'replaced' =>
170
+ array (
171
+ 0 => 'v3.9.3',
172
+ ),
173
+ ),
174
+ 'guzzle/plugin-oauth' =>
175
+ array (
176
+ 'replaced' =>
177
+ array (
178
+ 0 => 'v3.9.3',
179
+ ),
180
+ ),
181
+ 'guzzle/service' =>
182
+ array (
183
+ 'replaced' =>
184
+ array (
185
+ 0 => 'v3.9.3',
186
+ ),
187
+ ),
188
+ 'guzzle/stream' =>
189
+ array (
190
+ 'replaced' =>
191
+ array (
192
+ 0 => 'v3.9.3',
193
+ ),
194
+ ),
195
+ 'symfony/event-dispatcher' =>
196
+ array (
197
+ 'pretty_version' => 'v2.8.52',
198
+ 'version' => '2.8.52.0',
199
+ 'aliases' =>
200
+ array (
201
+ ),
202
+ 'reference' => 'a77e974a5fecb4398833b0709210e3d5e334ffb0',
203
+ ),
204
+ ),
205
+ );
lib/amazon/composer/platform_check.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // platform_check.php @generated by Composer
4
+
5
+ $issues = array();
6
+
7
+ if (!(PHP_VERSION_ID >= 50309)) {
8
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 5.3.9". You are running ' . PHP_VERSION . '.';
9
+ }
10
+
11
+ if ($issues) {
12
+ if (!headers_sent()) {
13
+ header('HTTP/1.1 500 Internal Server Error');
14
+ }
15
+ if (!ini_get('display_errors')) {
16
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
17
+ fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
18
+ } elseif (!headers_sent()) {
19
+ echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
20
+ }
21
+ }
22
+ trigger_error(
23
+ 'Composer detected issues in your platform: ' . implode(' ', $issues),
24
+ E_USER_ERROR
25
+ );
26
+ }
lib/amazon/guzzle/guzzle/CHANGELOG.md ADDED
@@ -0,0 +1,751 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CHANGELOG
2
+
3
+ ## 3.9.3 - 2015-03-18
4
+
5
+ * Ensuring Content-Length is not stripped from a request when it is `0`.
6
+ * Added more information to stream wrapper exceptions.
7
+ * Message parser will no longer throw warnings for malformed messages.
8
+ * Giving a valid cache TTL when max-age is 0.
9
+
10
+ ## 3.9.2 - 2014-09-10
11
+
12
+ * Retrying "Connection died, retrying a fresh connect" curl errors.
13
+ * Automatically extracting the cacert from the phar in client constructor.
14
+ * Added EntityBody support for OPTIONS requests.
15
+
16
+ ## 3.9.1 - 2014-05-07
17
+
18
+ * Added a fix to ReadLimitEntityBody to ensure it doesn't infinitely loop.
19
+ * Added a fix to the stream checksum function so that when the first read
20
+ returns a falsey value, it still continues to consume the stream until EOF.
21
+
22
+ ## 3.9.0 - 2014-04-23
23
+
24
+ * `null`, `false`, and `"_guzzle_blank_"` all now serialize as an empty value
25
+ with no trailing "=". See dc1d824277.
26
+ * No longer performing an MD5 check on the cacert each time the phar is used,
27
+ but rather copying the cacert to the temp directory.
28
+ * `"0"` can now be added as a URL path
29
+ * Deleting cookies that are set to empty
30
+ * If-Modified-Since is no longer unnecessarily added to the CachePlugin
31
+ * Cookie path matching now follows RFC 6265 s5.1.4
32
+ * Updated service descriptions are now added to a service client's composite
33
+ factory.
34
+ * MockPlugin now throws an exception if the queue is empty.
35
+ * Properly parsing URLs that start with "http" but are not absolute
36
+ * Added the ability to configure the curl_multi_select timeout setting
37
+ * OAuth parameters are now sorted using lexicographical byte value ordering
38
+ * Fixing invalid usage of an out of range PHP feature in the ErrorResponsePlugin
39
+
40
+ ## 3.8.1 -2014-01-28
41
+
42
+ * Bug: Always using GET requests when redirecting from a 303 response
43
+ * Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in
44
+ `Guzzle\Http\ClientInterface::setSslVerification()`
45
+ * Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL
46
+ * Bug: The body of a request can now be set to `"0"`
47
+ * Sending PHP stream requests no longer forces `HTTP/1.0`
48
+ * Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of
49
+ each sub-exception
50
+ * Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than
51
+ clobbering everything).
52
+ * Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators)
53
+ * Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`.
54
+ For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`.
55
+ * Now properly escaping the regular expression delimiter when matching Cookie domains.
56
+ * Network access is now disabled when loading XML documents
57
+
58
+ ## 3.8.0 - 2013-12-05
59
+
60
+ * Added the ability to define a POST name for a file
61
+ * JSON response parsing now properly walks additionalProperties
62
+ * cURL error code 18 is now retried automatically in the BackoffPlugin
63
+ * Fixed a cURL error when URLs contain fragments
64
+ * Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were
65
+ CurlExceptions
66
+ * CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e)
67
+ * Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS`
68
+ * Fixed a bug that was encountered when parsing empty header parameters
69
+ * UriTemplate now has a `setRegex()` method to match the docs
70
+ * The `debug` request parameter now checks if it is truthy rather than if it exists
71
+ * Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin
72
+ * Added the ability to combine URLs using strict RFC 3986 compliance
73
+ * Command objects can now return the validation errors encountered by the command
74
+ * Various fixes to cache revalidation (#437 and 29797e5)
75
+ * Various fixes to the AsyncPlugin
76
+ * Cleaned up build scripts
77
+
78
+ ## 3.7.4 - 2013-10-02
79
+
80
+ * Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430)
81
+ * Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp
82
+ (see https://github.com/aws/aws-sdk-php/issues/147)
83
+ * Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots
84
+ * Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420)
85
+ * Updated the bundled cacert.pem (#419)
86
+ * OauthPlugin now supports adding authentication to headers or query string (#425)
87
+
88
+ ## 3.7.3 - 2013-09-08
89
+
90
+ * Added the ability to get the exception associated with a request/command when using `MultiTransferException` and
91
+ `CommandTransferException`.
92
+ * Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description
93
+ * Schemas are only injected into response models when explicitly configured.
94
+ * No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of
95
+ an EntityBody.
96
+ * Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator.
97
+ * Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`.
98
+ * Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody()
99
+ * Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin
100
+ * Bug fix: Visiting XML attributes first before visting XML children when serializing requests
101
+ * Bug fix: Properly parsing headers that contain commas contained in quotes
102
+ * Bug fix: mimetype guessing based on a filename is now case-insensitive
103
+
104
+ ## 3.7.2 - 2013-08-02
105
+
106
+ * Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander
107
+ See https://github.com/guzzle/guzzle/issues/371
108
+ * Bug fix: Cookie domains are now matched correctly according to RFC 6265
109
+ See https://github.com/guzzle/guzzle/issues/377
110
+ * Bug fix: GET parameters are now used when calculating an OAuth signature
111
+ * Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted
112
+ * `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched
113
+ * `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input.
114
+ See https://github.com/guzzle/guzzle/issues/379
115
+ * Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See
116
+ https://github.com/guzzle/guzzle/pull/380
117
+ * cURL multi cleanup and optimizations
118
+
119
+ ## 3.7.1 - 2013-07-05
120
+
121
+ * Bug fix: Setting default options on a client now works
122
+ * Bug fix: Setting options on HEAD requests now works. See #352
123
+ * Bug fix: Moving stream factory before send event to before building the stream. See #353
124
+ * Bug fix: Cookies no longer match on IP addresses per RFC 6265
125
+ * Bug fix: Correctly parsing header parameters that are in `<>` and quotes
126
+ * Added `cert` and `ssl_key` as request options
127
+ * `Host` header can now diverge from the host part of a URL if the header is set manually
128
+ * `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter
129
+ * OAuth parameters are only added via the plugin if they aren't already set
130
+ * Exceptions are now thrown when a URL cannot be parsed
131
+ * Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails
132
+ * Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin
133
+
134
+ ## 3.7.0 - 2013-06-10
135
+
136
+ * See UPGRADING.md for more information on how to upgrade.
137
+ * Requests now support the ability to specify an array of $options when creating a request to more easily modify a
138
+ request. You can pass a 'request.options' configuration setting to a client to apply default request options to
139
+ every request created by a client (e.g. default query string variables, headers, curl options, etc).
140
+ * Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`.
141
+ See `Guzzle\Http\StaticClient::mount`.
142
+ * Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests
143
+ created by a command (e.g. custom headers, query string variables, timeout settings, etc).
144
+ * Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the
145
+ headers of a response
146
+ * Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key
147
+ (e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`)
148
+ * ServiceBuilders now support storing and retrieving arbitrary data
149
+ * CachePlugin can now purge all resources for a given URI
150
+ * CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource
151
+ * CachePlugin now uses the Vary header to determine if a resource is a cache hit
152
+ * `Guzzle\Http\Message\Response` now implements `\Serializable`
153
+ * Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters
154
+ * `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable
155
+ * Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()`
156
+ * Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size
157
+ * `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message
158
+ * Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older
159
+ Symfony users can still use the old version of Monolog.
160
+ * Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`.
161
+ Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`.
162
+ * Several performance improvements to `Guzzle\Common\Collection`
163
+ * Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
164
+ createRequest, head, delete, put, patch, post, options, prepareRequest
165
+ * Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
166
+ * Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
167
+ * Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
168
+ `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
169
+ resource, string, or EntityBody into the $options parameter to specify the download location of the response.
170
+ * Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
171
+ default `array()`
172
+ * Added `Guzzle\Stream\StreamInterface::isRepeatable`
173
+ * Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
174
+ $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
175
+ $client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`.
176
+ * Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`.
177
+ * Removed `Guzzle\Http\ClientInterface::expandTemplate()`
178
+ * Removed `Guzzle\Http\ClientInterface::setRequestFactory()`
179
+ * Removed `Guzzle\Http\ClientInterface::getCurlMulti()`
180
+ * Removed `Guzzle\Http\Message\RequestInterface::canCache`
181
+ * Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`
182
+ * Removed `Guzzle\Http\Message\RequestInterface::isRedirect`
183
+ * Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
184
+ * You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting
185
+ `Guzzle\Common\Version::$emitWarnings` to true.
186
+ * Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use
187
+ `$request->getResponseBody()->isRepeatable()` instead.
188
+ * Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
189
+ `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
190
+ * Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
191
+ `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
192
+ * Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
193
+ * Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
194
+ * Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
195
+ * Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand.
196
+ These will work through Guzzle 4.0
197
+ * Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params].
198
+ * Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
199
+ * Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`.
200
+ * Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`.
201
+ * Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
202
+ * Marked `Guzzle\Common\Collection::inject()` as deprecated.
203
+ * Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');`
204
+ * CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
205
+ CacheStorageInterface. These two objects and interface will be removed in a future version.
206
+ * Always setting X-cache headers on cached responses
207
+ * Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
208
+ * `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
209
+ $request, Response $response);`
210
+ * `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
211
+ * `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
212
+ * Added `CacheStorageInterface::purge($url)`
213
+ * `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
214
+ $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
215
+ CanCacheStrategyInterface $canCache = null)`
216
+ * Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
217
+
218
+ ## 3.6.0 - 2013-05-29
219
+
220
+ * ServiceDescription now implements ToArrayInterface
221
+ * Added command.hidden_params to blacklist certain headers from being treated as additionalParameters
222
+ * Guzzle can now correctly parse incomplete URLs
223
+ * Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
224
+ * Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
225
+ * Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
226
+ * Specific header implementations can be created for complex headers. When a message creates a header, it uses a
227
+ HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
228
+ CacheControl header implementation.
229
+ * Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
230
+ * Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
231
+ * Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
232
+ Guzzle\Http\Curl\RequestMediator
233
+ * Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
234
+ * Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
235
+ * Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
236
+ * Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
237
+ * Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
238
+ * All response header helper functions return a string rather than mixing Header objects and strings inconsistently
239
+ * Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc are managed by Guzzle
240
+ directly via interfaces
241
+ * Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
242
+ but are a no-op until removed.
243
+ * Most classes that used to require a ``Guzzle\Service\Command\CommandInterface` typehint now request a
244
+ `Guzzle\Service\Command\ArrayCommandInterface`.
245
+ * Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
246
+ on a request while the request is still being transferred
247
+ * The ability to case-insensitively search for header values
248
+ * Guzzle\Http\Message\Header::hasExactHeader
249
+ * Guzzle\Http\Message\Header::raw. Use getAll()
250
+ * Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
251
+ instead.
252
+ * `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
253
+ * Added the ability to cast Model objects to a string to view debug information.
254
+
255
+ ## 3.5.0 - 2013-05-13
256
+
257
+ * Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times
258
+ * Bug: Better cleanup of one-time events accross the board (when an event is meant to fire once, it will now remove
259
+ itself from the EventDispatcher)
260
+ * Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values
261
+ * Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too
262
+ * Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a
263
+ non-existent key
264
+ * Bug: All __call() method arguments are now required (helps with mocking frameworks)
265
+ * Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference
266
+ to help with refcount based garbage collection of resources created by sending a request
267
+ * Deprecating ZF1 cache and log adapters. These will be removed in the next major version.
268
+ * Deprecating `Response::getPreviousResponse()` (method signature still exists, but it'sdeprecated). Use the
269
+ HistoryPlugin for a history.
270
+ * Added a `responseBody` alias for the `response_body` location
271
+ * Refactored internals to no longer rely on Response::getRequest()
272
+ * HistoryPlugin can now be cast to a string
273
+ * HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests
274
+ and responses that are sent over the wire
275
+ * Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects
276
+
277
+ ## 3.4.3 - 2013-04-30
278
+
279
+ * Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response
280
+ * Added a check to re-extract the temp cacert bundle from the phar before sending each request
281
+
282
+ ## 3.4.2 - 2013-04-29
283
+
284
+ * Bug fix: Stream objects now work correctly with "a" and "a+" modes
285
+ * Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present
286
+ * Bug fix: AsyncPlugin no longer forces HEAD requests
287
+ * Bug fix: DateTime timezones are now properly handled when using the service description schema formatter
288
+ * Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails
289
+ * Setting a response on a request will write to the custom request body from the response body if one is specified
290
+ * LogPlugin now writes to php://output when STDERR is undefined
291
+ * Added the ability to set multiple POST files for the same key in a single call
292
+ * application/x-www-form-urlencoded POSTs now use the utf-8 charset by default
293
+ * Added the ability to queue CurlExceptions to the MockPlugin
294
+ * Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send)
295
+ * Configuration loading now allows remote files
296
+
297
+ ## 3.4.1 - 2013-04-16
298
+
299
+ * Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti
300
+ handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost.
301
+ * Exceptions are now properly grouped when sending requests in parallel
302
+ * Redirects are now properly aggregated when a multi transaction fails
303
+ * Redirects now set the response on the original object even in the event of a failure
304
+ * Bug fix: Model names are now properly set even when using $refs
305
+ * Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax
306
+ * Added support for oauth_callback in OAuth signatures
307
+ * Added support for oauth_verifier in OAuth signatures
308
+ * Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection
309
+
310
+ ## 3.4.0 - 2013-04-11
311
+
312
+ * Bug fix: URLs are now resolved correctly based on http://tools.ietf.org/html/rfc3986#section-5.2. #289
313
+ * Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
314
+ * Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
315
+ * Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.
316
+ * Bug fix: Added `number` type to service descriptions.
317
+ * Bug fix: empty parameters are removed from an OAuth signature
318
+ * Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header
319
+ * Bug fix: Fixed "array to string" error when validating a union of types in a service description
320
+ * Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream
321
+ * Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin.
322
+ * Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs.
323
+ * The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections.
324
+ * Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if
325
+ the Content-Type can be determined based on the entity body or the path of the request.
326
+ * Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder.
327
+ * Added support for a PSR-3 LogAdapter.
328
+ * Added a `command.after_prepare` event
329
+ * Added `oauth_callback` parameter to the OauthPlugin
330
+ * Added the ability to create a custom stream class when using a stream factory
331
+ * Added a CachingEntityBody decorator
332
+ * Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized.
333
+ * The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar.
334
+ * You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies
335
+ * POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This
336
+ means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use
337
+ POST fields or files (the latter is only used when emulating a form POST in the browser).
338
+ * Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest
339
+
340
+ ## 3.3.1 - 2013-03-10
341
+
342
+ * Added the ability to create PHP streaming responses from HTTP requests
343
+ * Bug fix: Running any filters when parsing response headers with service descriptions
344
+ * Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing
345
+ * Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across
346
+ response location visitors.
347
+ * Bug fix: Removed the possibility of creating configuration files with circular dependencies
348
+ * RequestFactory::create() now uses the key of a POST file when setting the POST file name
349
+ * Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set
350
+
351
+ ## 3.3.0 - 2013-03-03
352
+
353
+ * A large number of performance optimizations have been made
354
+ * Bug fix: Added 'wb' as a valid write mode for streams
355
+ * Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned
356
+ * Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()`
357
+ * BC: Removed `Guzzle\Http\Utils` class
358
+ * BC: Setting a service description on a client will no longer modify the client's command factories.
359
+ * BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using
360
+ the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
361
+ * BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to
362
+ lowercase
363
+ * Operation parameter objects are now lazy loaded internally
364
+ * Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses
365
+ * Added support for instantiating responseType=class responseClass classes. Classes must implement
366
+ `Guzzle\Service\Command\ResponseClassInterface`
367
+ * Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These
368
+ additional properties also support locations and can be used to parse JSON responses where the outermost part of the
369
+ JSON is an array
370
+ * Added support for nested renaming of JSON models (rename sentAs to name)
371
+ * CachePlugin
372
+ * Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error
373
+ * Debug headers can now added to cached response in the CachePlugin
374
+
375
+ ## 3.2.0 - 2013-02-14
376
+
377
+ * CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients.
378
+ * URLs with no path no longer contain a "/" by default
379
+ * Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url.
380
+ * BadResponseException no longer includes the full request and response message
381
+ * Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface
382
+ * Adding getResponseBody() to Guzzle\Http\Message\RequestInterface
383
+ * Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription
384
+ * Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list
385
+ * xmlEncoding can now be customized for the XML declaration of a XML service description operation
386
+ * Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value
387
+ aggregation and no longer uses callbacks
388
+ * The URL encoding implementation of Guzzle\Http\QueryString can now be customized
389
+ * Bug fix: Filters were not always invoked for array service description parameters
390
+ * Bug fix: Redirects now use a target response body rather than a temporary response body
391
+ * Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded
392
+ * Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives
393
+
394
+ ## 3.1.2 - 2013-01-27
395
+
396
+ * Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the
397
+ response body. For example, the XmlVisitor now parses the XML response into an array in the before() method.
398
+ * Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent
399
+ * CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444)
400
+ * Fixed a bug where redirect responses were not chained correctly using getPreviousResponse()
401
+ * Setting default headers on a client after setting the user-agent will not erase the user-agent setting
402
+
403
+ ## 3.1.1 - 2013-01-20
404
+
405
+ * Adding wildcard support to Guzzle\Common\Collection::getPath()
406
+ * Adding alias support to ServiceBuilder configs
407
+ * Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface
408
+
409
+ ## 3.1.0 - 2013-01-12
410
+
411
+ * BC: CurlException now extends from RequestException rather than BadResponseException
412
+ * BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse()
413
+ * Added getData to ServiceDescriptionInterface
414
+ * Added context array to RequestInterface::setState()
415
+ * Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http
416
+ * Bug: Adding required content-type when JSON request visitor adds JSON to a command
417
+ * Bug: Fixing the serialization of a service description with custom data
418
+ * Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing
419
+ an array of successful and failed responses
420
+ * Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection
421
+ * Added Guzzle\Http\IoEmittingEntityBody
422
+ * Moved command filtration from validators to location visitors
423
+ * Added `extends` attributes to service description parameters
424
+ * Added getModels to ServiceDescriptionInterface
425
+
426
+ ## 3.0.7 - 2012-12-19
427
+
428
+ * Fixing phar detection when forcing a cacert to system if null or true
429
+ * Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()`
430
+ * Cleaning up `Guzzle\Common\Collection::inject` method
431
+ * Adding a response_body location to service descriptions
432
+
433
+ ## 3.0.6 - 2012-12-09
434
+
435
+ * CurlMulti performance improvements
436
+ * Adding setErrorResponses() to Operation
437
+ * composer.json tweaks
438
+
439
+ ## 3.0.5 - 2012-11-18
440
+
441
+ * Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin
442
+ * Bug: Response body can now be a string containing "0"
443
+ * Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert
444
+ * Bug: QueryString::fromString now properly parses query string parameters that contain equal signs
445
+ * Added support for XML attributes in service description responses
446
+ * DefaultRequestSerializer now supports array URI parameter values for URI template expansion
447
+ * Added better mimetype guessing to requests and post files
448
+
449
+ ## 3.0.4 - 2012-11-11
450
+
451
+ * Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value
452
+ * Bug: Cookies can now be added that have a name, domain, or value set to "0"
453
+ * Bug: Using the system cacert bundle when using the Phar
454
+ * Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures
455
+ * Enhanced cookie jar de-duplication
456
+ * Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added
457
+ * Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies
458
+ * Added the ability to create any sort of hash for a stream rather than just an MD5 hash
459
+
460
+ ## 3.0.3 - 2012-11-04
461
+
462
+ * Implementing redirects in PHP rather than cURL
463
+ * Added PECL URI template extension and using as default parser if available
464
+ * Bug: Fixed Content-Length parsing of Response factory
465
+ * Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams.
466
+ * Adding ToArrayInterface throughout library
467
+ * Fixing OauthPlugin to create unique nonce values per request
468
+
469
+ ## 3.0.2 - 2012-10-25
470
+
471
+ * Magic methods are enabled by default on clients
472
+ * Magic methods return the result of a command
473
+ * Service clients no longer require a base_url option in the factory
474
+ * Bug: Fixed an issue with URI templates where null template variables were being expanded
475
+
476
+ ## 3.0.1 - 2012-10-22
477
+
478
+ * Models can now be used like regular collection objects by calling filter, map, etc
479
+ * Models no longer require a Parameter structure or initial data in the constructor
480
+ * Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator`
481
+
482
+ ## 3.0.0 - 2012-10-15
483
+
484
+ * Rewrote service description format to be based on Swagger
485
+ * Now based on JSON schema
486
+ * Added nested input structures and nested response models
487
+ * Support for JSON and XML input and output models
488
+ * Renamed `commands` to `operations`
489
+ * Removed dot class notation
490
+ * Removed custom types
491
+ * Broke the project into smaller top-level namespaces to be more component friendly
492
+ * Removed support for XML configs and descriptions. Use arrays or JSON files.
493
+ * Removed the Validation component and Inspector
494
+ * Moved all cookie code to Guzzle\Plugin\Cookie
495
+ * Magic methods on a Guzzle\Service\Client now return the command un-executed.
496
+ * Calling getResult() or getResponse() on a command will lazily execute the command if needed.
497
+ * Now shipping with cURL's CA certs and using it by default
498
+ * Added previousResponse() method to response objects
499
+ * No longer sending Accept and Accept-Encoding headers on every request
500
+ * Only sending an Expect header by default when a payload is greater than 1MB
501
+ * Added/moved client options:
502
+ * curl.blacklist to curl.option.blacklist
503
+ * Added ssl.certificate_authority
504
+ * Added a Guzzle\Iterator component
505
+ * Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin
506
+ * Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin)
507
+ * Added a more robust caching plugin
508
+ * Added setBody to response objects
509
+ * Updating LogPlugin to use a more flexible MessageFormatter
510
+ * Added a completely revamped build process
511
+ * Cleaning up Collection class and removing default values from the get method
512
+ * Fixed ZF2 cache adapters
513
+
514
+ ## 2.8.8 - 2012-10-15
515
+
516
+ * Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did
517
+
518
+ ## 2.8.7 - 2012-09-30
519
+
520
+ * Bug: Fixed config file aliases for JSON includes
521
+ * Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests
522
+ * Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload
523
+ * Bug: Hardening request and response parsing to account for missing parts
524
+ * Bug: Fixed PEAR packaging
525
+ * Bug: Fixed Request::getInfo
526
+ * Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail
527
+ * Adding the ability for the namespace Iterator factory to look in multiple directories
528
+ * Added more getters/setters/removers from service descriptions
529
+ * Added the ability to remove POST fields from OAuth signatures
530
+ * OAuth plugin now supports 2-legged OAuth
531
+
532
+ ## 2.8.6 - 2012-09-05
533
+
534
+ * Added the ability to modify and build service descriptions
535
+ * Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command
536
+ * Added a `json` parameter location
537
+ * Now allowing dot notation for classes in the CacheAdapterFactory
538
+ * Using the union of two arrays rather than an array_merge when extending service builder services and service params
539
+ * Ensuring that a service is a string before doing strpos() checks on it when substituting services for references
540
+ in service builder config files.
541
+ * Services defined in two different config files that include one another will by default replace the previously
542
+ defined service, but you can now create services that extend themselves and merge their settings over the previous
543
+ * The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like
544
+ '_default' with a default JSON configuration file.
545
+
546
+ ## 2.8.5 - 2012-08-29
547
+
548
+ * Bug: Suppressed empty arrays from URI templates
549
+ * Bug: Added the missing $options argument from ServiceDescription::factory to enable caching
550
+ * Added support for HTTP responses that do not contain a reason phrase in the start-line
551
+ * AbstractCommand commands are now invokable
552
+ * Added a way to get the data used when signing an Oauth request before a request is sent
553
+
554
+ ## 2.8.4 - 2012-08-15
555
+
556
+ * Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin
557
+ * Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable.
558
+ * Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream
559
+ * Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream
560
+ * Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5())
561
+ * Added additional response status codes
562
+ * Removed SSL information from the default User-Agent header
563
+ * DELETE requests can now send an entity body
564
+ * Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries
565
+ * Added the ability of the MockPlugin to consume mocked request bodies
566
+ * LogPlugin now exposes request and response objects in the extras array
567
+
568
+ ## 2.8.3 - 2012-07-30
569
+
570
+ * Bug: Fixed a case where empty POST requests were sent as GET requests
571
+ * Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body
572
+ * Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new
573
+ * Added multiple inheritance to service description commands
574
+ * Added an ApiCommandInterface and added ``getParamNames()`` and ``hasParam()``
575
+ * Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything
576
+ * Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles
577
+
578
+ ## 2.8.2 - 2012-07-24
579
+
580
+ * Bug: Query string values set to 0 are no longer dropped from the query string
581
+ * Bug: A Collection object is no longer created each time a call is made to ``Guzzle\Service\Command\AbstractCommand::getRequestHeaders()``
582
+ * Bug: ``+`` is now treated as an encoded space when parsing query strings
583
+ * QueryString and Collection performance improvements
584
+ * Allowing dot notation for class paths in filters attribute of a service descriptions
585
+
586
+ ## 2.8.1 - 2012-07-16
587
+
588
+ * Loosening Event Dispatcher dependency
589
+ * POST redirects can now be customized using CURLOPT_POSTREDIR
590
+
591
+ ## 2.8.0 - 2012-07-15
592
+
593
+ * BC: Guzzle\Http\Query
594
+ * Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl)
595
+ * Changed isEncodingValues() and isEncodingFields() to isUrlEncoding()
596
+ * Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool)
597
+ * Changed the aggregation functions of QueryString to be static methods
598
+ * Can now use fromString() with querystrings that have a leading ?
599
+ * cURL configuration values can be specified in service descriptions using ``curl.`` prefixed parameters
600
+ * Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body
601
+ * Cookies are no longer URL decoded by default
602
+ * Bug: URI template variables set to null are no longer expanded
603
+
604
+ ## 2.7.2 - 2012-07-02
605
+
606
+ * BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser.
607
+ * BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty()
608
+ * CachePlugin now allows for a custom request parameter function to check if a request can be cached
609
+ * Bug fix: CachePlugin now only caches GET and HEAD requests by default
610
+ * Bug fix: Using header glue when transferring headers over the wire
611
+ * Allowing deeply nested arrays for composite variables in URI templates
612
+ * Batch divisors can now return iterators or arrays
613
+
614
+ ## 2.7.1 - 2012-06-26
615
+
616
+ * Minor patch to update version number in UA string
617
+ * Updating build process
618
+
619
+ ## 2.7.0 - 2012-06-25
620
+
621
+ * BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes.
622
+ * BC: Removed magic setX methods from commands
623
+ * BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method
624
+ * Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable.
625
+ * Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity)
626
+ * Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace
627
+ * Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin
628
+ * Added the ability to set POST fields and files in a service description
629
+ * Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method
630
+ * Adding a command.before_prepare event to clients
631
+ * Added BatchClosureTransfer and BatchClosureDivisor
632
+ * BatchTransferException now includes references to the batch divisor and transfer strategies
633
+ * Fixed some tests so that they pass more reliably
634
+ * Added Guzzle\Common\Log\ArrayLogAdapter
635
+
636
+ ## 2.6.6 - 2012-06-10
637
+
638
+ * BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin
639
+ * BC: Removing Guzzle\Service\Command\CommandSet
640
+ * Adding generic batching system (replaces the batch queue plugin and command set)
641
+ * Updating ZF cache and log adapters and now using ZF's composer repository
642
+ * Bug: Setting the name of each ApiParam when creating through an ApiCommand
643
+ * Adding result_type, result_doc, deprecated, and doc_url to service descriptions
644
+ * Bug: Changed the default cookie header casing back to 'Cookie'
645
+
646
+ ## 2.6.5 - 2012-06-03
647
+
648
+ * BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource()
649
+ * BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from
650
+ * BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data
651
+ * BC: Renaming methods in the CookieJarInterface
652
+ * Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations
653
+ * Making the default glue for HTTP headers ';' instead of ','
654
+ * Adding a removeValue to Guzzle\Http\Message\Header
655
+ * Adding getCookies() to request interface.
656
+ * Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber()
657
+
658
+ ## 2.6.4 - 2012-05-30
659
+
660
+ * BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class.
661
+ * BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand
662
+ * Bug: Fixing magic method command calls on clients
663
+ * Bug: Email constraint only validates strings
664
+ * Bug: Aggregate POST fields when POST files are present in curl handle
665
+ * Bug: Fixing default User-Agent header
666
+ * Bug: Only appending or prepending parameters in commands if they are specified
667
+ * Bug: Not requiring response reason phrases or status codes to match a predefined list of codes
668
+ * Allowing the use of dot notation for class namespaces when using instance_of constraint
669
+ * Added any_match validation constraint
670
+ * Added an AsyncPlugin
671
+ * Passing request object to the calculateWait method of the ExponentialBackoffPlugin
672
+ * Allowing the result of a command object to be changed
673
+ * Parsing location and type sub values when instantiating a service description rather than over and over at runtime
674
+
675
+ ## 2.6.3 - 2012-05-23
676
+
677
+ * [BC] Guzzle\Common\FromConfigInterface no longer requires any config options.
678
+ * [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields.
679
+ * You can now use an array of data when creating PUT request bodies in the request factory.
680
+ * Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable.
681
+ * [Http] Adding support for Content-Type in multipart POST uploads per upload
682
+ * [Http] Added support for uploading multiple files using the same name (foo[0], foo[1])
683
+ * Adding more POST data operations for easier manipulation of POST data.
684
+ * You can now set empty POST fields.
685
+ * The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files.
686
+ * Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate.
687
+ * CS updates
688
+
689
+ ## 2.6.2 - 2012-05-19
690
+
691
+ * [Http] Better handling of nested scope requests in CurlMulti. Requests are now always prepares in the send() method rather than the addRequest() method.
692
+
693
+ ## 2.6.1 - 2012-05-19
694
+
695
+ * [BC] Removing 'path' support in service descriptions. Use 'uri'.
696
+ * [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache.
697
+ * [BC] Removing Guzzle\Common\NullObject. Use https://github.com/mtdowling/NullObject if you need it.
698
+ * [BC] Removing Guzzle\Common\XmlElement.
699
+ * All commands, both dynamic and concrete, have ApiCommand objects.
700
+ * Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits.
701
+ * Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored.
702
+ * Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible.
703
+
704
+ ## 2.6.0 - 2012-05-15
705
+
706
+ * [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder
707
+ * [BC] Executing a Command returns the result of the command rather than the command
708
+ * [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed.
709
+ * [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args.
710
+ * [BC] Moving ResourceIterator* to Guzzle\Service\Resource
711
+ * [BC] Completely refactored ResourceIterators to iterate over a cloned command object
712
+ * [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate
713
+ * [BC] Guzzle\Guzzle is now deprecated
714
+ * Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject
715
+ * Adding Guzzle\Version class to give version information about Guzzle
716
+ * Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate()
717
+ * Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data
718
+ * ServiceDescription and ServiceBuilder are now cacheable using similar configs
719
+ * Changing the format of XML and JSON service builder configs. Backwards compatible.
720
+ * Cleaned up Cookie parsing
721
+ * Trimming the default Guzzle User-Agent header
722
+ * Adding a setOnComplete() method to Commands that is called when a command completes
723
+ * Keeping track of requests that were mocked in the MockPlugin
724
+ * Fixed a caching bug in the CacheAdapterFactory
725
+ * Inspector objects can be injected into a Command object
726
+ * Refactoring a lot of code and tests to be case insensitive when dealing with headers
727
+ * Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL
728
+ * Adding the ability to set global option overrides to service builder configs
729
+ * Adding the ability to include other service builder config files from within XML and JSON files
730
+ * Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method.
731
+
732
+ ## 2.5.0 - 2012-05-08
733
+
734
+ * Major performance improvements
735
+ * [BC] Simplifying Guzzle\Common\Collection. Please check to see if you are using features that are now deprecated.
736
+ * [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component.
737
+ * [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates. Use "{}"
738
+ * Added the ability to passed parameters to all requests created by a client
739
+ * Added callback functionality to the ExponentialBackoffPlugin
740
+ * Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies.
741
+ * Rewinding request stream bodies when retrying requests
742
+ * Exception is thrown when JSON response body cannot be decoded
743
+ * Added configurable magic method calls to clients and commands. This is off by default.
744
+ * Fixed a defect that added a hash to every parsed URL part
745
+ * Fixed duplicate none generation for OauthPlugin.
746
+ * Emitting an event each time a client is generated by a ServiceBuilder
747
+ * Using an ApiParams object instead of a Collection for parameters of an ApiCommand
748
+ * cache.* request parameters should be renamed to params.cache.*
749
+ * Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc). See CurlHandle.
750
+ * Added the ability to disable type validation of service descriptions
751
+ * ServiceDescriptions and ServiceBuilders are now Serializable
lib/amazon/guzzle/guzzle/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2011 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
lib/amazon/guzzle/guzzle/README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Guzzle, PHP HTTP client and webservice framework
2
+ ================================================
3
+
4
+ # This is an old version of Guzzle
5
+
6
+ This repository is for Guzzle 3.x. Guzzle 5.x, the new version of Guzzle, has
7
+ been released and is available at
8
+ [https://github.com/guzzle/guzzle](https://github.com/guzzle/guzzle). The
9
+ documentation for Guzzle version 5+ can be found at
10
+ [http://guzzlephp.org](http://guzzlephp.org).
11
+
12
+ Guzzle 3 is only maintained for bug and security fixes. Guzzle 3 will be EOL
13
+ at some point in late 2015.
14
+
15
+ ### About Guzzle 3
16
+
17
+ [![Composer Downloads](https://poser.pugx.org/guzzle/guzzle/d/total.png)](https://packagist.org/packages/guzzle/guzzle)
18
+ [![Build Status](https://secure.travis-ci.org/guzzle/guzzle3.png?branch=master)](http://travis-ci.org/guzzle/guzzle3)
19
+
20
+ - Extremely powerful API provides all the power of cURL with a simple interface.
21
+ - Truly take advantage of HTTP/1.1 with persistent connections, connection pooling, and parallel requests.
22
+ - Service description DSL allows you build awesome web service clients faster.
23
+ - Symfony2 event-based plugin system allows you to completely modify the behavior of a request.
24
+
25
+ Get answers with: [Documentation](http://guzzle3.readthedocs.org/en/latest/), [Forums](https://groups.google.com/forum/?hl=en#!forum/guzzle), IRC ([#guzzlephp](irc://irc.freenode.net/#guzzlephp) @ irc.freenode.net)
26
+
27
+ ### Installing via Composer
28
+
29
+ The recommended way to install Guzzle is through [Composer](http://getcomposer.org).
30
+
31
+ ```bash
32
+ # Install Composer
33
+ curl -sS https://getcomposer.org/installer | php
34
+
35
+ # Add Guzzle as a dependency
36
+ php composer.phar require guzzle/guzzle:~3.9
37
+ ```
38
+
39
+ After installing, you need to require Composer's autoloader:
40
+
41
+ ```php
42
+ require 'vendor/autoload.php';
43
+ ```
44
+ ## Known Issues
45
+
46
+ 1. Problem following a specific redirect: https://github.com/guzzle/guzzle/issues/385.
47
+ This has been fixed in Guzzle 4/5.
48
+ 2. Root XML attributes not serialized in a service description: https://github.com/guzzle/guzzle3/issues/5.
49
+ This has been fixed in Guzzle 4/5.
50
+ 3. Accept-Encoding not preserved when following redirect: https://github.com/guzzle/guzzle3/issues/9
51
+ Fixed in Guzzle 4/5.
52
+ 4. String "Array" Transmitted w/ PostFiles and Duplicate Aggregator: https://github.com/guzzle/guzzle3/issues/10
53
+ Fixed in Guzzle 4/5.
54
+ 5. Recursive model references with array items: https://github.com/guzzle/guzzle3/issues/13
55
+ Fixed in Guzzle 4/5
56
+ 6. String "Array" Transmitted w/ PostFiles and Duplicate Aggregator: https://github.com/guzzle/guzzle3/issues/10
57
+ Fixed in Guzzle 4/5.
lib/amazon/guzzle/guzzle/UPGRADING.md ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Guzzle Upgrade Guide
2
+ ====================
3
+
4
+ 3.6 to 3.7
5
+ ----------
6
+
7
+ ### Deprecations
8
+
9
+ - You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.:
10
+
11
+ ```php
12
+ \Guzzle\Common\Version::$emitWarnings = true;
13
+ ```
14
+
15
+ The following APIs and options have been marked as deprecated:
16
+
17
+ - Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead.
18
+ - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
19
+ - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
20
+ - Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
21
+ - Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
22
+ - Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
23
+ - Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
24
+ - Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
25
+ - Marked `Guzzle\Common\Collection::inject()` as deprecated.
26
+ - Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use
27
+ `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or
28
+ `$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));`
29
+
30
+ 3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational
31
+ request methods. When paired with a client's configuration settings, these options allow you to specify default settings
32
+ for various aspects of a request. Because these options make other previous configuration options redundant, several
33
+ configuration options and methods of a client and AbstractCommand have been deprecated.
34
+
35
+ - Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`.
36
+ - Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`.
37
+ - Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')`
38
+ - Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0
39
+
40
+ $command = $client->getCommand('foo', array(
41
+ 'command.headers' => array('Test' => '123'),
42
+ 'command.response_body' => '/path/to/file'
43
+ ));
44
+
45
+ // Should be changed to:
46
+
47
+ $command = $client->getCommand('foo', array(
48
+ 'command.request_options' => array(
49
+ 'headers' => array('Test' => '123'),
50
+ 'save_as' => '/path/to/file'
51
+ )
52
+ ));
53
+
54
+ ### Interface changes
55
+
56
+ Additions and changes (you will need to update any implementations or subclasses you may have created):
57
+
58
+ - Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
59
+ createRequest, head, delete, put, patch, post, options, prepareRequest
60
+ - Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
61
+ - Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
62
+ - Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
63
+ `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
64
+ resource, string, or EntityBody into the $options parameter to specify the download location of the response.
65
+ - Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
66
+ default `array()`
67
+ - Added `Guzzle\Stream\StreamInterface::isRepeatable`
68
+ - Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
69
+
70
+ The following methods were removed from interfaces. All of these methods are still available in the concrete classes
71
+ that implement them, but you should update your code to use alternative methods:
72
+
73
+ - Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
74
+ `$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
75
+ `$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or
76
+ `$client->setDefaultOption('headers/{header_name}', 'value')`. or
77
+ `$client->setDefaultOption('headers', array('header_name' => 'value'))`.
78
+ - Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`.
79
+ - Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail.
80
+ - Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail.
81
+ - Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail.
82
+ - Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin.
83
+ - Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin.
84
+ - Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin.
85
+
86
+ ### Cache plugin breaking changes
87
+
88
+ - CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
89
+ CacheStorageInterface. These two objects and interface will be removed in a future version.
90
+ - Always setting X-cache headers on cached responses
91
+ - Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
92
+ - `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
93
+ $request, Response $response);`
94
+ - `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
95
+ - `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
96
+ - Added `CacheStorageInterface::purge($url)`
97
+ - `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
98
+ $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
99
+ CanCacheStrategyInterface $canCache = null)`
100
+ - Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
101
+
102
+ 3.5 to 3.6
103
+ ----------
104
+
105
+ * Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
106
+ * Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
107
+ * Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
108
+ For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader().
109
+ Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request.
110
+ * Specific header implementations can be created for complex headers. When a message creates a header, it uses a
111
+ HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
112
+ CacheControl header implementation.
113
+ * Moved getLinks() from Response to just be used on a Link header object.
114
+
115
+ If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the
116
+ HeaderInterface (e.g. toArray(), getAll(), etc).
117
+
118
+ ### Interface changes
119
+
120
+ * Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
121
+ * Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
122
+ * Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
123
+ Guzzle\Http\Curl\RequestMediator
124
+ * Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
125
+ * Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
126
+ * Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
127
+
128
+ ### Removed deprecated functions
129
+
130
+ * Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
131
+ * Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
132
+
133
+ ### Deprecations
134
+
135
+ * The ability to case-insensitively search for header values
136
+ * Guzzle\Http\Message\Header::hasExactHeader
137
+ * Guzzle\Http\Message\Header::raw. Use getAll()
138
+ * Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
139
+ instead.
140
+
141
+ ### Other changes
142
+
143
+ * All response header helper functions return a string rather than mixing Header objects and strings inconsistently
144
+ * Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc are managed by Guzzle
145
+ directly via interfaces
146
+ * Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
147
+ but are a no-op until removed.
148
+ * Most classes that used to require a ``Guzzle\Service\Command\CommandInterface` typehint now request a
149
+ `Guzzle\Service\Command\ArrayCommandInterface`.
150
+ * Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
151
+ on a request while the request is still being transferred
152
+ * `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
153
+
154
+ 3.3 to 3.4
155
+ ----------
156
+
157
+ Base URLs of a client now follow the rules of http://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs.
158
+
159
+ 3.2 to 3.3
160
+ ----------
161
+
162
+ ### Response::getEtag() quote stripping removed
163
+
164
+ `Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header
165
+
166
+ ### Removed `Guzzle\Http\Utils`
167
+
168
+ The `Guzzle\Http\Utils` class was removed. This class was only used for testing.
169
+
170
+ ### Stream wrapper and type
171
+
172
+ `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to lowercase.
173
+
174
+ ### curl.emit_io became emit_io
175
+
176
+ Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the
177
+ 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
178
+
179
+ 3.1 to 3.2
180
+ ----------
181
+
182
+ ### CurlMulti is no longer reused globally
183
+
184
+ Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added
185
+ to a single client can pollute requests dispatched from other clients.
186
+
187
+ If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the
188
+ ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is
189
+ created.
190
+
191
+ ```php
192
+ $multi = new Guzzle\Http\Curl\CurlMulti();
193
+ $builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json');
194
+ $builder->addListener('service_builder.create_client', function ($event) use ($multi) {
195
+ $event['client']->setCurlMulti($multi);
196
+ }
197
+ });
198
+ ```
199
+
200
+ ### No default path
201
+
202
+ URLs no longer have a default path value of '/' if no path was specified.
203
+
204
+ Before:
205
+
206
+ ```php
207
+ $request = $client->get('http://www.foo.com');
208
+ echo $request->getUrl();
209
+ // >> http://www.foo.com/
210
+ ```
211
+
212
+ After:
213
+
214
+ ```php
215
+ $request = $client->get('http://www.foo.com');
216
+ echo $request->getUrl();
217
+ // >> http://www.foo.com
218
+ ```
219
+
220
+ ### Less verbose BadResponseException
221
+
222
+ The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and
223
+ response information. You can, however, get access to the request and response object by calling `getRequest()` or
224
+ `getResponse()` on the exception object.
225
+
226
+ ### Query parameter aggregation
227
+
228
+ Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a
229
+ setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is
230
+ responsible for handling the aggregation of multi-valued query string variables into a flattened hash.
231
+
232
+ 2.8 to 3.x
233
+ ----------
234
+
235
+ ### Guzzle\Service\Inspector
236
+
237
+ Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig`
238
+
239
+ **Before**
240
+
241
+ ```php
242
+ use Guzzle\Service\Inspector;
243
+
244
+ class YourClient extends \Guzzle\Service\Client
245
+ {
246
+ public static function factory($config = array())
247
+ {
248
+ $default = array();
249
+ $required = array('base_url', 'username', 'api_key');
250
+ $config = Inspector::fromConfig($config, $default, $required);
251
+
252
+ $client = new self(
253
+ $config->get('base_url'),
254
+ $config->get('username'),
255
+ $config->get('api_key')
256
+ );
257
+ $client->setConfig($config);
258
+
259
+ $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
260
+
261
+ return $client;
262
+ }
263
+ ```
264
+
265
+ **After**
266
+
267
+ ```php
268
+ use Guzzle\Common\Collection;
269
+
270
+ class YourClient extends \Guzzle\Service\Client
271
+ {
272
+ public static function factory($config = array())
273
+ {
274
+ $default = array();
275
+ $required = array('base_url', 'username', 'api_key');
276
+ $config = Collection::fromConfig($config, $default, $required);
277
+
278
+ $client = new self(
279
+ $config->get('base_url'),
280
+ $config->get('username'),
281
+ $config->get('api_key')
282
+ );
283
+ $client->setConfig($config);
284
+
285
+ $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
286
+
287
+ return $client;
288
+ }
289
+ ```
290
+
291
+ ### Convert XML Service Descriptions to JSON
292
+
293
+ **Before**
294
+
295
+ ```xml
296
+ <?xml version="1.0" encoding="UTF-8"?>
297
+ <client>
298
+ <commands>
299
+ <!-- Groups -->
300
+ <command name="list_groups" method="GET" uri="groups.json">
301
+ <doc>Get a list of groups</doc>
302
+ </command>
303
+ <command name="search_groups" method="GET" uri='search.json?query="{{query}} type:group"'>
304
+ <doc>Uses a search query to get a list of groups</doc>
305
+ <param name="query" type="string" required="true" />
306
+ </command>
307
+ <command name="create_group" method="POST" uri="groups.json">
308
+ <doc>Create a group</doc>
309
+ <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
310
+ <param name="Content-Type" location="header" static="application/json"/>
311
+ </command>
312
+ <command name="delete_group" method="DELETE" uri="groups/{{id}}.json">
313
+ <doc>Delete a group by ID</doc>
314
+ <param name="id" type="integer" required="true"/>
315
+ </command>
316
+ <command name="get_group" method="GET" uri="groups/{{id}}.json">
317
+ <param name="id" type="integer" required="true"/>
318
+ </command>
319
+ <command name="update_group" method="PUT" uri="groups/{{id}}.json">
320
+ <doc>Update a group</doc>
321
+ <param name="id" type="integer" required="true"/>
322
+ <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
323
+ <param name="Content-Type" location="header" static="application/json"/>
324
+ </command>
325
+ </commands>
326
+ </client>
327
+ ```
328
+
329
+ **After**
330
+
331
+ ```json
332
+ {
333
+ "name": "Zendesk REST API v2",
334
+ "apiVersion": "2012-12-31",
335
+ "description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users",
336
+ "operations": {
337
+ "list_groups": {
338
+ "httpMethod":"GET",
339
+ "uri": "groups.json",
340
+ "summary": "Get a list of groups"
341
+ },
342
+ "search_groups":{
343
+ "httpMethod":"GET",
344
+ "uri": "search.json?query=\"{query} type:group\"",
345
+ "summary": "Uses a search query to get a list of groups",
346
+ "parameters":{
347
+ "query":{
348
+ "location": "uri",
349
+ "description":"Zendesk Search Query",
350
+ "type": "string",
351
+ "required": true
352
+ }
353
+ }
354
+ },
355
+ "create_group": {
356
+ "httpMethod":"POST",
357
+ "uri": "groups.json",
358
+ "summary": "Create a group",
359
+ "parameters":{
360
+ "data": {
361
+ "type": "array",
362
+ "location": "body",
363
+ "description":"Group JSON",
364
+ "filters": "json_encode",
365
+ "required": true
366
+ },
367
+ "Content-Type":{
368
+ "type": "string",
369
+ "location":"header",
370
+ "static": "application/json"
371
+ }
372
+ }
373
+ },
374
+ "delete_group": {
375
+ "httpMethod":"DELETE",
376
+ "uri": "groups/{id}.json",
377
+ "summary": "Delete a group",
378
+ "parameters":{
379
+ "id":{
380
+ "location": "uri",
381
+ "description":"Group to delete by ID",
382
+ "type": "integer",
383
+ "required": true
384
+ }
385
+ }
386
+ },
387
+ "get_group": {
388
+ "httpMethod":"GET",
389
+ "uri": "groups/{id}.json",
390
+ "summary": "Get a ticket",
391
+ "parameters":{
392
+ "id":{
393
+ "location": "uri",
394
+ "description":"Group to get by ID",
395
+ "type": "integer",
396
+ "required": true
397
+ }
398
+ }
399
+ },
400
+ "update_group": {
401
+ "httpMethod":"PUT",
402
+ "uri": "groups/{id}.json",
403
+ "summary": "Update a group",
404
+ "parameters":{
405
+ "id": {
406
+ "location": "uri",
407
+ "description":"Group to update by ID",
408
+ "type": "integer",
409
+ "required": true
410
+ },
411
+ "data": {
412
+ "type": "array",
413
+ "location": "body",
414
+ "description":"Group JSON",
415
+ "filters": "json_encode",
416
+ "required": true
417
+ },
418
+ "Content-Type":{
419
+ "type": "string",
420
+ "location":"header",
421
+ "static": "application/json"
422
+ }
423
+ }
424
+ }
425
+ }
426
+ ```
427
+
428
+ ### Guzzle\Service\Description\ServiceDescription
429
+
430
+ Commands are now called Operations
431
+
432
+ **Before**
433
+
434
+ ```php
435
+ use Guzzle\Service\Description\ServiceDescription;
436
+
437
+ $sd = new ServiceDescription();
438
+ $sd->getCommands(); // @returns ApiCommandInterface[]
439
+ $sd->hasCommand($name);
440
+ $sd->getCommand($name); // @returns ApiCommandInterface|null
441
+ $sd->addCommand($command); // @param ApiCommandInterface $command
442
+ ```
443
+
444
+ **After**
445
+
446
+ ```php
447
+ use Guzzle\Service\Description\ServiceDescription;
448
+
449
+ $sd = new ServiceDescription();
450
+ $sd->getOperations(); // @returns OperationInterface[]
451
+ $sd->hasOperation($name);
452
+ $sd->getOperation($name); // @returns OperationInterface|null
453
+ $sd->addOperation($operation); // @param OperationInterface $operation
454
+ ```
455
+
456
+ ### Guzzle\Common\Inflection\Inflector
457
+
458
+ Namespace is now `Guzzle\Inflection\Inflector`
459
+
460
+ ### Guzzle\Http\Plugin
461
+
462
+ Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below.
463
+
464
+ ### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log
465
+
466
+ Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively.
467
+
468
+ **Before**
469
+
470
+ ```php
471
+ use Guzzle\Common\Log\ClosureLogAdapter;
472
+ use Guzzle\Http\Plugin\LogPlugin;
473
+
474
+ /** @var \Guzzle\Http\Client */
475
+ $client;
476
+
477
+ // $verbosity is an integer indicating desired message verbosity level
478
+ $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE);
479
+ ```
480
+
481
+ **After**
482
+
483
+ ```php
484
+ use Guzzle\Log\ClosureLogAdapter;
485
+ use Guzzle\Log\MessageFormatter;
486
+ use Guzzle\Plugin\Log\LogPlugin;
487
+
488
+ /** @var \Guzzle\Http\Client */
489
+ $client;
490
+
491
+ // $format is a string indicating desired message format -- @see MessageFormatter
492
+ $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT);
493
+ ```
494
+
495
+ ### Guzzle\Http\Plugin\CurlAuthPlugin
496
+
497
+ Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`.
498
+
499
+ ### Guzzle\Http\Plugin\ExponentialBackoffPlugin
500
+
501
+ Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes.
502
+
503
+ **Before**
504
+
505
+ ```php
506
+ use Guzzle\Http\Plugin\ExponentialBackoffPlugin;
507
+
508
+ $backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge(
509
+ ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429)
510
+ ));
511
+
512
+ $client->addSubscriber($backoffPlugin);
513
+ ```
514
+
515
+ **After**
516
+
517
+ ```php
518
+ use Guzzle\Plugin\Backoff\BackoffPlugin;
519
+ use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
520
+
521
+ // Use convenient factory method instead -- see implementation for ideas of what
522
+ // you can do with chaining backoff strategies
523
+ $backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge(
524
+ HttpBackoffStrategy::getDefaultFailureCodes(), array(429)
525
+ ));
526
+ $client->addSubscriber($backoffPlugin);
527
+ ```
528
+
529
+ ### Known Issues
530
+
531
+ #### [BUG] Accept-Encoding header behavior changed unintentionally.
532
+
533
+ (See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e)
534
+
535
+ In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to
536
+ properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen.
537
+ See issue #217 for a workaround, or use a version containing the fix.
lib/amazon/guzzle/guzzle/build.xml ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project name="guzzle" default="test">
3
+ <!-- set local values, like git location -->
4
+ <property file="phing/build.properties.dist" override="true" />
5
+ <property file="phing/build.properties" override="true" />
6
+
7
+ <property name="dir.output" value="${project.basedir}/build/artifacts" />
8
+ <property name="dir.imports" value="${project.basedir}/phing/imports" />
9
+ <property name="dir.bin" value="${project.basedir}/bin" />
10
+ <property name="repo.dir" value="${project.basedir}" />
11
+
12
+ <import file="${dir.imports}/dependencies.xml"/>
13
+ <import file="${dir.imports}/deploy.xml"/>
14
+
15
+ <target name="composer-lint" description="lint-check composer.json only">
16
+ <composerlint dir="${project.basedir}/src" file="{$project.basedir}/composer.json" />
17
+ </target>
18
+
19
+ <target name="test" description="Run unit tests">
20
+ <exec passthru="true" command="vendor/bin/phpunit" checkReturn="true" />
21
+ </target>
22
+
23
+ <target name="build-init" description="Initialize local phing properties">
24
+ <copy file="phing/build.properties.dist" tofile="phing/build.properties" overwrite="false" />
25
+ </target>
26
+
27
+ <target name="clean">
28
+ <delete dir="${dir.output}"/>
29
+ <delete dir="${project.basedir}/build/pearwork"/>
30
+ </target>
31
+
32
+ <target name="prepare" depends="clean,build-init">
33
+ <mkdir dir="${dir.output}"/>
34
+ <mkdir dir="${dir.output}/logs" />
35
+ </target>
36
+
37
+ <target name="coverage" depends="prepare">
38
+ <exec passthru="true" command="vendor/bin/phpunit --coverage-html=${dir.output}/coverage" />
39
+ </target>
40
+
41
+ <target name="view-coverage">
42
+ <exec passthru="true" command="open ${dir.output}/coverage/index.html" />
43
+ </target>
44
+
45
+ </project>
lib/amazon/guzzle/guzzle/composer.json ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "guzzle/guzzle",
3
+ "type": "library",
4
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
5
+ "keywords": ["framework", "http", "rest", "web service", "curl", "client", "HTTP client"],
6
+ "homepage": "http://guzzlephp.org/",
7
+ "license": "MIT",
8
+
9
+ "authors": [
10
+ {
11
+ "name": "Michael Dowling",
12
+ "email": "mtdowling@gmail.com",
13
+ "homepage": "https://github.com/mtdowling"
14
+ },
15
+ {
16
+ "name": "Guzzle Community",
17
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
18
+ }
19
+ ],
20
+
21
+ "replace": {
22
+ "guzzle/batch": "self.version",
23
+ "guzzle/cache": "self.version",
24
+ "guzzle/common": "self.version",
25
+ "guzzle/http": "self.version",
26
+ "guzzle/inflection": "self.version",
27
+ "guzzle/iterator": "self.version",
28
+ "guzzle/log": "self.version",
29
+ "guzzle/parser": "self.version",
30
+ "guzzle/plugin": "self.version",
31
+ "guzzle/plugin-async": "self.version",
32
+ "guzzle/plugin-backoff": "self.version",
33
+ "guzzle/plugin-cache": "self.version",
34
+ "guzzle/plugin-cookie": "self.version",
35
+ "guzzle/plugin-curlauth": "self.version",
36
+ "guzzle/plugin-error-response": "self.version",
37
+ "guzzle/plugin-history": "self.version",
38
+ "guzzle/plugin-log": "self.version",
39
+ "guzzle/plugin-md5": "self.version",
40
+ "guzzle/plugin-mock": "self.version",
41
+ "guzzle/plugin-oauth": "self.version",
42
+ "guzzle/service": "self.version",
43
+ "guzzle/stream": "self.version"
44
+ },
45
+
46
+ "require": {
47
+ "php": ">=5.3.3",
48
+ "ext-curl": "*",
49
+ "symfony/event-dispatcher": "~2.1"
50
+ },
51
+
52
+ "autoload": {
53
+ "psr-0": {
54
+ "Guzzle": "src/",
55
+ "Guzzle\\Tests": "tests/"
56
+ }
57
+ },
58
+
59
+ "suggest": {
60
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
61
+ },
62
+
63
+ "scripts": {
64
+ "test": "phpunit"
65
+ },
66
+
67
+ "require-dev": {
68
+ "doctrine/cache": "~1.3",
69
+ "symfony/class-loader": "~2.1",
70
+ "monolog/monolog": "~1.0",
71
+ "psr/log": "~1.0",
72
+ "zendframework/zend-cache": "2.*,<2.3",
73
+ "zendframework/zend-log": "2.*,<2.3",
74
+ "phpunit/phpunit": "3.7.*"
75
+ },
76
+
77
+ "extra": {
78
+ "branch-alias": {
79
+ "dev-master": "3.9-dev"
80
+ }
81
+ }
82
+ }
lib/amazon/guzzle/guzzle/phar-stub.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ Phar::mapPhar('guzzle.phar');
4
+
5
+ require_once 'phar://guzzle.phar/vendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.php';
6
+
7
+ $classLoader = new Symfony\Component\ClassLoader\UniversalClassLoader();
8
+ $classLoader->registerNamespaces(array(
9
+ 'Guzzle' => 'phar://guzzle.phar/src',
10
+ 'Symfony\\Component\\EventDispatcher' => 'phar://guzzle.phar/vendor/symfony/event-dispatcher',
11
+ 'Doctrine' => 'phar://guzzle.phar/vendor/doctrine/common/lib',
12
+ 'Monolog' => 'phar://guzzle.phar/vendor/monolog/monolog/src'
13
+ ));
14
+ $classLoader->register();
15
+
16
+ __HALT_COMPILER();
lib/amazon/guzzle/guzzle/phpunit.xml.dist ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <phpunit bootstrap="./tests/bootstrap.php"
3
+ colors="true"
4
+ processIsolation="false"
5
+ stopOnFailure="false"
6
+ syntaxCheck="false"
7
+ convertErrorsToExceptions="true"
8
+ convertNoticesToExceptions="true"
9
+ convertWarningsToExceptions="true"
10
+ testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader">
11
+
12
+ <testsuites>
13
+ <testsuite>
14
+ <directory>./tests/Guzzle/Tests</directory>
15
+ </testsuite>
16
+ </testsuites>
17
+
18
+ <logging>
19
+ <log type="junit" target="build/artifacts/logs/junit.xml" logIncompleteSkipped="false" />
20
+ </logging>
21
+
22
+ <filter>
23
+ <whitelist>
24
+ <directory suffix=".php">./src/Guzzle</directory>
25
+ <exclude>
26
+ <directory suffix="Interface.php">./src/Guzzle</directory>
27
+ <file>./src/Guzzle/Common/Exception/GuzzleException.php</file>
28
+ <file>./src/Guzzle/Http/Exception/HttpException.php</file>
29
+ <file>./src/Guzzle/Http/Exception/ServerErrorResponseException.php</file>
30
+ <file>./src/Guzzle/Http/Exception/ClientErrorResponseException.php</file>
31
+ <file>./src/Guzzle/Http/Exception/TooManyRedirectsException.php</file>
32
+ <file>./src/Guzzle/Http/Exception/CouldNotRewindStreamException.php</file>
33
+ <file>./src/Guzzle/Common/Exception/BadMethodCallException.php</file>
34
+ <file>./src/Guzzle/Common/Exception/InvalidArgumentException.php</file>
35
+ <file>./src/Guzzle/Common/Exception/RuntimeException.php</file>
36
+ <file>./src/Guzzle/Common/Exception/UnexpectedValueException.php</file>
37
+ <file>./src/Guzzle/Service/Exception/ClientNotFoundException.php</file>
38
+ <file>./src/Guzzle/Service/Exception/CommandException.php</file>
39
+ <file>./src/Guzzle/Service/Exception/DescriptionBuilderException.php</file>
40
+ <file>./src/Guzzle/Service/Exception/ServiceBuilderException.php</file>
41
+ <file>./src/Guzzle/Service/Exception/ServiceNotFoundException.php</file>
42
+ <file>./src/Guzzle/Service/Exception/ValidationException.php</file>
43
+ <file>./src/Guzzle/Service/Exception/JsonException.php</file>
44
+ </exclude>
45
+ </whitelist>
46
+ </filter>
47
+
48
+ </phpunit>
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/AbstractBatchDecorator.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ /**
6
+ * Abstract decorator used when decorating a BatchInterface
7
+ */
8
+ abstract class AbstractBatchDecorator implements BatchInterface
9
+ {
10
+ /** @var BatchInterface Decorated batch object */
11
+ protected $decoratedBatch;
12
+
13
+ /**
14
+ * @param BatchInterface $decoratedBatch BatchInterface that is being decorated
15
+ */
16
+ public function __construct(BatchInterface $decoratedBatch)
17
+ {
18
+ $this->decoratedBatch = $decoratedBatch;
19
+ }
20
+
21
+ /**
22
+ * Allow decorators to implement custom methods
23
+ *
24
+ * @param string $method Missing method name
25
+ * @param array $args Method arguments
26
+ *
27
+ * @return mixed
28
+ * @codeCoverageIgnore
29
+ */
30
+ public function __call($method, array $args)
31
+ {
32
+ return call_user_func_array(array($this->decoratedBatch, $method), $args);
33
+ }
34
+
35
+ public function add($item)
36
+ {
37
+ $this->decoratedBatch->add($item);
38
+
39
+ return $this;
40
+ }
41
+
42
+ public function flush()
43
+ {
44
+ return $this->decoratedBatch->flush();
45
+ }
46
+
47
+ public function isEmpty()
48
+ {
49
+ return $this->decoratedBatch->isEmpty();
50
+ }
51
+
52
+ /**
53
+ * Trace the decorators associated with the batch
54
+ *
55
+ * @return array
56
+ */
57
+ public function getDecorators()
58
+ {
59
+ $found = array($this);
60
+ if (method_exists($this->decoratedBatch, 'getDecorators')) {
61
+ $found = array_merge($found, $this->decoratedBatch->getDecorators());
62
+ }
63
+
64
+ return $found;
65
+ }
66
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/Batch.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ use Guzzle\Batch\Exception\BatchTransferException;
6
+
7
+ /**
8
+ * Default batch implementation used to convert queued items into smaller chunks of batches using a
9
+ * {@see BatchDivisorIterface} and transfers each batch using a {@see BatchTransferInterface}.
10
+ *
11
+ * Any exception encountered during a flush operation will throw a {@see BatchTransferException} object containing the
12
+ * batch that failed. After an exception is encountered, you can flush the batch again to attempt to finish transferring
13
+ * any previously created batches or queued items.
14
+ */
15
+ class Batch implements BatchInterface
16
+ {
17
+ /** @var \SplQueue Queue of items in the queue */
18
+ protected $queue;
19
+
20
+ /** @var array Divided batches to be transferred */
21
+ protected $dividedBatches;
22
+
23
+ /** @var BatchTransferInterface */
24
+ protected $transferStrategy;
25
+
26
+ /** @var BatchDivisorInterface */
27
+ protected $divisionStrategy;
28
+
29
+ /**
30
+ * @param BatchTransferInterface $transferStrategy Strategy used to transfer items
31
+ * @param BatchDivisorInterface $divisionStrategy Divisor used to create batches
32
+ */
33
+ public function __construct(BatchTransferInterface $transferStrategy, BatchDivisorInterface $divisionStrategy)
34
+ {
35
+ $this->transferStrategy = $transferStrategy;
36
+ $this->divisionStrategy = $divisionStrategy;
37
+ $this->queue = new \SplQueue();
38
+ $this->queue->setIteratorMode(\SplQueue::IT_MODE_DELETE);
39
+ $this->dividedBatches = array();
40
+ }
41
+
42
+ public function add($item)
43
+ {
44
+ $this->queue->enqueue($item);
45
+
46
+ return $this;
47
+ }
48
+
49
+ public function flush()
50
+ {
51
+ $this->createBatches();
52
+
53
+ $items = array();
54
+ foreach ($this->dividedBatches as $batchIndex => $dividedBatch) {
55
+ while ($dividedBatch->valid()) {
56
+ $batch = $dividedBatch->current();
57
+ $dividedBatch->next();
58
+ try {
59
+ $this->transferStrategy->transfer($batch);
60
+ $items = array_merge($items, $batch);
61
+ } catch (\Exception $e) {
62
+ throw new BatchTransferException($batch, $items, $e, $this->transferStrategy, $this->divisionStrategy);
63
+ }
64
+ }
65
+ // Keep the divided batch down to a minimum in case of a later exception
66
+ unset($this->dividedBatches[$batchIndex]);
67
+ }
68
+
69
+ return $items;
70
+ }
71
+
72
+ public function isEmpty()
73
+ {
74
+ return count($this->queue) == 0 && count($this->dividedBatches) == 0;
75
+ }
76
+
77
+ /**
78
+ * Create batches for any queued items
79
+ */
80
+ protected function createBatches()
81
+ {
82
+ if (count($this->queue)) {
83
+ if ($batches = $this->divisionStrategy->createBatches($this->queue)) {
84
+ // Convert arrays into iterators
85
+ if (is_array($batches)) {
86
+ $batches = new \ArrayIterator($batches);
87
+ }
88
+ $this->dividedBatches[] = $batches;
89
+ }
90
+ }
91
+ }
92
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchBuilder.php ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ use Guzzle\Common\Exception\InvalidArgumentException;
6
+ use Guzzle\Common\Exception\RuntimeException;
7
+
8
+ /**
9
+ * Builder used to create custom batch objects
10
+ */
11
+ class BatchBuilder
12
+ {
13
+ /** @var bool Whether or not the batch should automatically flush*/
14
+ protected $autoFlush = false;
15
+
16
+ /** @var bool Whether or not to maintain a batch history */
17
+ protected $history = false;
18
+
19
+ /** @var bool Whether or not to buffer exceptions encountered in transfer */
20
+ protected $exceptionBuffering = false;
21
+
22
+ /** @var mixed Callable to invoke each time a flush completes */
23
+ protected $afterFlush;
24
+
25
+ /** @var BatchTransferInterface Object used to transfer items in the queue */
26
+ protected $transferStrategy;
27
+
28
+ /** @var BatchDivisorInterface Object used to divide the queue into batches */
29
+ protected $divisorStrategy;
30
+
31
+ /** @var array of Mapped transfer strategies by handle name */
32
+ protected static $mapping = array(
33
+ 'request' => 'Guzzle\Batch\BatchRequestTransfer',
34
+ 'command' => 'Guzzle\Batch\BatchCommandTransfer'
35
+ );
36
+
37
+ /**
38
+ * Create a new instance of the BatchBuilder
39
+ *
40
+ * @return BatchBuilder
41
+ */
42
+ public static function factory()
43
+ {
44
+ return new self();
45
+ }
46
+
47
+ /**
48
+ * Automatically flush the batch when the size of the queue reaches a certain threshold. Adds {@see FlushingBatch}.
49
+ *
50
+ * @param $threshold Number of items to allow in the queue before a flush
51
+ *
52
+ * @return BatchBuilder
53
+ */
54
+ public function autoFlushAt($threshold)
55
+ {
56
+ $this->autoFlush = $threshold;
57
+
58
+ return $this;
59
+ }
60
+
61
+ /**
62
+ * Maintain a history of all items that have been transferred using the batch. Adds {@see HistoryBatch}.
63
+ *
64
+ * @return BatchBuilder
65
+ */
66
+ public function keepHistory()
67
+ {
68
+ $this->history = true;
69
+
70
+ return $this;
71
+ }
72
+
73
+ /**
74
+ * Buffer exceptions thrown during transfer so that you can transfer as much as possible, and after a transfer
75
+ * completes, inspect each exception that was thrown. Enables the {@see ExceptionBufferingBatch} decorator.
76
+ *
77
+ * @return BatchBuilder
78
+ */
79
+ public function bufferExceptions()
80
+ {
81
+ $this->exceptionBuffering = true;
82
+
83
+ return $this;
84
+ }
85
+
86
+ /**
87
+ * Notify a callable each time a batch flush completes. Enables the {@see NotifyingBatch} decorator.
88
+ *
89
+ * @param mixed $callable Callable function to notify
90
+ *
91
+ * @return BatchBuilder
92
+ * @throws InvalidArgumentException if the argument is not callable
93
+ */
94
+ public function notify($callable)
95
+ {
96
+ $this->afterFlush = $callable;
97
+
98
+ return $this;
99
+ }
100
+
101
+ /**
102
+ * Configures the batch to transfer batches of requests. Associates a {@see \Guzzle\Http\BatchRequestTransfer}
103
+ * object as both the transfer and divisor strategy.
104
+ *
105
+ * @param int $batchSize Batch size for each batch of requests
106
+ *
107
+ * @return BatchBuilder
108
+ */
109
+ public function transferRequests($batchSize = 50)
110
+ {
111
+ $className = self::$mapping['request'];
112
+ $this->transferStrategy = new $className($batchSize);
113
+ $this->divisorStrategy = $this->transferStrategy;
114
+
115
+ return $this;
116
+ }
117
+
118
+ /**
119
+ * Configures the batch to transfer batches commands. Associates as
120
+ * {@see \Guzzle\Service\Command\BatchCommandTransfer} as both the transfer and divisor strategy.
121
+ *
122
+ * @param int $batchSize Batch size for each batch of commands
123
+ *
124
+ * @return BatchBuilder
125
+ */
126
+ public function transferCommands($batchSize = 50)
127
+ {
128
+ $className = self::$mapping['command'];
129
+ $this->transferStrategy = new $className($batchSize);
130
+ $this->divisorStrategy = $this->transferStrategy;
131
+
132
+ return $this;
133
+ }
134
+
135
+ /**
136
+ * Specify the strategy used to divide the queue into an array of batches
137
+ *
138
+ * @param BatchDivisorInterface $divisorStrategy Strategy used to divide a batch queue into batches
139
+ *
140
+ * @return BatchBuilder
141
+ */
142
+ public function createBatchesWith(BatchDivisorInterface $divisorStrategy)
143
+ {
144
+ $this->divisorStrategy = $divisorStrategy;
145
+
146
+ return $this;
147
+ }
148
+
149
+ /**
150
+ * Specify the strategy used to transport the items when flush is called
151
+ *
152
+ * @param BatchTransferInterface $transferStrategy How items are transferred
153
+ *
154
+ * @return BatchBuilder
155
+ */
156
+ public function transferWith(BatchTransferInterface $transferStrategy)
157
+ {
158
+ $this->transferStrategy = $transferStrategy;
159
+
160
+ return $this;
161
+ }
162
+
163
+ /**
164
+ * Create and return the instantiated batch
165
+ *
166
+ * @return BatchInterface
167
+ * @throws RuntimeException if no transfer strategy has been specified
168
+ */
169
+ public function build()
170
+ {
171
+ if (!$this->transferStrategy) {
172
+ throw new RuntimeException('No transfer strategy has been specified');
173
+ }
174
+
175
+ if (!$this->divisorStrategy) {
176
+ throw new RuntimeException('No divisor strategy has been specified');
177
+ }
178
+
179
+ $batch = new Batch($this->transferStrategy, $this->divisorStrategy);
180
+
181
+ if ($this->exceptionBuffering) {
182
+ $batch = new ExceptionBufferingBatch($batch);
183
+ }
184
+
185
+ if ($this->afterFlush) {
186
+ $batch = new NotifyingBatch($batch, $this->afterFlush);
187
+ }
188
+
189
+ if ($this->autoFlush) {
190
+ $batch = new FlushingBatch($batch, $this->autoFlush);
191
+ }
192
+
193
+ if ($this->history) {
194
+ $batch = new HistoryBatch($batch);
195
+ }
196
+
197
+ return $batch;
198
+ }
199
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchClosureDivisor.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ use Guzzle\Common\Exception\InvalidArgumentException;
6
+
7
+ /**
8
+ * Divides batches using a callable
9
+ */
10
+ class BatchClosureDivisor implements BatchDivisorInterface
11
+ {
12
+ /** @var callable Method used to divide the batches */
13
+ protected $callable;
14
+
15
+ /** @var mixed $context Context passed to the callable */
16
+ protected $context;
17
+
18
+ /**
19
+ * @param callable $callable Method used to divide the batches. The method must accept an \SplQueue and return an
20
+ * array of arrays containing the divided items.
21
+ * @param mixed $context Optional context to pass to the batch divisor
22
+ *
23
+ * @throws InvalidArgumentException if the callable is not callable
24
+ */
25
+ public function __construct($callable, $context = null)
26
+ {
27
+ if (!is_callable($callable)) {
28
+ throw new InvalidArgumentException('Must pass a callable');
29
+ }
30
+
31
+ $this->callable = $callable;
32
+ $this->context = $context;
33
+ }
34
+
35
+ public function createBatches(\SplQueue $queue)
36
+ {
37
+ return call_user_func($this->callable, $queue, $this->context);
38
+ }
39
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchClosureTransfer.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ use Guzzle\Common\Exception\InvalidArgumentException;
6
+
7
+ /**
8
+ * Batch transfer strategy where transfer logic can be defined via a Closure.
9
+ * This class is to be used with {@see Guzzle\Batch\BatchInterface}
10
+ */
11
+ class BatchClosureTransfer implements BatchTransferInterface
12
+ {
13
+ /** @var callable A closure that performs the transfer */
14
+ protected $callable;
15
+
16
+ /** @var mixed $context Context passed to the callable */
17
+ protected $context;
18
+
19
+ /**
20
+ * @param mixed $callable Callable that performs the transfer. This function should accept two arguments:
21
+ * (array $batch, mixed $context).
22
+ * @param mixed $context Optional context to pass to the batch divisor
23
+ *
24
+ * @throws InvalidArgumentException
25
+ */
26
+ public function __construct($callable, $context = null)
27
+ {
28
+ if (!is_callable($callable)) {
29
+ throw new InvalidArgumentException('Argument must be callable');
30
+ }
31
+
32
+ $this->callable = $callable;
33
+ $this->context = $context;
34
+ }
35
+
36
+ public function transfer(array $batch)
37
+ {
38
+ return empty($batch) ? null : call_user_func($this->callable, $batch, $this->context);
39
+ }
40
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchCommandTransfer.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ use Guzzle\Batch\BatchTransferInterface;
6
+ use Guzzle\Batch\BatchDivisorInterface;
7
+ use Guzzle\Common\Exception\InvalidArgumentException;
8
+ use Guzzle\Service\Command\CommandInterface;
9
+ use Guzzle\Service\Exception\InconsistentClientTransferException;
10
+
11
+ /**
12
+ * Efficiently transfers multiple commands in parallel per client
13
+ * This class is to be used with {@see Guzzle\Batch\BatchInterface}
14
+ */
15
+ class BatchCommandTransfer implements BatchTransferInterface, BatchDivisorInterface
16
+ {
17
+ /** @var int Size of each command batch */
18
+ protected $batchSize;
19
+
20
+ /**
21
+ * @param int $batchSize Size of each batch
22
+ */
23
+ public function __construct($batchSize = 50)
24
+ {
25
+ $this->batchSize = $batchSize;
26
+ }
27
+
28
+ /**
29
+ * Creates batches by grouping commands by their associated client
30
+ * {@inheritdoc}
31
+ */
32
+ public function createBatches(\SplQueue $queue)
33
+ {
34
+ $groups = new \SplObjectStorage();
35
+ foreach ($queue as $item) {
36
+ if (!$item instanceof CommandInterface) {
37
+ throw new InvalidArgumentException('All items must implement Guzzle\Service\Command\CommandInterface');
38
+ }
39
+ $client = $item->getClient();
40
+ if (!$groups->contains($client)) {
41
+ $groups->attach($client, new \ArrayObject(array($item)));
42
+ } else {
43
+ $groups[$client]->append($item);
44
+ }
45
+ }
46
+
47
+ $batches = array();
48
+ foreach ($groups as $batch) {
49
+ $batches = array_merge($batches, array_chunk($groups[$batch]->getArrayCopy(), $this->batchSize));
50
+ }
51
+
52
+ return $batches;
53
+ }
54
+
55
+ public function transfer(array $batch)
56
+ {
57
+ if (empty($batch)) {
58
+ return;
59
+ }
60
+
61
+ // Get the client of the first found command
62
+ $client = reset($batch)->getClient();
63
+
64
+ // Keep a list of all commands with invalid clients
65
+ $invalid = array_filter($batch, function ($command) use ($client) {
66
+ return $command->getClient() !== $client;
67
+ });
68
+
69
+ if (!empty($invalid)) {
70
+ throw new InconsistentClientTransferException($invalid);
71
+ }
72
+
73
+ $client->execute($batch);
74
+ }
75
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchDivisorInterface.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ /**
6
+ * Interface used for dividing a queue of items into an array of batches
7
+ */
8
+ interface BatchDivisorInterface
9
+ {
10
+ /**
11
+ * Divide a queue of items into an array batches
12
+ *
13
+ * @param \SplQueue $queue Queue of items to divide into batches. Items are removed as they are iterated.
14
+ *
15
+ * @return array|\Traversable Returns an array or Traversable object that contains arrays of items to transfer
16
+ */
17
+ public function createBatches(\SplQueue $queue);
18
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchInterface.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ /**
6
+ * Interface for efficiently transferring items in a queue using batches
7
+ */
8
+ interface BatchInterface
9
+ {
10
+ /**
11
+ * Add an item to the queue
12
+ *
13
+ * @param mixed $item Item to add
14
+ *
15
+ * @return self
16
+ */
17
+ public function add($item);
18
+
19
+ /**
20
+ * Flush the batch and transfer the items
21
+ *
22
+ * @return array Returns an array flushed items
23
+ */
24
+ public function flush();
25
+
26
+ /**
27
+ * Check if the batch is empty and has further items to transfer
28
+ *
29
+ * @return bool
30
+ */
31
+ public function isEmpty();
32
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchRequestTransfer.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ use Guzzle\Batch\BatchTransferInterface;
6
+ use Guzzle\Batch\BatchDivisorInterface;
7
+ use Guzzle\Common\Exception\InvalidArgumentException;
8
+ use Guzzle\Http\Message\RequestInterface;
9
+
10
+ /**
11
+ * Batch transfer strategy used to efficiently transfer a batch of requests.
12
+ * This class is to be used with {@see Guzzle\Batch\BatchInterface}
13
+ */
14
+ class BatchRequestTransfer implements BatchTransferInterface, BatchDivisorInterface
15
+ {
16
+ /** @var int Size of each command batch */
17
+ protected $batchSize;
18
+
19
+ /**
20
+ * Constructor used to specify how large each batch should be
21
+ *
22
+ * @param int $batchSize Size of each batch
23
+ */
24
+ public function __construct($batchSize = 50)
25
+ {
26
+ $this->batchSize = $batchSize;
27
+ }
28
+
29
+ /**
30
+ * Creates batches of requests by grouping requests by their associated curl multi object.
31
+ * {@inheritdoc}
32
+ */
33
+ public function createBatches(\SplQueue $queue)
34
+ {
35
+ // Create batches by client objects
36
+ $groups = new \SplObjectStorage();
37
+ foreach ($queue as $item) {
38
+ if (!$item instanceof RequestInterface) {
39
+ throw new InvalidArgumentException('All items must implement Guzzle\Http\Message\RequestInterface');
40
+ }
41
+ $client = $item->getClient();
42
+ if (!$groups->contains($client)) {
43
+ $groups->attach($client, array($item));
44
+ } else {
45
+ $current = $groups[$client];
46
+ $current[] = $item;
47
+ $groups[$client] = $current;
48
+ }
49
+ }
50
+
51
+ $batches = array();
52
+ foreach ($groups as $batch) {
53
+ $batches = array_merge($batches, array_chunk($groups[$batch], $this->batchSize));
54
+ }
55
+
56
+ return $batches;
57
+ }
58
+
59
+ public function transfer(array $batch)
60
+ {
61
+ if ($batch) {
62
+ reset($batch)->getClient()->send($batch);
63
+ }
64
+ }
65
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchSizeDivisor.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ /**
6
+ * Divides batches into smaller batches under a certain size
7
+ */
8
+ class BatchSizeDivisor implements BatchDivisorInterface
9
+ {
10
+ /** @var int Size of each batch */
11
+ protected $size;
12
+
13
+ /** @param int $size Size of each batch */
14
+ public function __construct($size)
15
+ {
16
+ $this->size = $size;
17
+ }
18
+
19
+ /**
20
+ * Set the size of each batch
21
+ *
22
+ * @param int $size Size of each batch
23
+ *
24
+ * @return BatchSizeDivisor
25
+ */
26
+ public function setSize($size)
27
+ {
28
+ $this->size = $size;
29
+
30
+ return $this;
31
+ }
32
+
33
+ /**
34
+ * Get the size of each batch
35
+ *
36
+ * @return int
37
+ */
38
+ public function getSize()
39
+ {
40
+ return $this->size;
41
+ }
42
+
43
+ public function createBatches(\SplQueue $queue)
44
+ {
45
+ return array_chunk(iterator_to_array($queue, false), $this->size);
46
+ }
47
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/BatchTransferInterface.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ /**
6
+ * Interface used for transferring batches of items
7
+ */
8
+ interface BatchTransferInterface
9
+ {
10
+ /**
11
+ * Transfer an array of items
12
+ *
13
+ * @param array $batch Array of items to transfer
14
+ */
15
+ public function transfer(array $batch);
16
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/Exception/BatchTransferException.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch\Exception;
4
+
5
+ use Guzzle\Common\Exception\GuzzleException;
6
+ use Guzzle\Batch\BatchTransferInterface as TransferStrategy;
7
+ use Guzzle\Batch\BatchDivisorInterface as DivisorStrategy;
8
+
9
+ /**
10
+ * Exception thrown during a batch transfer
11
+ */
12
+ class BatchTransferException extends \Exception implements GuzzleException
13
+ {
14
+ /** @var array The batch being sent when the exception occurred */
15
+ protected $batch;
16
+
17
+ /** @var TransferStrategy The transfer strategy in use when the exception occurred */
18
+ protected $transferStrategy;
19
+
20
+ /** @var DivisorStrategy The divisor strategy in use when the exception occurred */
21
+ protected $divisorStrategy;
22
+
23
+ /** @var array Items transferred at the point in which the exception was encountered */
24
+ protected $transferredItems;
25
+
26
+ /**
27
+ * @param array $batch The batch being sent when the exception occurred
28
+ * @param array $transferredItems Items transferred at the point in which the exception was encountered
29
+ * @param \Exception $exception Exception encountered
30
+ * @param TransferStrategy $transferStrategy The transfer strategy in use when the exception occurred
31
+ * @param DivisorStrategy $divisorStrategy The divisor strategy in use when the exception occurred
32
+ */
33
+ public function __construct(
34
+ array $batch,
35
+ array $transferredItems,
36
+ \Exception $exception,
37
+ TransferStrategy $transferStrategy = null,
38
+ DivisorStrategy $divisorStrategy = null
39
+ ) {
40
+ $this->batch = $batch;
41
+ $this->transferredItems = $transferredItems;
42
+ $this->transferStrategy = $transferStrategy;
43
+ $this->divisorStrategy = $divisorStrategy;
44
+ parent::__construct(
45
+ 'Exception encountered while transferring batch: ' . $exception->getMessage(),
46
+ $exception->getCode(),
47
+ $exception
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Get the batch that we being sent when the exception occurred
53
+ *
54
+ * @return array
55
+ */
56
+ public function getBatch()
57
+ {
58
+ return $this->batch;
59
+ }
60
+
61
+ /**
62
+ * Get the items transferred at the point in which the exception was encountered
63
+ *
64
+ * @return array
65
+ */
66
+ public function getTransferredItems()
67
+ {
68
+ return $this->transferredItems;
69
+ }
70
+
71
+ /**
72
+ * Get the transfer strategy
73
+ *
74
+ * @return TransferStrategy
75
+ */
76
+ public function getTransferStrategy()
77
+ {
78
+ return $this->transferStrategy;
79
+ }
80
+
81
+ /**
82
+ * Get the divisor strategy
83
+ *
84
+ * @return DivisorStrategy
85
+ */
86
+ public function getDivisorStrategy()
87
+ {
88
+ return $this->divisorStrategy;
89
+ }
90
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/ExceptionBufferingBatch.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ use Guzzle\Batch\Exception\BatchTransferException;
6
+
7
+ /**
8
+ * BatchInterface decorator used to buffer exceptions encountered during a transfer. The exceptions can then later be
9
+ * processed after a batch flush has completed.
10
+ */
11
+ class ExceptionBufferingBatch extends AbstractBatchDecorator
12
+ {
13
+ /** @var array Array of BatchTransferException exceptions */
14
+ protected $exceptions = array();
15
+
16
+ public function flush()
17
+ {
18
+ $items = array();
19
+
20
+ while (!$this->decoratedBatch->isEmpty()) {
21
+ try {
22
+ $transferredItems = $this->decoratedBatch->flush();
23
+ } catch (BatchTransferException $e) {
24
+ $this->exceptions[] = $e;
25
+ $transferredItems = $e->getTransferredItems();
26
+ }
27
+ $items = array_merge($items, $transferredItems);
28
+ }
29
+
30
+ return $items;
31
+ }
32
+
33
+ /**
34
+ * Get the buffered exceptions
35
+ *
36
+ * @return array Array of BatchTransferException objects
37
+ */
38
+ public function getExceptions()
39
+ {
40
+ return $this->exceptions;
41
+ }
42
+
43
+ /**
44
+ * Clear the buffered exceptions
45
+ */
46
+ public function clearExceptions()
47
+ {
48
+ $this->exceptions = array();
49
+ }
50
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/FlushingBatch.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ /**
6
+ * BatchInterface decorator used to add automatic flushing of the queue when the size of the queue reaches a threshold.
7
+ */
8
+ class FlushingBatch extends AbstractBatchDecorator
9
+ {
10
+ /** @var int The threshold for which to automatically flush */
11
+ protected $threshold;
12
+
13
+ /** @var int Current number of items known to be in the queue */
14
+ protected $currentTotal = 0;
15
+
16
+ /**
17
+ * @param BatchInterface $decoratedBatch BatchInterface that is being decorated
18
+ * @param int $threshold Flush when the number in queue matches the threshold
19
+ */
20
+ public function __construct(BatchInterface $decoratedBatch, $threshold)
21
+ {
22
+ $this->threshold = $threshold;
23
+ parent::__construct($decoratedBatch);
24
+ }
25
+
26
+ /**
27
+ * Set the auto-flush threshold
28
+ *
29
+ * @param int $threshold The auto-flush threshold
30
+ *
31
+ * @return FlushingBatch
32
+ */
33
+ public function setThreshold($threshold)
34
+ {
35
+ $this->threshold = $threshold;
36
+
37
+ return $this;
38
+ }
39
+
40
+ /**
41
+ * Get the auto-flush threshold
42
+ *
43
+ * @return int
44
+ */
45
+ public function getThreshold()
46
+ {
47
+ return $this->threshold;
48
+ }
49
+
50
+ public function add($item)
51
+ {
52
+ $this->decoratedBatch->add($item);
53
+ if (++$this->currentTotal >= $this->threshold) {
54
+ $this->currentTotal = 0;
55
+ $this->decoratedBatch->flush();
56
+ }
57
+
58
+ return $this;
59
+ }
60
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/HistoryBatch.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ /**
6
+ * BatchInterface decorator used to keep a history of items that were added to the batch. You must clear the history
7
+ * manually to remove items from the history.
8
+ */
9
+ class HistoryBatch extends AbstractBatchDecorator
10
+ {
11
+ /** @var array Items in the history */
12
+ protected $history = array();
13
+
14
+ public function add($item)
15
+ {
16
+ $this->history[] = $item;
17
+ $this->decoratedBatch->add($item);
18
+
19
+ return $this;
20
+ }
21
+
22
+ /**
23
+ * Get the batch history
24
+ *
25
+ * @return array
26
+ */
27
+ public function getHistory()
28
+ {
29
+ return $this->history;
30
+ }
31
+
32
+ /**
33
+ * Clear the batch history
34
+ */
35
+ public function clearHistory()
36
+ {
37
+ $this->history = array();
38
+ }
39
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Batch/NotifyingBatch.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Batch;
4
+
5
+ use Guzzle\Common\Exception\InvalidArgumentException;
6
+
7
+ /**
8
+ * BatchInterface decorator used to call a method each time flush is called
9
+ */
10
+ class NotifyingBatch extends AbstractBatchDecorator
11
+ {
12
+ /** @var mixed Callable to call */
13
+ protected $callable;
14
+
15
+ /**
16
+ * @param BatchInterface $decoratedBatch Batch object to decorate
17
+ * @param mixed $callable Callable to call
18
+ *
19
+ * @throws InvalidArgumentException
20
+ */
21
+ public function __construct(BatchInterface $decoratedBatch, $callable)
22
+ {
23
+ if (!is_callable($callable)) {
24
+ throw new InvalidArgumentException('The passed argument is not callable');
25
+ }
26
+
27
+ $this->callable = $callable;
28
+ parent::__construct($decoratedBatch);
29
+ }
30
+
31
+ public function flush()
32
+ {
33
+ $items = $this->decoratedBatch->flush();
34
+ call_user_func($this->callable, $items);
35
+
36
+ return $items;
37
+ }
38
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Http/Curl/CurlHandle.php CHANGED
@@ -209,7 +209,7 @@ class CurlHandle
209
  $args[] = $handle;
210
 
211
  // PHP 5.5 pushed the handle onto the start of the args
212
- if (is_resource($args[0])) {
213
  array_shift($args);
214
  }
215
 
@@ -233,7 +233,7 @@ class CurlHandle
233
  */
234
  public function __construct($handle, $options)
235
  {
236
- if (!is_resource($handle)) {
237
  throw new InvalidArgumentException('Invalid handle provided');
238
  }
239
  if (is_array($options)) {
@@ -259,8 +259,9 @@ class CurlHandle
259
  */
260
  public function close()
261
  {
262
- if (is_resource($this->handle)) {
263
  curl_close($this->handle);
 
264
  }
265
  $this->handle = null;
266
  }
@@ -272,7 +273,7 @@ class CurlHandle
272
  */
273
  public function isAvailable()
274
  {
275
- return is_resource($this->handle);
276
  }
277
 
278
  /**
@@ -322,7 +323,7 @@ class CurlHandle
322
  */
323
  public function getInfo($option = null)
324
  {
325
- if (!is_resource($this->handle)) {
326
  return null;
327
  }
328
 
209
  $args[] = $handle;
210
 
211
  // PHP 5.5 pushed the handle onto the start of the args
212
+ if (false !== $args[0]) {
213
  array_shift($args);
214
  }
215
 
233
  */
234
  public function __construct($handle, $options)
235
  {
236
+ if (false === $handle) {
237
  throw new InvalidArgumentException('Invalid handle provided');
238
  }
239
  if (is_array($options)) {
259
  */
260
  public function close()
261
  {
262
+ if (false !== $this->handle && null !== $this->handle) {
263
  curl_close($this->handle);
264
+ unset($this->handle);
265
  }
266
  $this->handle = null;
267
  }
273
  */
274
  public function isAvailable()
275
  {
276
+ return false !== $this->handle;
277
  }
278
 
279
  /**
323
  */
324
  public function getInfo($option = null)
325
  {
326
+ if (false === $this->handle) {
327
  return null;
328
  }
329
 
lib/amazon/guzzle/guzzle/src/Guzzle/Http/Curl/CurlMulti.php CHANGED
@@ -58,7 +58,7 @@ class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface
58
 
59
  public function __destruct()
60
  {
61
- if (is_resource($this->multiHandle)) {
62
  curl_multi_close($this->multiHandle);
63
  }
64
  }
58
 
59
  public function __destruct()
60
  {
61
+ if (false !== $this->multiHandle) {
62
  curl_multi_close($this->multiHandle);
63
  }
64
  }
lib/amazon/guzzle/guzzle/src/Guzzle/Http/Curl/RequestMediator.php CHANGED
@@ -44,6 +44,7 @@ class RequestMediator
44
  if (strpos($header, 'HTTP/') === 0) {
45
 
46
  $startLine = explode(' ', $header, 3);
 
47
  $code = $startLine[1];
48
  $status = isset($startLine[2]) ? $startLine[2] : '';
49
 
@@ -56,6 +57,7 @@ class RequestMediator
56
  }
57
 
58
  $response = new Response($code, null, $body);
 
59
  $response->setStatus($code, $status);
60
  $this->request->startResponse($response);
61
 
44
  if (strpos($header, 'HTTP/') === 0) {
45
 
46
  $startLine = explode(' ', $header, 3);
47
+ list($protocol, $version) = explode('/', trim($startLine[0]));
48
  $code = $startLine[1];
49
  $status = isset($startLine[2]) ? $startLine[2] : '';
50
 
57
  }
58
 
59
  $response = new Response($code, null, $body);
60
+ $response->setProtocol($protocol, $version);
61
  $response->setStatus($code, $status);
62
  $this->request->startResponse($response);
63
 
lib/amazon/guzzle/guzzle/src/Guzzle/Http/EntityBody.php-tmp DELETED
@@ -1,188 +0,0 @@
1
- <?php
2
-
3
- namespace Guzzle\Http;
4
-
5
- use Guzzle\Common\Exception\InvalidArgumentException;
6
- use Guzzle\Common\Version;
7
- use Guzzle\Http\Mimetypes;
8
- use Guzzle\Stream\Stream;
9
-
10
- /**
11
- * Entity body used with an HTTP request or response
12
- */
13
-
14
- class EntityBody extends Stream implements EntityBodyInterface {
15
- /** @var bool Content-Encoding of the entity body if known */
16
- protected $contentEncoding = false;
17
-
18
- /** @var callable Method to invoke for rewinding a stream */
19
- protected $rewindFunction;
20
-
21
- /**
22
- * Create a new EntityBody based on the input type
23
- *
24
- * @param resource|string|EntityBody $resource Entity body data
25
- * @param int $size Size of the data contained in the resource
26
- *
27
- * @return EntityBody
28
- * @throws InvalidArgumentException if the $resource arg is not a resource or string
29
- */
30
- public static function factory($resource = '', $size = null) {
31
- if ($resource instanceof EntityBodyInterface) {
32
- return $resource;
33
- }
34
-
35
- switch (gettype($resource)) {
36
- case 'string':
37
- return self::fromString($resource);
38
- case 'resource':
39
- return new static ($resource, $size);
40
- case 'object':
41
- if (method_exists($resource, '__toString')) {
42
- return self::fromString((string) $resource);
43
- }
44
- break;
45
- case 'array':
46
- return self::fromString(http_build_query($resource));
47
- }
48
-
49
- throw new InvalidArgumentException('Invalid resource type');
50
- }
51
-
52
- public function setRewindFunction($callable) {
53
- if (!is_callable($callable)) {
54
- throw new InvalidArgumentException('Must specify a callable');
55
- }
56
-
57
- $this->rewindFunction = $callable;
58
-
59
- return $this;
60
- }
61
-
62
- public function rewind() {
63
- return $this->rewindFunction?call_user_func($this->rewindFunction, $this):parent::rewind();
64
- }
65
-
66
- /**
67
- * Create a new EntityBody from a string
68
- *
69
- * @param string $string String of data
70
- *
71
- * @return EntityBody
72
- */
73
- public static function fromString($string) {
74
- $stream = fopen('php://temp', 'r+');
75
- if ($string !== '') {
76
- fwrite($stream, $string);
77
- rewind($stream);
78
- }
79
-
80
- return new static ($stream);
81
- }
82
-
83
- public function compress($filter = 'zlib.deflate') {
84
- $result = $this->handleCompression($filter);
85
- $this->contentEncoding = $result?$filter:false;
86
-
87
- return $result;
88
- }
89
-
90
- public function uncompress($filter = 'zlib.inflate') {
91
- $offsetStart = 0;
92
-
93
- // When inflating gzipped data, the first 10 bytes must be stripped
94
- // if a gzip header is present
95
- if ($filter == 'zlib.inflate') {
96
- // @codeCoverageIgnoreStart
97
- if (!$this->isReadable() || ($this->isConsumed() && !$this->isSeekable())) {
98
- return false;
99
- }
100
- // @codeCoverageIgnoreEnd
101
- if (stream_get_contents($this->stream, 3, 0) === "\x1f\x8b\x08") {
102
- $offsetStart = 10;
103
- }
104
- }
105
-
106
- $this->contentEncoding = false;
107
-
108
- return $this->handleCompression($filter, $offsetStart);
109
- }
110
-
111
- public function getContentLength() {
112
- return $this->getSize();
113
- }
114
-
115
- public function getContentType() {
116
- return $this->getUri()?Mimetypes::getInstance()->fromFilename($this->getUri()):null;
117
- }
118
-
119
- public function getContentMd5($rawOutput = false, $base64Encode = false) {
120
- if ($hash = self::getHash($this, 'md5', $rawOutput)) {
121
- return $hash && $base64Encode?base64_encode($hash):$hash;
122
- } else {
123
- return false;
124
- }
125
- }
126
-
127
- /**
128
- * Calculate the MD5 hash of an entity body
129
- *
130
- * @param EntityBodyInterface $body Entity body to calculate the hash for
131
- * @param bool $rawOutput Whether or not to use raw output
132
- * @param bool $base64Encode Whether or not to base64 encode raw output (only if raw output is true)
133
- *
134
- * @return bool|string Returns an MD5 string on success or FALSE on failure
135
- * @deprecated This will be deprecated soon
136
- * @codeCoverageIgnore
137
- */
138
- public static function calculateMd5(EntityBodyInterface $body, $rawOutput = false, $base64Encode = false) {
139
- Version::warn(__CLASS__ .' is deprecated. Use getContentMd5()');
140
- return $body->getContentMd5($rawOutput, $base64Encode);
141
- }
142
-
143
- public function setStreamFilterContentEncoding($streamFilterContentEncoding) {
144
- $this->contentEncoding = $streamFilterContentEncoding;
145
-
146
- return $this;
147
- }
148
-
149
- public function getContentEncoding() {
150
- return strtr($this->contentEncoding, array(
151
- 'zlib.deflate' => 'gzip',
152
- 'bzip2.compress' => 'compress'
153
- ))?:false;
154
- }
155
-
156
- protected function handleCompression($filter, $offsetStart = 0) {
157
- // @codeCoverageIgnoreStart
158
- if (!$this->isReadable() || ($this->isConsumed() && !$this->isSeekable())) {
159
- return false;
160
- }
161
- // @codeCoverageIgnoreEnd
162
-
163
- $handle = fopen('php://temp', 'r+');
164
- $filter = @stream_filter_append($handle, $filter, STREAM_FILTER_WRITE);
165
- if (!$filter) {
166
- return false;
167
- }
168
-
169
- // Seek to the offset start if possible
170
- $this->seek($offsetStart);
171
- while ($data = fread($this->stream, 8096)) {
172
- fwrite($handle, $data);
173
- }
174
-
175
- fclose($this->stream);
176
- $this->stream = $handle;
177
- stream_filter_remove($filter);
178
- $stat = fstat($this->stream);
179
- $this->size = $stat['size'];
180
- $this->rebuildCache();
181
- $this->seek(0);
182
-
183
- // Remove any existing rewind function as the underlying stream has been replaced
184
- $this->rewindFunction = null;
185
-
186
- return true;
187
- }
188
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/amazon/guzzle/guzzle/src/Guzzle/Http/Message/Response.php CHANGED
@@ -879,7 +879,7 @@ class Response extends AbstractMessage implements \Serializable
879
  {
880
  $errorMessage = null;
881
  $internalErrors = libxml_use_internal_errors(true);
882
- $disableEntities = libxml_disable_entity_loader(true);
883
  libxml_clear_errors();
884
 
885
  try {
@@ -893,7 +893,7 @@ class Response extends AbstractMessage implements \Serializable
893
 
894
  libxml_clear_errors();
895
  libxml_use_internal_errors($internalErrors);
896
- libxml_disable_entity_loader($disableEntities);
897
 
898
  if ($errorMessage) {
899
  throw new RuntimeException('Unable to parse response body into XML: ' . $errorMessage);
879
  {
880
  $errorMessage = null;
881
  $internalErrors = libxml_use_internal_errors(true);
882
+ if (\PHP_VERSION_ID < 80000) $disableEntities = libxml_disable_entity_loader(true);
883
  libxml_clear_errors();
884
 
885
  try {
893
 
894
  libxml_clear_errors();
895
  libxml_use_internal_errors($internalErrors);
896
+ if (\PHP_VERSION_ID < 80000) libxml_disable_entity_loader($disableEntities);
897
 
898
  if ($errorMessage) {
899
  throw new RuntimeException('Unable to parse response body into XML: ' . $errorMessage);
lib/amazon/guzzle/guzzle/src/Guzzle/Log/AbstractLogAdapter.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ /**
6
+ * Adapter class that allows Guzzle to log data using various logging implementations
7
+ */
8
+ abstract class AbstractLogAdapter implements LogAdapterInterface
9
+ {
10
+ protected $log;
11
+
12
+ public function getLogObject()
13
+ {
14
+ return $this->log;
15
+ }
16
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Log/ArrayLogAdapter.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ /**
6
+ * Stores all log messages in an array
7
+ */
8
+ class ArrayLogAdapter implements LogAdapterInterface
9
+ {
10
+ protected $logs = array();
11
+
12
+ public function log($message, $priority = LOG_INFO, $extras = array())
13
+ {
14
+ $this->logs[] = array('message' => $message, 'priority' => $priority, 'extras' => $extras);
15
+ }
16
+
17
+ /**
18
+ * Get logged entries
19
+ *
20
+ * @return array
21
+ */
22
+ public function getLogs()
23
+ {
24
+ return $this->logs;
25
+ }
26
+
27
+ /**
28
+ * Clears logged entries
29
+ */
30
+ public function clearLogs()
31
+ {
32
+ $this->logs = array();
33
+ }
34
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Log/ClosureLogAdapter.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ /**
6
+ * Logs messages using Closures. Closures combined with filtering can trigger application events based on log messages.
7
+ */
8
+ class ClosureLogAdapter extends AbstractLogAdapter
9
+ {
10
+ public function __construct($logObject)
11
+ {
12
+ if (!is_callable($logObject)) {
13
+ throw new \InvalidArgumentException('Object must be callable');
14
+ }
15
+
16
+ $this->log = $logObject;
17
+ }
18
+
19
+ public function log($message, $priority = LOG_INFO, $extras = array())
20
+ {
21
+ call_user_func($this->log, $message, $priority, $extras);
22
+ }
23
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Log/LogAdapterInterface.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ /**
6
+ * Adapter class that allows Guzzle to log data to various logging implementations.
7
+ */
8
+ interface LogAdapterInterface
9
+ {
10
+ /**
11
+ * Log a message at a priority
12
+ *
13
+ * @param string $message Message to log
14
+ * @param integer $priority Priority of message (use the \LOG_* constants of 0 - 7)
15
+ * @param array $extras Extra information to log in event
16
+ */
17
+ public function log($message, $priority = LOG_INFO, $extras = array());
18
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Log/MessageFormatter.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ use Guzzle\Http\Curl\CurlHandle;
6
+ use Guzzle\Http\Message\RequestInterface;
7
+ use Guzzle\Http\Message\EntityEnclosingRequestInterface;
8
+ use Guzzle\Http\Message\Response;
9
+
10
+ /**
11
+ * Message formatter used in various places in the framework
12
+ *
13
+ * Format messages using a template that can contain the the following variables:
14
+ *
15
+ * - {request}: Full HTTP request message
16
+ * - {response}: Full HTTP response message
17
+ * - {ts}: Timestamp
18
+ * - {host}: Host of the request
19
+ * - {method}: Method of the request
20
+ * - {url}: URL of the request
21
+ * - {host}: Host of the request
22
+ * - {protocol}: Request protocol
23
+ * - {version}: Protocol version
24
+ * - {resource}: Resource of the request (path + query + fragment)
25
+ * - {port}: Port of the request
26
+ * - {hostname}: Hostname of the machine that sent the request
27
+ * - {code}: Status code of the response (if available)
28
+ * - {phrase}: Reason phrase of the response (if available)
29
+ * - {curl_error}: Curl error message (if available)
30
+ * - {curl_code}: Curl error code (if available)
31
+ * - {curl_stderr}: Curl standard error (if available)
32
+ * - {connect_time}: Time in seconds it took to establish the connection (if available)
33
+ * - {total_time}: Total transaction time in seconds for last transfer (if available)
34
+ * - {req_header_*}: Replace `*` with the lowercased name of a request header to add to the message
35
+ * - {res_header_*}: Replace `*` with the lowercased name of a response header to add to the message
36
+ * - {req_body}: Request body
37
+ * - {res_body}: Response body
38
+ */
39
+ class MessageFormatter
40
+ {
41
+ const DEFAULT_FORMAT = "{hostname} {req_header_User-Agent} - [{ts}] \"{method} {resource} {protocol}/{version}\" {code} {res_header_Content-Length}";
42
+ const DEBUG_FORMAT = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{curl_stderr}";
43
+ const SHORT_FORMAT = '[{ts}] "{method} {resource} {protocol}/{version}" {code}';
44
+
45
+ /**
46
+ * @var string Template used to format log messages
47
+ */
48
+ protected $template;
49
+
50
+ /**
51
+ * @param string $template Log message template
52
+ */
53
+ public function __construct($template = self::DEFAULT_FORMAT)
54
+ {
55
+ $this->template = $template ?: self::DEFAULT_FORMAT;
56
+ }
57
+
58
+ /**
59
+ * Set the template to use for logging
60
+ *
61
+ * @param string $template Log message template
62
+ *
63
+ * @return self
64
+ */
65
+ public function setTemplate($template)
66
+ {
67
+ $this->template = $template;
68
+
69
+ return $this;
70
+ }
71
+
72
+ /**
73
+ * Returns a formatted message
74
+ *
75
+ * @param RequestInterface $request Request that was sent
76
+ * @param Response $response Response that was received
77
+ * @param CurlHandle $handle Curl handle associated with the message
78
+ * @param array $customData Associative array of custom template data
79
+ *
80
+ * @return string
81
+ */
82
+ public function format(
83
+ RequestInterface $request,
84
+ Response $response = null,
85
+ CurlHandle $handle = null,
86
+ array $customData = array()
87
+ ) {
88
+ $cache = $customData;
89
+
90
+ return preg_replace_callback(
91
+ '/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
92
+ function (array $matches) use ($request, $response, $handle, &$cache) {
93
+
94
+ if (array_key_exists($matches[1], $cache)) {
95
+ return $cache[$matches[1]];
96
+ }
97
+
98
+ $result = '';
99
+ switch ($matches[1]) {
100
+ case 'request':
101
+ $result = (string) $request;
102
+ break;
103
+ case 'response':
104
+ $result = (string) $response;
105
+ break;
106
+ case 'req_body':
107
+ $result = $request instanceof EntityEnclosingRequestInterface
108
+ ? (string) $request->getBody() : '';
109
+ break;
110
+ case 'res_body':
111
+ $result = $response ? $response->getBody(true) : '';
112
+ break;
113
+ case 'ts':
114
+ $result = gmdate('c');
115
+ break;
116
+ case 'method':
117
+ $result = $request->getMethod();
118
+ break;
119
+ case 'url':
120
+ $result = (string) $request->getUrl();
121
+ break;
122
+ case 'resource':
123
+ $result = $request->getResource();
124
+ break;
125
+ case 'protocol':
126
+ $result = 'HTTP';
127
+ break;
128
+ case 'version':
129
+ $result = $request->getProtocolVersion();
130
+ break;
131
+ case 'host':
132
+ $result = $request->getHost();
133
+ break;
134
+ case 'hostname':
135
+ $result = gethostname();
136
+ break;
137
+ case 'port':
138
+ $result = $request->getPort();
139
+ break;
140
+ case 'code':
141
+ $result = $response ? $response->getStatusCode() : '';
142
+ break;
143
+ case 'phrase':
144
+ $result = $response ? $response->getReasonPhrase() : '';
145
+ break;
146
+ case 'connect_time':
147
+ $result = $handle && $handle->getInfo(CURLINFO_CONNECT_TIME)
148
+ ? $handle->getInfo(CURLINFO_CONNECT_TIME)
149
+ : ($response ? $response->getInfo('connect_time') : '');
150
+ break;
151
+ case 'total_time':
152
+ $result = $handle && $handle->getInfo(CURLINFO_TOTAL_TIME)
153
+ ? $handle->getInfo(CURLINFO_TOTAL_TIME)
154
+ : ($response ? $response->getInfo('total_time') : '');
155
+ break;
156
+ case 'curl_error':
157
+ $result = $handle ? $handle->getError() : '';
158
+ break;
159
+ case 'curl_code':
160
+ $result = $handle ? $handle->getErrorNo() : '';
161
+ break;
162
+ case 'curl_stderr':
163
+ $result = $handle ? $handle->getStderr() : '';
164
+ break;
165
+ default:
166
+ if (strpos($matches[1], 'req_header_') === 0) {
167
+ $result = $request->getHeader(substr($matches[1], 11));
168
+ } elseif ($response && strpos($matches[1], 'res_header_') === 0) {
169
+ $result = $response->getHeader(substr($matches[1], 11));
170
+ }
171
+ }
172
+
173
+ $cache[$matches[1]] = $result;
174
+ return $result;
175
+ },
176
+ $this->template
177
+ );
178
+ }
179
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Log/MonologLogAdapter.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ use Monolog\Logger;
6
+
7
+ /**
8
+ * @deprecated
9
+ * @codeCoverageIgnore
10
+ */
11
+ class MonologLogAdapter extends AbstractLogAdapter
12
+ {
13
+ /**
14
+ * syslog to Monolog mappings
15
+ */
16
+ private static $mapping = array(
17
+ LOG_DEBUG => Logger::DEBUG,
18
+ LOG_INFO => Logger::INFO,
19
+ LOG_WARNING => Logger::WARNING,
20
+ LOG_ERR => Logger::ERROR,
21
+ LOG_CRIT => Logger::CRITICAL,
22
+ LOG_ALERT => Logger::ALERT
23
+ );
24
+
25
+ public function __construct(Logger $logObject)
26
+ {
27
+ $this->log = $logObject;
28
+ }
29
+
30
+ public function log($message, $priority = LOG_INFO, $extras = array())
31
+ {
32
+ $this->log->addRecord(self::$mapping[$priority], $message, $extras);
33
+ }
34
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Log/PsrLogAdapter.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ use Psr\Log\LogLevel;
6
+ use Psr\Log\LoggerInterface;
7
+
8
+ /**
9
+ * PSR-3 log adapter
10
+ *
11
+ * @link https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
12
+ */
13
+ class PsrLogAdapter extends AbstractLogAdapter
14
+ {
15
+ /**
16
+ * syslog to PSR-3 mappings
17
+ */
18
+ private static $mapping = array(
19
+ LOG_DEBUG => LogLevel::DEBUG,
20
+ LOG_INFO => LogLevel::INFO,
21
+ LOG_WARNING => LogLevel::WARNING,
22
+ LOG_ERR => LogLevel::ERROR,
23
+ LOG_CRIT => LogLevel::CRITICAL,
24
+ LOG_ALERT => LogLevel::ALERT
25
+ );
26
+
27
+ public function __construct(LoggerInterface $logObject)
28
+ {
29
+ $this->log = $logObject;
30
+ }
31
+
32
+ public function log($message, $priority = LOG_INFO, $extras = array())
33
+ {
34
+ $this->log->log(self::$mapping[$priority], $message, $extras);
35
+ }
36
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Log/Zf1LogAdapter.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ use Guzzle\Common\Version;
6
+
7
+ /**
8
+ * Adapts a Zend Framework 1 logger object
9
+ * @deprecated
10
+ * @codeCoverageIgnore
11
+ */
12
+ class Zf1LogAdapter extends AbstractLogAdapter
13
+ {
14
+ public function __construct(\Zend_Log $logObject)
15
+ {
16
+ $this->log = $logObject;
17
+ Version::warn(__CLASS__ . ' is deprecated');
18
+ }
19
+
20
+ public function log($message, $priority = LOG_INFO, $extras = array())
21
+ {
22
+ $this->log->log($message, $priority, $extras);
23
+ }
24
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Log/Zf2LogAdapter.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Guzzle\Log;
4
+
5
+ use Zend\Log\Logger;
6
+
7
+ /**
8
+ * Adapts a Zend Framework 2 logger object
9
+ */
10
+ class Zf2LogAdapter extends AbstractLogAdapter
11
+ {
12
+ public function __construct(Logger $logObject)
13
+ {
14
+ $this->log = $logObject;
15
+ }
16
+
17
+ public function log($message, $priority = LOG_INFO, $extras = array())
18
+ {
19
+ $this->log->log($priority, $message, $extras);
20
+ }
21
+ }
lib/amazon/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php CHANGED
@@ -28,7 +28,7 @@ class CompositeFactory implements \IteratorAggregate, \Countable, FactoryInterfa
28
  }
29
  $factories[] = new ConcreteClassFactory($client);
30
 
31
- return new self($factories);
32
  }
33
 
34
  /**
28
  }
29
  $factories[] = new ConcreteClassFactory($client);
30
 
31
+ return new static($factories);
32
  }
33
 
34
  /**
lib/amazon/s3IWPBackup.php CHANGED
@@ -329,7 +329,9 @@ class IWP_MMB_S3_MULTICALL extends IWP_MMB_Backup_Multicall
329
  $partNumber++;
330
  }
331
  }
332
- @fclose($file);
 
 
333
  }
334
  catch (S3Exception $e) {
335
  $this->statusLog($this -> hisID, array('stage' => 's3MultiCall', 'status' => 'partiallyCompleted', 'statusMsg' => 'retracingValues','nextFunc' => 'amazons3_backup', 'task_result' => $task_result, 'responseParams' => $result_arr));
@@ -381,7 +383,6 @@ class IWP_MMB_S3_MULTICALL extends IWP_MMB_Backup_Multicall
381
  $status = 'completed';
382
  iwp_mmb_print_flush('Amazon S3 upload: End');
383
  if($status == 'completed'){
384
- $partArrayLength = count($partsArray);
385
  $verificationResult = $this -> postUploadVerification($s3, $backup_file, $as3_file, $type = "amazons3", $as3_bucket,$as3_access_key,$as3_secure_key,$as3_bucket_region);
386
  if(!$verificationResult){
387
  return $this->statusLog($historyID, array('stage' => 'uploadAmazons3', 'status' => 'error', 'statusMsg' => 'S3 verification failed: File may be corrupted.', 'statusCode' => 'docomplete_S3_verification_failed_file_may_be_corrupted'));
@@ -574,7 +575,7 @@ class IWP_MMB_S3_MULTICALL extends IWP_MMB_Backup_Multicall
574
  }
575
  }
576
 
577
- function postUploadS3Verification($backup_file, $destFile, $type = "", $as3_bucket = "", $as3_access_key = "", $as3_secure_key = "", $as3_bucket_region = "", $size1, $size2, $return_size = false){
578
  if (empty($as3_bucket_region)) {
579
  require_once($GLOBALS['iwp_mmb_plugin_dir']."/lib/S3.php");
580
  $s3 = new IWP_MMB_S3(trim($as3_access_key), trim(str_replace(' ', '+', $as3_secure_key)), false, 's3.amazonaws.com');
@@ -612,6 +613,9 @@ class IWP_MMB_S3_MULTICALL extends IWP_MMB_Backup_Multicall
612
  if ($return_size == true) {
613
  return $s3_file_size;
614
  }
 
 
 
615
  echo "S3 fileszie during verification - ".$s3_file_size.PHP_EOL."size 1 - ".$size1.PHP_EOL."size 2 - ".$size2.PHP_EOL;
616
 
617
  if((($s3_file_size >= $size1 && $s3_file_size <= $actual_file_size) || ($s3_file_size <= $size2 && $s3_file_size >= $actual_file_size) || ($s3_file_size == $actual_file_size)) && ($s3_file_size != 0)){
329
  $partNumber++;
330
  }
331
  }
332
+ if(is_resource($file)) {
333
+ @fclose($file);
334
+ }
335
  }
336
  catch (S3Exception $e) {
337
  $this->statusLog($this -> hisID, array('stage' => 's3MultiCall', 'status' => 'partiallyCompleted', 'statusMsg' => 'retracingValues','nextFunc' => 'amazons3_backup', 'task_result' => $task_result, 'responseParams' => $result_arr));
383
  $status = 'completed';
384
  iwp_mmb_print_flush('Amazon S3 upload: End');
385
  if($status == 'completed'){
 
386
  $verificationResult = $this -> postUploadVerification($s3, $backup_file, $as3_file, $type = "amazons3", $as3_bucket,$as3_access_key,$as3_secure_key,$as3_bucket_region);
387
  if(!$verificationResult){
388
  return $this->statusLog($historyID, array('stage' => 'uploadAmazons3', 'status' => 'error', 'statusMsg' => 'S3 verification failed: File may be corrupted.', 'statusCode' => 'docomplete_S3_verification_failed_file_may_be_corrupted'));
575
  }
576
  }
577
 
578
+ function postUploadS3Verification($backup_file, $destFile, $type = "", $as3_bucket = "", $as3_access_key = "", $as3_secure_key = "", $as3_bucket_region = "", $size1 = 0, $size2 = 0, $return_size = false){
579
  if (empty($as3_bucket_region)) {
580
  require_once($GLOBALS['iwp_mmb_plugin_dir']."/lib/S3.php");
581
  $s3 = new IWP_MMB_S3(trim($as3_access_key), trim(str_replace(' ', '+', $as3_secure_key)), false, 's3.amazonaws.com');
613
  if ($return_size == true) {
614
  return $s3_file_size;
615
  }
616
+ if(!isset($actual_file_size)){
617
+ $actual_file_size = 0;
618
+ }
619
  echo "S3 fileszie during verification - ".$s3_file_size.PHP_EOL."size 1 - ".$size1.PHP_EOL."size 2 - ".$size2.PHP_EOL;
620
 
621
  if((($s3_file_size >= $size1 && $s3_file_size <= $actual_file_size) || ($s3_file_size <= $size2 && $s3_file_size >= $actual_file_size) || ($s3_file_size == $actual_file_size)) && ($s3_file_size != 0)){
lib/amazon/symfony/event-dispatcher/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ vendor/
2
+ composer.lock
3
+ phpunit.xml
lib/amazon/symfony/event-dispatcher/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CHANGELOG
2
+ =========
3
+
4
+ 2.5.0
5
+ -----
6
+
7
+ * added Debug\TraceableEventDispatcher (originally in HttpKernel)
8
+ * changed Debug\TraceableEventDispatcherInterface to extend EventDispatcherInterface
9
+ * added RegisterListenersPass (originally in HttpKernel)
10
+
11
+ 2.1.0
12
+ -----
13
+
14
+ * added TraceableEventDispatcherInterface
15
+ * added ContainerAwareEventDispatcher
16
+ * added a reference to the EventDispatcher on the Event
17
+ * added a reference to the Event name on the event
18
+ * added fluid interface to the dispatch() method which now returns the Event
19
+ object
20
+ * added GenericEvent event class
21
+ * added the possibility for subscribers to subscribe several times for the
22
+ same event
23
+ * added ImmutableEventDispatcher
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php → ContainerAwareEventDispatcher.php} RENAMED
@@ -23,32 +23,18 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
23
  */
24
  class ContainerAwareEventDispatcher extends EventDispatcher
25
  {
26
- /**
27
- * The container from where services are loaded.
28
- *
29
- * @var ContainerInterface
30
- */
31
  private $container;
32
 
33
  /**
34
  * The service IDs of the event listeners and subscribers.
35
- *
36
- * @var array
37
  */
38
  private $listenerIds = array();
39
 
40
  /**
41
  * The services registered as listeners.
42
- *
43
- * @var array
44
  */
45
  private $listeners = array();
46
 
47
- /**
48
- * Constructor.
49
- *
50
- * @param ContainerInterface $container A ContainerInterface instance
51
- */
52
  public function __construct(ContainerInterface $container)
53
  {
54
  $this->container = $container;
@@ -68,7 +54,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
68
  */
69
  public function addListenerService($eventName, $callback, $priority = 0)
70
  {
71
- if (!is_array($callback) || 2 !== count($callback)) {
72
  throw new \InvalidArgumentException('Expected an array("service", "method") argument');
73
  }
74
 
@@ -81,7 +67,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
81
 
82
  if (isset($this->listenerIds[$eventName])) {
83
  foreach ($this->listenerIds[$eventName] as $i => $args) {
84
- list($serviceId, $method, $priority) = $args;
85
  $key = $serviceId.'.'.$method;
86
  if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) {
87
  unset($this->listeners[$eventName][$key]);
@@ -100,12 +86,12 @@ class ContainerAwareEventDispatcher extends EventDispatcher
100
  }
101
 
102
  /**
103
- * @see EventDispatcherInterface::hasListeners()
104
  */
105
  public function hasListeners($eventName = null)
106
  {
107
  if (null === $eventName) {
108
- return (bool) count($this->listenerIds) || (bool) count($this->listeners);
109
  }
110
 
111
  if (isset($this->listenerIds[$eventName])) {
@@ -116,7 +102,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
116
  }
117
 
118
  /**
119
- * @see EventDispatcherInterface::getListeners()
120
  */
121
  public function getListeners($eventName = null)
122
  {
@@ -131,6 +117,16 @@ class ContainerAwareEventDispatcher extends EventDispatcher
131
  return parent::getListeners($eventName);
132
  }
133
 
 
 
 
 
 
 
 
 
 
 
134
  /**
135
  * Adds a service as event subscriber.
136
  *
@@ -140,9 +136,9 @@ class ContainerAwareEventDispatcher extends EventDispatcher
140
  public function addSubscriberService($serviceId, $class)
141
  {
142
  foreach ($class::getSubscribedEvents() as $eventName => $params) {
143
- if (is_string($params)) {
144
  $this->listenerIds[$eventName][] = array($serviceId, $params, 0);
145
- } elseif (is_string($params[0])) {
146
  $this->listenerIds[$eventName][] = array($serviceId, $params[0], isset($params[1]) ? $params[1] : 0);
147
  } else {
148
  foreach ($params as $listener) {
@@ -152,21 +148,6 @@ class ContainerAwareEventDispatcher extends EventDispatcher
152
  }
153
  }
154
 
155
- /**
156
- * {@inheritdoc}
157
- *
158
- * Lazily loads listeners for this event from the dependency injection
159
- * container.
160
- *
161
- * @throws \InvalidArgumentException if the service is not defined
162
- */
163
- public function dispatch($eventName, Event $event = null)
164
- {
165
- $this->lazyLoad($eventName);
166
-
167
- return parent::dispatch($eventName, $event);
168
- }
169
-
170
  public function getContainer()
171
  {
172
  return $this->container;
@@ -190,7 +171,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
190
  $key = $serviceId.'.'.$method;
191
  if (!isset($this->listeners[$eventName][$key])) {
192
  $this->addListener($eventName, array($listener, $method), $priority);
193
- } elseif ($listener !== $this->listeners[$eventName][$key]) {
194
  parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method));
195
  $this->addListener($eventName, array($listener, $method), $priority);
196
  }
23
  */
24
  class ContainerAwareEventDispatcher extends EventDispatcher
25
  {
 
 
 
 
 
26
  private $container;
27
 
28
  /**
29
  * The service IDs of the event listeners and subscribers.
 
 
30
  */
31
  private $listenerIds = array();
32
 
33
  /**
34
  * The services registered as listeners.
 
 
35
  */
36
  private $listeners = array();
37
 
 
 
 
 
 
38
  public function __construct(ContainerInterface $container)
39
  {
40
  $this->container = $container;
54
  */
55
  public function addListenerService($eventName, $callback, $priority = 0)
56
  {
57
+ if (!\is_array($callback) || 2 !== \count($callback)) {
58
  throw new \InvalidArgumentException('Expected an array("service", "method") argument');
59
  }
60
 
67
 
68
  if (isset($this->listenerIds[$eventName])) {
69
  foreach ($this->listenerIds[$eventName] as $i => $args) {
70
+ list($serviceId, $method) = $args;
71
  $key = $serviceId.'.'.$method;
72
  if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) {
73
  unset($this->listeners[$eventName][$key]);
86
  }
87
 
88
  /**
89
+ * {@inheritdoc}
90
  */
91
  public function hasListeners($eventName = null)
92
  {
93
  if (null === $eventName) {
94
+ return $this->listenerIds || $this->listeners || parent::hasListeners();
95
  }
96
 
97
  if (isset($this->listenerIds[$eventName])) {
102
  }
103
 
104
  /**
105
+ * {@inheritdoc}
106
  */
107
  public function getListeners($eventName = null)
108
  {
117
  return parent::getListeners($eventName);
118
  }
119
 
120
+ /**
121
+ * {@inheritdoc}
122
+ */
123
+ public function getListenerPriority($eventName, $listener)
124
+ {
125
+ $this->lazyLoad($eventName);
126
+
127
+ return parent::getListenerPriority($eventName, $listener);
128
+ }
129
+
130
  /**
131
  * Adds a service as event subscriber.
132
  *
136
  public function addSubscriberService($serviceId, $class)
137
  {
138
  foreach ($class::getSubscribedEvents() as $eventName => $params) {
139
+ if (\is_string($params)) {
140
  $this->listenerIds[$eventName][] = array($serviceId, $params, 0);
141
+ } elseif (\is_string($params[0])) {
142
  $this->listenerIds[$eventName][] = array($serviceId, $params[0], isset($params[1]) ? $params[1] : 0);
143
  } else {
144
  foreach ($params as $listener) {
148
  }
149
  }
150
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  public function getContainer()
152
  {
153
  return $this->container;
171
  $key = $serviceId.'.'.$method;
172
  if (!isset($this->listeners[$eventName][$key])) {
173
  $this->addListener($eventName, array($listener, $method), $priority);
174
+ } elseif ($this->listeners[$eventName][$key] !== $listener) {
175
  parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method));
176
  $this->addListener($eventName, array($listener, $method), $priority);
177
  }
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/Debug → Debug}/TraceableEventDispatcher.php RENAMED
@@ -11,11 +11,11 @@
11
 
12
  namespace Symfony\Component\EventDispatcher\Debug;
13
 
 
 
14
  use Symfony\Component\EventDispatcher\EventDispatcherInterface;
15
  use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16
- use Symfony\Component\EventDispatcher\Event;
17
  use Symfony\Component\Stopwatch\Stopwatch;
18
- use Psr\Log\LoggerInterface;
19
 
20
  /**
21
  * Collects some data about event listeners.
@@ -33,13 +33,6 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
33
  private $dispatcher;
34
  private $wrappedListeners;
35
 
36
- /**
37
- * Constructor.
38
- *
39
- * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
40
- * @param Stopwatch $stopwatch A Stopwatch instance
41
- * @param LoggerInterface $logger A LoggerInterface instance
42
- */
43
  public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null)
44
  {
45
  $this->dispatcher = $dispatcher;
@@ -99,6 +92,18 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
99
  return $this->dispatcher->getListeners($eventName);
100
  }
101
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  /**
103
  * {@inheritdoc}
104
  */
@@ -116,6 +121,10 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
116
  $event = new Event();
117
  }
118
 
 
 
 
 
119
  $this->preProcess($eventName);
120
  $this->preDispatch($eventName, $event);
121
 
@@ -158,7 +167,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
158
  $allListeners = $this->getListeners();
159
  } catch (\Exception $e) {
160
  if (null !== $this->logger) {
161
- $this->logger->info(sprintf('An exception was thrown while getting the uncalled listeners (%s)', $e->getMessage()), array('exception' => $e));
162
  }
163
 
164
  // unable to retrieve the uncalled listeners
@@ -186,6 +195,8 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
186
  }
187
  }
188
 
 
 
189
  return $notCalled;
190
  }
191
 
@@ -199,7 +210,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
199
  */
200
  public function __call($method, $arguments)
201
  {
202
- return call_user_func_array(array($this->dispatcher, $method), $arguments);
203
  }
204
 
205
  /**
@@ -225,12 +236,12 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
225
  private function preProcess($eventName)
226
  {
227
  foreach ($this->dispatcher->getListeners($eventName) as $listener) {
228
- $this->dispatcher->removeListener($eventName, $listener);
229
  $info = $this->getListenerInfo($listener, $eventName);
230
  $name = isset($info['class']) ? $info['class'] : $info['type'];
231
  $wrappedListener = new WrappedListener($listener, $name, $this->stopwatch, $this);
232
  $this->wrappedListeners[$eventName][] = $wrappedListener;
233
- $this->dispatcher->addListener($eventName, $wrappedListener);
 
234
  }
235
  }
236
 
@@ -243,8 +254,9 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
243
  continue;
244
  }
245
  // Unwrap listener
 
246
  $this->dispatcher->removeListener($eventName, $listener);
247
- $this->dispatcher->addListener($eventName, $listener->getWrappedListener());
248
 
249
  $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName);
250
  if ($listener->wasCalled()) {
@@ -285,13 +297,20 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
285
  {
286
  $info = array(
287
  'event' => $eventName,
 
288
  );
 
 
 
 
 
 
289
  if ($listener instanceof \Closure) {
290
  $info += array(
291
  'type' => 'Closure',
292
  'pretty' => 'closure',
293
  );
294
- } elseif (is_string($listener)) {
295
  try {
296
  $r = new \ReflectionFunction($listener);
297
  $file = $r->getFileName();
@@ -307,11 +326,11 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
307
  'line' => $line,
308
  'pretty' => $listener,
309
  );
310
- } elseif (is_array($listener) || (is_object($listener) && is_callable($listener))) {
311
- if (!is_array($listener)) {
312
  $listener = array($listener, '__invoke');
313
  }
314
- $class = is_object($listener[0]) ? get_class($listener[0]) : $listener[0];
315
  try {
316
  $r = new \ReflectionMethod($class, $listener[1]);
317
  $file = $r->getFileName();
@@ -332,4 +351,25 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
332
 
333
  return $info;
334
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
11
 
12
  namespace Symfony\Component\EventDispatcher\Debug;
13
 
14
+ use Psr\Log\LoggerInterface;
15
+ use Symfony\Component\EventDispatcher\Event;
16
  use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17
  use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
18
  use Symfony\Component\Stopwatch\Stopwatch;
 
19
 
20
  /**
21
  * Collects some data about event listeners.
33
  private $dispatcher;
34
  private $wrappedListeners;
35
 
 
 
 
 
 
 
 
36
  public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null)
37
  {
38
  $this->dispatcher = $dispatcher;
92
  return $this->dispatcher->getListeners($eventName);
93
  }
94
 
95
+ /**
96
+ * {@inheritdoc}
97
+ */
98
+ public function getListenerPriority($eventName, $listener)
99
+ {
100
+ if (!method_exists($this->dispatcher, 'getListenerPriority')) {
101
+ return 0;
102
+ }
103
+
104
+ return $this->dispatcher->getListenerPriority($eventName, $listener);
105
+ }
106
+
107
  /**
108
  * {@inheritdoc}
109
  */
121
  $event = new Event();
122
  }
123
 
124
+ if (null !== $this->logger && $event->isPropagationStopped()) {
125
+ $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName));
126
+ }
127
+
128
  $this->preProcess($eventName);
129
  $this->preDispatch($eventName, $event);
130
 
167
  $allListeners = $this->getListeners();
168
  } catch (\Exception $e) {
169
  if (null !== $this->logger) {
170
+ $this->logger->info('An exception was thrown while getting the uncalled listeners.', array('exception' => $e));
171
  }
172
 
173
  // unable to retrieve the uncalled listeners
195
  }
196
  }
197
 
198
+ uasort($notCalled, array($this, 'sortListenersByPriority'));
199
+
200
  return $notCalled;
201
  }
202
 
210
  */
211
  public function __call($method, $arguments)
212
  {
213
+ return \call_user_func_array(array($this->dispatcher, $method), $arguments);
214
  }
215
 
216
  /**
236
  private function preProcess($eventName)
237
  {
238
  foreach ($this->dispatcher->getListeners($eventName) as $listener) {
 
239
  $info = $this->getListenerInfo($listener, $eventName);
240
  $name = isset($info['class']) ? $info['class'] : $info['type'];
241
  $wrappedListener = new WrappedListener($listener, $name, $this->stopwatch, $this);
242
  $this->wrappedListeners[$eventName][] = $wrappedListener;
243
+ $this->dispatcher->removeListener($eventName, $listener);
244
+ $this->dispatcher->addListener($eventName, $wrappedListener, $info['priority']);
245
  }
246
  }
247
 
254
  continue;
255
  }
256
  // Unwrap listener
257
+ $priority = $this->getListenerPriority($eventName, $listener);
258
  $this->dispatcher->removeListener($eventName, $listener);
259
+ $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority);
260
 
261
  $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName);
262
  if ($listener->wasCalled()) {
297
  {
298
  $info = array(
299
  'event' => $eventName,
300
+ 'priority' => $this->getListenerPriority($eventName, $listener),
301
  );
302
+
303
+ // unwrap for correct listener info
304
+ if ($listener instanceof WrappedListener) {
305
+ $listener = $listener->getWrappedListener();
306
+ }
307
+
308
  if ($listener instanceof \Closure) {
309
  $info += array(
310
  'type' => 'Closure',
311
  'pretty' => 'closure',
312
  );
313
+ } elseif (\is_string($listener)) {
314
  try {
315
  $r = new \ReflectionFunction($listener);
316
  $file = $r->getFileName();
326
  'line' => $line,
327
  'pretty' => $listener,
328
  );
329
+ } elseif (\is_array($listener) || (\is_object($listener) && \is_callable($listener))) {
330
+ if (!\is_array($listener)) {
331
  $listener = array($listener, '__invoke');
332
  }
333
+ $class = \is_object($listener[0]) ? \get_class($listener[0]) : $listener[0];
334
  try {
335
  $r = new \ReflectionMethod($class, $listener[1]);
336
  $file = $r->getFileName();
351
 
352
  return $info;
353
  }
354
+
355
+ private function sortListenersByPriority($a, $b)
356
+ {
357
+ if (\is_int($a['priority']) && !\is_int($b['priority'])) {
358
+ return 1;
359
+ }
360
+
361
+ if (!\is_int($a['priority']) && \is_int($b['priority'])) {
362
+ return -1;
363
+ }
364
+
365
+ if ($a['priority'] === $b['priority']) {
366
+ return 0;
367
+ }
368
+
369
+ if ($a['priority'] > $b['priority']) {
370
+ return -1;
371
+ }
372
+
373
+ return 1;
374
+ }
375
  }
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/Debug → Debug}/TraceableEventDispatcherInterface.php RENAMED
File without changes
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/Debug → Debug}/WrappedListener.php RENAMED
@@ -11,9 +11,9 @@
11
 
12
  namespace Symfony\Component\EventDispatcher\Debug;
13
 
14
- use Symfony\Component\Stopwatch\Stopwatch;
15
  use Symfony\Component\EventDispatcher\Event;
16
  use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
17
 
18
  /**
19
  * @author Fabien Potencier <fabien@symfony.com>
@@ -58,7 +58,7 @@ class WrappedListener
58
 
59
  $e = $this->stopwatch->start($this->name, 'event_listener');
60
 
61
- call_user_func($this->listener, $event, $eventName, $this->dispatcher ?: $dispatcher);
62
 
63
  if ($e->isStarted()) {
64
  $e->stop();
11
 
12
  namespace Symfony\Component\EventDispatcher\Debug;
13
 
 
14
  use Symfony\Component\EventDispatcher\Event;
15
  use Symfony\Component\EventDispatcher\EventDispatcherInterface;
16
+ use Symfony\Component\Stopwatch\Stopwatch;
17
 
18
  /**
19
  * @author Fabien Potencier <fabien@symfony.com>
58
 
59
  $e = $this->stopwatch->start($this->name, 'event_listener');
60
 
61
+ \call_user_func($this->listener, $event, $eventName, $this->dispatcher ?: $dispatcher);
62
 
63
  if ($e->isStarted()) {
64
  $e->stop();
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/DependencyInjection → DependencyInjection}/RegisterListenersPass.php RENAMED
@@ -11,32 +11,19 @@
11
 
12
  namespace Symfony\Component\EventDispatcher\DependencyInjection;
13
 
14
- use Symfony\Component\DependencyInjection\ContainerBuilder;
15
  use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
 
16
 
17
  /**
18
  * Compiler pass to register tagged services for an event dispatcher.
19
  */
20
  class RegisterListenersPass implements CompilerPassInterface
21
  {
22
- /**
23
- * @var string
24
- */
25
  protected $dispatcherService;
26
-
27
- /**
28
- * @var string
29
- */
30
  protected $listenerTag;
31
-
32
- /**
33
- * @var string
34
- */
35
  protected $subscriberTag;
36
 
37
  /**
38
- * Constructor.
39
- *
40
  * @param string $dispatcherService Service name of the event dispatcher in processed container
41
  * @param string $listenerTag Tag name used for listener
42
  * @param string $subscriberTag Tag name used for subscribers
@@ -97,10 +84,13 @@ class RegisterListenersPass implements CompilerPassInterface
97
 
98
  // We must assume that the class value has been correctly filled, even if the service is created by a factory
99
  $class = $container->getParameterBag()->resolveValue($def->getClass());
100
-
101
- $refClass = new \ReflectionClass($class);
102
  $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
103
- if (!$refClass->implementsInterface($interface)) {
 
 
 
 
 
104
  throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
105
  }
106
 
11
 
12
  namespace Symfony\Component\EventDispatcher\DependencyInjection;
13
 
 
14
  use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
16
 
17
  /**
18
  * Compiler pass to register tagged services for an event dispatcher.
19
  */
20
  class RegisterListenersPass implements CompilerPassInterface
21
  {
 
 
 
22
  protected $dispatcherService;
 
 
 
 
23
  protected $listenerTag;
 
 
 
 
24
  protected $subscriberTag;
25
 
26
  /**
 
 
27
  * @param string $dispatcherService Service name of the event dispatcher in processed container
28
  * @param string $listenerTag Tag name used for listener
29
  * @param string $subscriberTag Tag name used for subscribers
84
 
85
  // We must assume that the class value has been correctly filled, even if the service is created by a factory
86
  $class = $container->getParameterBag()->resolveValue($def->getClass());
 
 
87
  $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
88
+
89
+ if (!is_subclass_of($class, $interface)) {
90
+ if (!class_exists($class, false)) {
91
+ throw new \InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
92
+ }
93
+
94
  throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
95
  }
96
 
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/Event.php → Event.php} RENAMED
@@ -24,8 +24,6 @@ namespace Symfony\Component\EventDispatcher;
24
  * @author Jonathan Wage <jonwage@gmail.com>
25
  * @author Roman Borschel <roman@code-factory.org>
26
  * @author Bernhard Schussek <bschussek@gmail.com>
27
- *
28
- * @api
29
  */
30
  class Event
31
  {
@@ -35,7 +33,7 @@ class Event
35
  private $propagationStopped = false;
36
 
37
  /**
38
- * @var EventDispatcher Dispatcher that dispatched this event
39
  */
40
  private $dispatcher;
41
 
@@ -49,9 +47,7 @@ class Event
49
  *
50
  * @see Event::stopPropagation()
51
  *
52
- * @return bool Whether propagation was already stopped for this event.
53
- *
54
- * @api
55
  */
56
  public function isPropagationStopped()
57
  {
@@ -64,8 +60,6 @@ class Event
64
  * If multiple event listeners are connected to the same event, no
65
  * further event listener will be triggered once any trigger calls
66
  * stopPropagation().
67
- *
68
- * @api
69
  */
70
  public function stopPropagation()
71
  {
@@ -77,9 +71,7 @@ class Event
77
  *
78
  * @param EventDispatcherInterface $dispatcher
79
  *
80
- * @deprecated Deprecated in 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
81
- *
82
- * @api
83
  */
84
  public function setDispatcher(EventDispatcherInterface $dispatcher)
85
  {
@@ -91,12 +83,12 @@ class Event
91
  *
92
  * @return EventDispatcherInterface
93
  *
94
- * @deprecated Deprecated in 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
95
- *
96
- * @api
97
  */
98
  public function getDispatcher()
99
  {
 
 
100
  return $this->dispatcher;
101
  }
102
 
@@ -105,23 +97,21 @@ class Event
105
  *
106
  * @return string
107
  *
108
- * @deprecated Deprecated in 2.4, to be removed in 3.0. The event name is passed to the listener call.
109
- *
110
- * @api
111
  */
112
  public function getName()
113
  {
 
 
114
  return $this->name;
115
  }
116
 
117
  /**
118
  * Sets the event's name property.
119
  *
120
- * @param string $name The event name.
121
- *
122
- * @deprecated Deprecated in 2.4, to be removed in 3.0. The event name is passed to the listener call.
123
  *
124
- * @api
125
  */
126
  public function setName($name)
127
  {
24
  * @author Jonathan Wage <jonwage@gmail.com>
25
  * @author Roman Borschel <roman@code-factory.org>
26
  * @author Bernhard Schussek <bschussek@gmail.com>
 
 
27
  */
28
  class Event
29
  {
33
  private $propagationStopped = false;
34
 
35
  /**
36
+ * @var EventDispatcherInterface Dispatcher that dispatched this event
37
  */
38
  private $dispatcher;
39
 
47
  *
48
  * @see Event::stopPropagation()
49
  *
50
+ * @return bool Whether propagation was already stopped for this event
 
 
51
  */
52
  public function isPropagationStopped()
53
  {
60
  * If multiple event listeners are connected to the same event, no
61
  * further event listener will be triggered once any trigger calls
62
  * stopPropagation().
 
 
63
  */
64
  public function stopPropagation()
65
  {
71
  *
72
  * @param EventDispatcherInterface $dispatcher
73
  *
74
+ * @deprecated since version 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
 
 
75
  */
76
  public function setDispatcher(EventDispatcherInterface $dispatcher)
77
  {
83
  *
84
  * @return EventDispatcherInterface
85
  *
86
+ * @deprecated since version 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
 
 
87
  */
88
  public function getDispatcher()
89
  {
90
+ @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.4 and will be removed in 3.0. The event dispatcher instance can be received in the listener call instead.', E_USER_DEPRECATED);
91
+
92
  return $this->dispatcher;
93
  }
94
 
97
  *
98
  * @return string
99
  *
100
+ * @deprecated since version 2.4, to be removed in 3.0. The event name is passed to the listener call.
 
 
101
  */
102
  public function getName()
103
  {
104
+ @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.4 and will be removed in 3.0. The event name can be received in the listener call instead.', E_USER_DEPRECATED);
105
+
106
  return $this->name;
107
  }
108
 
109
  /**
110
  * Sets the event's name property.
111
  *
112
+ * @param string $name The event name
 
 
113
  *
114
+ * @deprecated since version 2.4, to be removed in 3.0. The event name is passed to the listener call.
115
  */
116
  public function setName($name)
117
  {
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/EventDispatcher.php → EventDispatcher.php} RENAMED
@@ -24,8 +24,6 @@ namespace Symfony\Component\EventDispatcher;
24
  * @author Fabien Potencier <fabien@symfony.com>
25
  * @author Jordi Boggiano <j.boggiano@seld.be>
26
  * @author Jordan Alliot <jordan.alliot@gmail.com>
27
- *
28
- * @api
29
  */
30
  class EventDispatcher implements EventDispatcherInterface
31
  {
@@ -33,9 +31,7 @@ class EventDispatcher implements EventDispatcherInterface
33
  private $sorted = array();
34
 
35
  /**
36
- * @see EventDispatcherInterface::dispatch()
37
- *
38
- * @api
39
  */
40
  public function dispatch($eventName, Event $event = null)
41
  {
@@ -46,21 +42,23 @@ class EventDispatcher implements EventDispatcherInterface
46
  $event->setDispatcher($this);
47
  $event->setName($eventName);
48
 
49
- if (!isset($this->listeners[$eventName])) {
50
- return $event;
51
  }
52
 
53
- $this->doDispatch($this->getListeners($eventName), $eventName, $event);
54
-
55
  return $event;
56
  }
57
 
58
  /**
59
- * @see EventDispatcherInterface::getListeners()
60
  */
61
  public function getListeners($eventName = null)
62
  {
63
  if (null !== $eventName) {
 
 
 
 
64
  if (!isset($this->sorted[$eventName])) {
65
  $this->sortListeners($eventName);
66
  }
@@ -78,17 +76,38 @@ class EventDispatcher implements EventDispatcherInterface
78
  }
79
 
80
  /**
81
- * @see EventDispatcherInterface::hasListeners()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  */
83
  public function hasListeners($eventName = null)
84
  {
85
- return (bool) count($this->getListeners($eventName));
86
  }
87
 
88
  /**
89
- * @see EventDispatcherInterface::addListener()
90
- *
91
- * @api
92
  */
93
  public function addListener($eventName, $listener, $priority = 0)
94
  {
@@ -97,7 +116,7 @@ class EventDispatcher implements EventDispatcherInterface
97
  }
98
 
99
  /**
100
- * @see EventDispatcherInterface::removeListener()
101
  */
102
  public function removeListener($eventName, $listener)
103
  {
@@ -113,16 +132,14 @@ class EventDispatcher implements EventDispatcherInterface
113
  }
114
 
115
  /**
116
- * @see EventDispatcherInterface::addSubscriber()
117
- *
118
- * @api
119
  */
120
  public function addSubscriber(EventSubscriberInterface $subscriber)
121
  {
122
  foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
123
- if (is_string($params)) {
124
  $this->addListener($eventName, array($subscriber, $params));
125
- } elseif (is_string($params[0])) {
126
  $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
127
  } else {
128
  foreach ($params as $listener) {
@@ -133,17 +150,17 @@ class EventDispatcher implements EventDispatcherInterface
133
  }
134
 
135
  /**
136
- * @see EventDispatcherInterface::removeSubscriber()
137
  */
138
  public function removeSubscriber(EventSubscriberInterface $subscriber)
139
  {
140
  foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
141
- if (is_array($params) && is_array($params[0])) {
142
  foreach ($params as $listener) {
143
  $this->removeListener($eventName, array($subscriber, $listener[0]));
144
  }
145
  } else {
146
- $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0]));
147
  }
148
  }
149
  }
@@ -154,32 +171,28 @@ class EventDispatcher implements EventDispatcherInterface
154
  * This method can be overridden to add functionality that is executed
155
  * for each listener.
156
  *
157
- * @param callable[] $listeners The event listeners.
158
- * @param string $eventName The name of the event to dispatch.
159
- * @param Event $event The event object to pass to the event handlers/listeners.
160
  */
161
  protected function doDispatch($listeners, $eventName, Event $event)
162
  {
163
  foreach ($listeners as $listener) {
164
- call_user_func($listener, $event, $eventName, $this);
165
  if ($event->isPropagationStopped()) {
166
  break;
167
  }
 
168
  }
169
  }
170
 
171
  /**
172
  * Sorts the internal list of listeners for the given event by priority.
173
  *
174
- * @param string $eventName The name of the event.
175
  */
176
  private function sortListeners($eventName)
177
  {
178
- $this->sorted[$eventName] = array();
179
-
180
- if (isset($this->listeners[$eventName])) {
181
- krsort($this->listeners[$eventName]);
182
- $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
183
- }
184
  }
185
  }
24
  * @author Fabien Potencier <fabien@symfony.com>
25
  * @author Jordi Boggiano <j.boggiano@seld.be>
26
  * @author Jordan Alliot <jordan.alliot@gmail.com>
 
 
27
  */
28
  class EventDispatcher implements EventDispatcherInterface
29
  {
31
  private $sorted = array();
32
 
33
  /**
34
+ * {@inheritdoc}
 
 
35
  */
36
  public function dispatch($eventName, Event $event = null)
37
  {
42
  $event->setDispatcher($this);
43
  $event->setName($eventName);
44
 
45
+ if ($listeners = $this->getListeners($eventName)) {
46
+ $this->doDispatch($listeners, $eventName, $event);
47
  }
48
 
 
 
49
  return $event;
50
  }
51
 
52
  /**
53
+ * {@inheritdoc}
54
  */
55
  public function getListeners($eventName = null)
56
  {
57
  if (null !== $eventName) {
58
+ if (!isset($this->listeners[$eventName])) {
59
+ return array();
60
+ }
61
+
62
  if (!isset($this->sorted[$eventName])) {
63
  $this->sortListeners($eventName);
64
  }
76
  }
77
 
78
  /**
79
+ * Gets the listener priority for a specific event.
80
+ *
81
+ * Returns null if the event or the listener does not exist.
82
+ *
83
+ * @param string $eventName The name of the event
84
+ * @param callable $listener The listener
85
+ *
86
+ * @return int|null The event listener priority
87
+ */
88
+ public function getListenerPriority($eventName, $listener)
89
+ {
90
+ if (!isset($this->listeners[$eventName])) {
91
+ return;
92
+ }
93
+
94
+ foreach ($this->listeners[$eventName] as $priority => $listeners) {
95
+ if (false !== \in_array($listener, $listeners, true)) {
96
+ return $priority;
97
+ }
98
+ }
99
+ }
100
+
101
+ /**
102
+ * {@inheritdoc}
103
  */
104
  public function hasListeners($eventName = null)
105
  {
106
+ return (bool) $this->getListeners($eventName);
107
  }
108
 
109
  /**
110
+ * {@inheritdoc}
 
 
111
  */
112
  public function addListener($eventName, $listener, $priority = 0)
113
  {
116
  }
117
 
118
  /**
119
+ * {@inheritdoc}
120
  */
121
  public function removeListener($eventName, $listener)
122
  {
132
  }
133
 
134
  /**
135
+ * {@inheritdoc}
 
 
136
  */
137
  public function addSubscriber(EventSubscriberInterface $subscriber)
138
  {
139
  foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
140
+ if (\is_string($params)) {
141
  $this->addListener($eventName, array($subscriber, $params));
142
+ } elseif (\is_string($params[0])) {
143
  $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
144
  } else {
145
  foreach ($params as $listener) {
150
  }
151
 
152
  /**
153
+ * {@inheritdoc}
154
  */
155
  public function removeSubscriber(EventSubscriberInterface $subscriber)
156
  {
157
  foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
158
+ if (\is_array($params) && \is_array($params[0])) {
159
  foreach ($params as $listener) {
160
  $this->removeListener($eventName, array($subscriber, $listener[0]));
161
  }
162
  } else {
163
+ $this->removeListener($eventName, array($subscriber, \is_string($params) ? $params : $params[0]));
164
  }
165
  }
166
  }
171
  * This method can be overridden to add functionality that is executed
172
  * for each listener.
173
  *
174
+ * @param callable[] $listeners The event listeners
175
+ * @param string $eventName The name of the event to dispatch
176
+ * @param Event $event The event object to pass to the event handlers/listeners
177
  */
178
  protected function doDispatch($listeners, $eventName, Event $event)
179
  {
180
  foreach ($listeners as $listener) {
 
181
  if ($event->isPropagationStopped()) {
182
  break;
183
  }
184
+ \call_user_func($listener, $event, $eventName, $this);
185
  }
186
  }
187
 
188
  /**
189
  * Sorts the internal list of listeners for the given event by priority.
190
  *
191
+ * @param string $eventName The name of the event
192
  */
193
  private function sortListeners($eventName)
194
  {
195
+ krsort($this->listeners[$eventName]);
196
+ $this->sorted[$eventName] = \call_user_func_array('array_merge', $this->listeners[$eventName]);
 
 
 
 
197
  }
198
  }
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/EventDispatcherInterface.php → EventDispatcherInterface.php} RENAMED
@@ -17,8 +17,6 @@ namespace Symfony\Component\EventDispatcher;
17
  * manager.
18
  *
19
  * @author Bernhard Schussek <bschussek@gmail.com>
20
- *
21
- * @api
22
  */
23
  interface EventDispatcherInterface
24
  {
@@ -28,12 +26,10 @@ interface EventDispatcherInterface
28
  * @param string $eventName The name of the event to dispatch. The name of
29
  * the event is the name of the method that is
30
  * invoked on listeners.
31
- * @param Event $event The event to pass to the event handlers/listeners.
32
- * If not supplied, an empty Event instance is created.
33
  *
34
  * @return Event
35
- *
36
- * @api
37
  */
38
  public function dispatch($eventName, Event $event = null);
39
 
@@ -44,8 +40,6 @@ interface EventDispatcherInterface
44
  * @param callable $listener The listener
45
  * @param int $priority The higher this value, the earlier an event
46
  * listener will be triggered in the chain (defaults to 0)
47
- *
48
- * @api
49
  */
50
  public function addListener($eventName, $listener, $priority = 0);
51
 
@@ -54,10 +48,6 @@ interface EventDispatcherInterface
54
  *
55
  * The subscriber is asked for all the events he is
56
  * interested in and added as a listener for these events.
57
- *
58
- * @param EventSubscriberInterface $subscriber The subscriber.
59
- *
60
- * @api
61
  */
62
  public function addSubscriber(EventSubscriberInterface $subscriber);
63
 
@@ -69,11 +59,6 @@ interface EventDispatcherInterface
69
  */
70
  public function removeListener($eventName, $listener);
71
 
72
- /**
73
- * Removes an event subscriber.
74
- *
75
- * @param EventSubscriberInterface $subscriber The subscriber
76
- */
77
  public function removeSubscriber(EventSubscriberInterface $subscriber);
78
 
79
  /**
17
  * manager.
18
  *
19
  * @author Bernhard Schussek <bschussek@gmail.com>
 
 
20
  */
21
  interface EventDispatcherInterface
22
  {
26
  * @param string $eventName The name of the event to dispatch. The name of
27
  * the event is the name of the method that is
28
  * invoked on listeners.
29
+ * @param Event $event The event to pass to the event handlers/listeners
30
+ * If not supplied, an empty Event instance is created
31
  *
32
  * @return Event
 
 
33
  */
34
  public function dispatch($eventName, Event $event = null);
35
 
40
  * @param callable $listener The listener
41
  * @param int $priority The higher this value, the earlier an event
42
  * listener will be triggered in the chain (defaults to 0)
 
 
43
  */
44
  public function addListener($eventName, $listener, $priority = 0);
45
 
48
  *
49
  * The subscriber is asked for all the events he is
50
  * interested in and added as a listener for these events.
 
 
 
 
51
  */
52
  public function addSubscriber(EventSubscriberInterface $subscriber);
53
 
59
  */
60
  public function removeListener($eventName, $listener);
61
 
 
 
 
 
 
62
  public function removeSubscriber(EventSubscriberInterface $subscriber);
63
 
64
  /**
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/EventSubscriberInterface.php → EventSubscriberInterface.php} RENAMED
@@ -21,8 +21,6 @@ namespace Symfony\Component\EventDispatcher;
21
  * @author Jonathan Wage <jonwage@gmail.com>
22
  * @author Roman Borschel <roman@code-factory.org>
23
  * @author Bernhard Schussek <bschussek@gmail.com>
24
- *
25
- * @api
26
  */
27
  interface EventSubscriberInterface
28
  {
@@ -40,11 +38,9 @@ interface EventSubscriberInterface
40
  *
41
  * * array('eventName' => 'methodName')
42
  * * array('eventName' => array('methodName', $priority))
43
- * * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
44
  *
45
  * @return array The event names to listen to
46
- *
47
- * @api
48
  */
49
  public static function getSubscribedEvents();
50
  }
21
  * @author Jonathan Wage <jonwage@gmail.com>
22
  * @author Roman Borschel <roman@code-factory.org>
23
  * @author Bernhard Schussek <bschussek@gmail.com>
 
 
24
  */
25
  interface EventSubscriberInterface
26
  {
38
  *
39
  * * array('eventName' => 'methodName')
40
  * * array('eventName' => array('methodName', $priority))
41
+ * * array('eventName' => array(array('methodName1', $priority), array('methodName2')))
42
  *
43
  * @return array The event names to listen to
 
 
44
  */
45
  public static function getSubscribedEvents();
46
  }
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/GenericEvent.php → GenericEvent.php} RENAMED
@@ -20,25 +20,14 @@ namespace Symfony\Component\EventDispatcher;
20
  */
21
  class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
22
  {
23
- /**
24
- * Event subject.
25
- *
26
- * @var mixed usually object or callable
27
- */
28
  protected $subject;
29
-
30
- /**
31
- * Array of arguments.
32
- *
33
- * @var array
34
- */
35
  protected $arguments;
36
 
37
  /**
38
  * Encapsulate an event with $subject and $args.
39
  *
40
- * @param mixed $subject The subject of the event, usually an object.
41
- * @param array $arguments Arguments to store in the event.
42
  */
43
  public function __construct($subject = null, array $arguments = array())
44
  {
@@ -49,7 +38,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
49
  /**
50
  * Getter for subject property.
51
  *
52
- * @return mixed $subject The observer subject.
53
  */
54
  public function getSubject()
55
  {
@@ -59,11 +48,11 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
59
  /**
60
  * Get argument by key.
61
  *
62
- * @param string $key Key.
63
  *
64
- * @throws \InvalidArgumentException If key is not found.
65
  *
66
- * @return mixed Contents of array key.
67
  */
68
  public function getArgument($key)
69
  {
@@ -71,16 +60,16 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
71
  return $this->arguments[$key];
72
  }
73
 
74
- throw new \InvalidArgumentException(sprintf('%s not found in %s', $key, $this->getName()));
75
  }
76
 
77
  /**
78
  * Add argument to event.
79
  *
80
- * @param string $key Argument name.
81
- * @param mixed $value Value.
82
  *
83
- * @return GenericEvent
84
  */
85
  public function setArgument($key, $value)
86
  {
@@ -102,9 +91,9 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
102
  /**
103
  * Set args property.
104
  *
105
- * @param array $args Arguments.
106
  *
107
- * @return GenericEvent
108
  */
109
  public function setArguments(array $args = array())
110
  {
@@ -116,7 +105,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
116
  /**
117
  * Has argument.
118
  *
119
- * @param string $key Key of arguments array.
120
  *
121
  * @return bool
122
  */
@@ -128,11 +117,11 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
128
  /**
129
  * ArrayAccess for argument getter.
130
  *
131
- * @param string $key Array key.
132
- *
133
- * @throws \InvalidArgumentException If key does not exist in $this->args.
134
  *
135
  * @return mixed
 
 
136
  */
137
  public function offsetGet($key)
138
  {
@@ -142,8 +131,8 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
142
  /**
143
  * ArrayAccess for argument setter.
144
  *
145
- * @param string $key Array key to set.
146
- * @param mixed $value Value.
147
  */
148
  public function offsetSet($key, $value)
149
  {
@@ -153,7 +142,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
153
  /**
154
  * ArrayAccess for unset argument.
155
  *
156
- * @param string $key Array key.
157
  */
158
  public function offsetUnset($key)
159
  {
@@ -165,7 +154,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
165
  /**
166
  * ArrayAccess has argument.
167
  *
168
- * @param string $key Array key.
169
  *
170
  * @return bool
171
  */
20
  */
21
  class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
22
  {
 
 
 
 
 
23
  protected $subject;
 
 
 
 
 
 
24
  protected $arguments;
25
 
26
  /**
27
  * Encapsulate an event with $subject and $args.
28
  *
29
+ * @param mixed $subject The subject of the event, usually an object or a callable
30
+ * @param array $arguments Arguments to store in the event
31
  */
32
  public function __construct($subject = null, array $arguments = array())
33
  {
38
  /**
39
  * Getter for subject property.
40
  *
41
+ * @return mixed The observer subject
42
  */
43
  public function getSubject()
44
  {
48
  /**
49
  * Get argument by key.
50
  *
51
+ * @param string $key Key
52
  *
53
+ * @return mixed Contents of array key
54
  *
55
+ * @throws \InvalidArgumentException if key is not found
56
  */
57
  public function getArgument($key)
58
  {
60
  return $this->arguments[$key];
61
  }
62
 
63
+ throw new \InvalidArgumentException(sprintf('Argument "%s" not found.', $key));
64
  }
65
 
66
  /**
67
  * Add argument to event.
68
  *
69
+ * @param string $key Argument name
70
+ * @param mixed $value Value
71
  *
72
+ * @return $this
73
  */
74
  public function setArgument($key, $value)
75
  {
91
  /**
92
  * Set args property.
93
  *
94
+ * @param array $args Arguments
95
  *
96
+ * @return $this
97
  */
98
  public function setArguments(array $args = array())
99
  {
105
  /**
106
  * Has argument.
107
  *
108
+ * @param string $key Key of arguments array
109
  *
110
  * @return bool
111
  */
117
  /**
118
  * ArrayAccess for argument getter.
119
  *
120
+ * @param string $key Array key
 
 
121
  *
122
  * @return mixed
123
+ *
124
+ * @throws \InvalidArgumentException if key does not exist in $this->args
125
  */
126
  public function offsetGet($key)
127
  {
131
  /**
132
  * ArrayAccess for argument setter.
133
  *
134
+ * @param string $key Array key to set
135
+ * @param mixed $value Value
136
  */
137
  public function offsetSet($key, $value)
138
  {
142
  /**
143
  * ArrayAccess for unset argument.
144
  *
145
+ * @param string $key Array key
146
  */
147
  public function offsetUnset($key)
148
  {
154
  /**
155
  * ArrayAccess has argument.
156
  *
157
+ * @param string $key Array key
158
  *
159
  * @return bool
160
  */
lib/amazon/symfony/event-dispatcher/{Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php → ImmutableEventDispatcher.php} RENAMED
@@ -18,18 +18,8 @@ namespace Symfony\Component\EventDispatcher;
18
  */
19
  class ImmutableEventDispatcher implements EventDispatcherInterface
20
  {
21
- /**
22
- * The proxied dispatcher.
23
- *
24
- * @var EventDispatcherInterface
25
- */
26
  private $dispatcher;
27
 
28
- /**
29
- * Creates an unmodifiable proxy for an event dispatcher.
30
- *
31
- * @param EventDispatcherInterface $dispatcher The proxied event dispatcher.
32
- */
33
  public function __construct(EventDispatcherInterface $dispatcher)
34
  {
35
  $this->dispatcher = $dispatcher;
@@ -83,6 +73,14 @@ class ImmutableEventDispatcher implements EventDispatcherInterface
83
  return $this->dispatcher->getListeners($eventName);
84
  }
85
 
 
 
 
 
 
 
 
 
86
  /**
87
  * {@inheritdoc}
88
  */
18
  */
19
  class ImmutableEventDispatcher implements EventDispatcherInterface
20
  {
 
 
 
 
 
21
  private $dispatcher;
22
 
 
 
 
 
 
23
  public function __construct(EventDispatcherInterface $dispatcher)
24
  {
25
  $this->dispatcher = $dispatcher;
73
  return $this->dispatcher->getListeners($eventName);
74
  }
75
 
76
+ /**
77
+ * {@inheritdoc}
78
+ */
79
+ public function getListenerPriority($eventName, $listener)
80
+ {
81
+ return $this->dispatcher->getListenerPriority($eventName, $listener);
82
+ }
83
+
84
  /**
85
  * {@inheritdoc}
86
  */
lib/amazon/symfony/event-dispatcher/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2004-2018 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
lib/amazon/symfony/event-dispatcher/README.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ EventDispatcher Component
2
+ =========================
3
+
4
+ The EventDispatcher component provides tools that allow your application
5
+ components to communicate with each other by dispatching events and listening to
6
+ them.
7
+
8
+ Resources
9
+ ---------
10
+
11
+ * [Documentation](https://symfony.com/doc/current/components/event_dispatcher/index.html)
12
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
13
+ * [Report issues](https://github.com/symfony/symfony/issues) and
14
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
15
+ in the [main Symfony repository](https://github.com/symfony/symfony)
lib/amazon/symfony/event-dispatcher/composer.json ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "symfony/event-dispatcher",
3
+ "type": "library",
4
+ "description": "Symfony EventDispatcher Component",
5
+ "keywords": [],
6
+ "homepage": "https://symfony.com",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Fabien Potencier",
11
+ "email": "fabien@symfony.com"
12
+ },
13
+ {
14
+ "name": "Symfony Community",
15
+ "homepage": "https://symfony.com/contributors"
16
+ }
17
+ ],
18
+ "require": {
19
+ "php": ">=5.3.9"
20
+ },
21
+ "require-dev": {
22
+ "symfony/dependency-injection": "~2.6|~3.0.0",
23
+ "symfony/expression-language": "~2.6|~3.0.0",
24
+ "symfony/config": "^2.0.5|~3.0.0",
25
+ "symfony/stopwatch": "~2.3|~3.0.0",
26
+ "psr/log": "~1.0"
27
+ },
28
+ "suggest": {
29
+ "symfony/dependency-injection": "",
30
+ "symfony/http-kernel": ""
31
+ },
32
+ "autoload": {
33
+ "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" },
34
+ "exclude-from-classmap": [
35
+ "/Tests/"
36
+ ]
37
+ },
38
+ "minimum-stability": "dev",
39
+ "extra": {
40
+ "branch-alias": {
41
+ "dev-master": "2.8-dev"
42
+ }
43
+ }
44
+ }
lib/amazon/symfony/event-dispatcher/phpunit.xml.dist ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
5
+ backupGlobals="false"
6
+ colors="true"
7
+ bootstrap="vendor/autoload.php"
8
+ failOnRisky="true"
9
+ failOnWarning="true"
10
+ >
11
+ <php>
12
+ <ini name="error_reporting" value="-1" />
13
+ </php>
14
+
15
+ <testsuites>
16
+ <testsuite name="Symfony EventDispatcher Component Test Suite">
17
+ <directory>./Tests/</directory>
18
+ </testsuite>
19
+ </testsuites>
20
+
21
+ <filter>
22
+ <whitelist>
23
+ <directory>./</directory>
24
+ <exclude>
25
+ <directory>./Resources</directory>
26
+ <directory>./Tests</directory>
27
+ <directory>./vendor</directory>
28
+ </exclude>
29
+ </whitelist>
30
+ </filter>
31
+ </phpunit>
lib/dropbox.php CHANGED
@@ -155,7 +155,7 @@ class IWP_Dropbox {
155
  return $this->request($url, array('list' => ($listContents)? 'true' : 'false', 'file_limit' => $fileLimit));
156
  }
157
 
158
- public function search($path = '', $query , $fileLimit = 1000){
159
  if (strlen($query)>=3)
160
  throw new IWP_DropboxException("Error: Query \"$query\" must three characters long.");
161
  $url = self::API_URL.self::API_VERSION_URL.'search/'.$this->root.'/'.trim($path,'/');
155
  return $this->request($url, array('list' => ($listContents)? 'true' : 'false', 'file_limit' => $fileLimit));
156
  }
157
 
158
+ public function search($path = '', $query='' , $fileLimit = 1000){
159
  if (strlen($query)>=3)
160
  throw new IWP_DropboxException("Error: Query \"$query\" must three characters long.");
161
  $url = self::API_URL.self::API_VERSION_URL.'search/'.$this->root.'/'.trim($path,'/');
lib/ftp.class.php CHANGED
@@ -74,7 +74,7 @@ class IWP_MMB_ftp_wrapper {
74
  return false;
75
  }
76
 
77
- public function put($local_file_path, $remote_file_path, $mode = FTP_BINARY, $resume = false, $iwp_backup_core = false, $ftp_remote_path) {
78
 
79
  $file_size = filesize($local_file_path);
80
 
74
  return false;
75
  }
76
 
77
+ public function put($local_file_path, $remote_file_path, $mode = FTP_BINARY, $resume = false, $iwp_backup_core = false, $ftp_remote_path = false) {
78
 
79
  $file_size = filesize($local_file_path);
80
 
lib/phpseclib/phpseclib/BACKERS.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ # Backers
2
+
3
+ phpseclib ongoing development is made possible by [Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) and by contributions by users like you. Thank you.
4
+
5
+ ## Backers
6
+
7
+ - Zane Hooper
8
+ - [Setasign](https://www.setasign.com/)
lib/phpseclib/phpseclib/LICENSE CHANGED
@@ -1,5 +1,4 @@
1
- Copyright 2007-2016 TerraFrost and other contributors
2
- http://phpseclib.sourceforge.net/
3
 
4
  Permission is hereby granted, free of charge, to any person obtaining
5
  a copy of this software and associated documentation files (the
@@ -18,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2011-2019 TerraFrost and other contributors
 
2
 
3
  Permission is hereby granted, free of charge, to any person obtaining
4
  a copy of this software and associated documentation files (the
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
lib/phpseclib/phpseclib/README.md CHANGED
@@ -2,12 +2,19 @@
2
 
3
  [![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=1.0)](https://travis-ci.org/phpseclib/phpseclib)
4
 
 
 
 
 
 
 
 
 
5
  MIT-licensed pure-PHP implementations of an arbitrary-precision integer
6
  arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
7
  AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
8
 
9
  * [Browse Git](https://github.com/phpseclib/phpseclib)
10
- * [Code Coverage Report](https://coverage.phpseclib.org/1.0/latest/)
11
 
12
  ## Documentation
13
 
@@ -24,19 +31,24 @@ AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
24
 
25
  ### 2.0
26
 
 
27
  * Modernized version of 1.0
28
  * Minimum PHP version: 5.3.3
29
  * PSR-4 autoloading with namespace rooted at `\phpseclib`
30
- * Install via Composer: `composer require phpseclib/phpseclib ~2.0`
31
 
32
  ### 1.0
33
 
34
  * Long term support (LTS) release
35
  * PHP4 compatible
36
  * Composer compatible (PSR-0 autoloading)
37
- * Install using Composer: `composer require phpseclib/phpseclib ~1.0`
38
  * Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm)
39
- * [Download 1.0.7 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.7.zip/download)
 
 
 
 
40
 
41
  ## Support
42
 
2
 
3
  [![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=1.0)](https://travis-ci.org/phpseclib/phpseclib)
4
 
5
+ ## Supporting phpseclib
6
+
7
+ - [Become a backer or sponsor on Patreon](https://www.patreon.com/phpseclib)
8
+ - [One-time donation via PayPal or crypto-currencies](http://sourceforge.net/donate/index.php?group_id=198487)
9
+ - [Subscribe to Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme)
10
+
11
+ ## Introduction
12
+
13
  MIT-licensed pure-PHP implementations of an arbitrary-precision integer
14
  arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
15
  AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
16
 
17
  * [Browse Git](https://github.com/phpseclib/phpseclib)
 
18
 
19
  ## Documentation
20
 
31
 
32
  ### 2.0
33
 
34
+ * Long term support (LTS) release
35
  * Modernized version of 1.0
36
  * Minimum PHP version: 5.3.3
37
  * PSR-4 autoloading with namespace rooted at `\phpseclib`
38
+ * Install via Composer: `composer require phpseclib/phpseclib:~2.0`
39
 
40
  ### 1.0
41
 
42
  * Long term support (LTS) release
43
  * PHP4 compatible
44
  * Composer compatible (PSR-0 autoloading)
45
+ * Install using Composer: `composer require phpseclib/phpseclib:~1.0`
46
  * Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm)
47
+ * [Download 1.0.19 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.19.zip/download)
48
+
49
+ ## Security contact information
50
+
51
+ To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
52
 
53
  ## Support
54
 
lib/phpseclib/phpseclib/appveyor.yml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ build: false
2
+ shallow_clone: false
3
+ platform:
4
+ - x86
5
+ - x64
6
+ clone_folder: C:\projects\phpseclib
7
+
8
+ install:
9
+ - cinst -y OpenSSL.Light
10
+ - SET PATH=C:\Program Files\OpenSSL;%PATH%
11
+ - sc config wuauserv start= auto
12
+ - net start wuauserv
13
+ - cinst -y php --version 5.6.30
14
+ - cd c:\tools\php56
15
+ - copy php.ini-production php.ini
16
+ - echo date.timezone="UTC" >> php.ini
17
+ - echo extension_dir=ext >> php.ini
18
+ - echo extension=php_openssl.dll >> php.ini
19
+ - echo extension=php_gmp.dll >> php.ini
20
+ - cd C:\projects\phpseclib
21
+ - SET PATH=C:\tools\php56;%PATH%
22
+ - php.exe -r "readfile('http://getcomposer.org/installer');" | php.exe
23
+ - php.exe composer.phar install --prefer-source --no-interaction
24
+
25
+ test_script:
26
+ - cd C:\projects\phpseclib
27
+ - vendor\bin\phpunit.bat tests/Windows32Test.php
lib/phpseclib/phpseclib/composer.json CHANGED
@@ -55,7 +55,7 @@
55
  },
56
  "require-dev": {
57
  "phing/phing": "~2.7",
58
- "phpunit/phpunit": "~4.0",
59
  "sami/sami": "~2.0",
60
  "squizlabs/php_codesniffer": "~2.0"
61
  },
55
  },
56
  "require-dev": {
57
  "phing/phing": "~2.7",
58
+ "phpunit/phpunit": "^4.8.35|^5.7|^6.0",
59
  "sami/sami": "~2.0",
60
  "squizlabs/php_codesniffer": "~2.0"
61
  },
lib/phpseclib/phpseclib/composer.lock DELETED
@@ -1,1669 +0,0 @@
1
- {
2
- "_readme": [
3
- "This file locks the dependencies of your project to a known state",
4
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
- "This file is @generated automatically"
6
- ],
7
- "hash": "24648c5326ee237cd79bb0d311b16cb8",
8
- "content-hash": "cec0167a357df0f3da215133e2424a6c",
9
- "packages": [],
10
- "packages-dev": [
11
- {
12
- "name": "doctrine/instantiator",
13
- "version": "1.0.5",
14
- "source": {
15
- "type": "git",
16
- "url": "https://github.com/doctrine/instantiator.git",
17
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
18
- },
19
- "dist": {
20
- "type": "zip",
21
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
22
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
23
- "shasum": ""
24
- },
25
- "require": {
26
- "php": ">=5.3,<8.0-DEV"
27
- },
28
- "require-dev": {
29
- "athletic/athletic": "~0.1.8",
30
- "ext-pdo": "*",
31
- "ext-phar": "*",
32
- "phpunit/phpunit": "~4.0",
33
- "squizlabs/php_codesniffer": "~2.0"
34
- },
35
- "type": "library",
36
- "extra": {
37
- "branch-alias": {
38
- "dev-master": "1.0.x-dev"
39
- }
40
- },
41
- "autoload": {
42
- "psr-4": {
43
- "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
44
- }
45
- },
46
- "notification-url": "https://packagist.org/downloads/",
47
- "license": [
48
- "MIT"
49
- ],
50
- "authors": [
51
- {
52
- "name": "Marco Pivetta",
53
- "email": "ocramius@gmail.com",
54
- "homepage": "http://ocramius.github.com/"
55
- }
56
- ],
57
- "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
58
- "homepage": "https://github.com/doctrine/instantiator",
59
- "keywords": [
60
- "constructor",
61
- "instantiate"
62
- ],
63
- "time": "2015-06-14 21:17:01"
64
- },
65
- {
66
- "name": "michelf/php-markdown",
67
- "version": "1.6.0",
68
- "source": {
69
- "type": "git",
70
- "url": "https://github.com/michelf/php-markdown.git",
71
- "reference": "156e56ee036505ec637d761ee62dc425d807183c"
72
- },
73
- "dist": {
74
- "type": "zip",
75
- "url": "https://api.github.com/repos/michelf/php-markdown/zipball/156e56ee036505ec637d761ee62dc425d807183c",
76
- "reference": "156e56ee036505ec637d761ee62dc425d807183c",
77
- "shasum": ""
78
- },
79
- "require": {
80
- "php": ">=5.3.0"
81
- },
82
- "type": "library",
83
- "extra": {
84
- "branch-alias": {
85
- "dev-lib": "1.4.x-dev"
86
- }
87
- },
88
- "autoload": {
89
- "psr-0": {
90
- "Michelf": ""
91
- }
92
- },
93
- "notification-url": "https://packagist.org/downloads/",
94
- "license": [
95
- "BSD-3-Clause"
96
- ],
97
- "authors": [
98
- {
99
- "name": "Michel Fortin",
100
- "email": "michel.fortin@michelf.ca",
101
- "homepage": "https://michelf.ca/",
102
- "role": "Developer"
103
- },
104
- {
105
- "name": "John Gruber",
106
- "homepage": "https://daringfireball.net/"
107
- }
108
- ],
109
- "description": "PHP Markdown",
110
- "homepage": "https://michelf.ca/projects/php-markdown/",
111
- "keywords": [
112
- "markdown"
113
- ],
114
- "time": "2015-12-24 01:37:31"
115
- },
116
- {
117
- "name": "nikic/php-parser",
118
- "version": "v0.9.5",
119
- "source": {
120
- "type": "git",
121
- "url": "https://github.com/nikic/PHP-Parser.git",
122
- "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb"
123
- },
124
- "dist": {
125
- "type": "zip",
126
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ef70767475434bdb3615b43c327e2cae17ef12eb",
127
- "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb",
128
- "shasum": ""
129
- },
130
- "require": {
131
- "ext-tokenizer": "*",
132
- "php": ">=5.2"
133
- },
134
- "type": "library",
135
- "extra": {
136
- "branch-alias": {
137
- "dev-master": "0.9-dev"
138
- }
139
- },
140
- "autoload": {
141
- "psr-0": {
142
- "PHPParser": "lib/"
143
- }
144
- },
145
- "notification-url": "https://packagist.org/downloads/",
146
- "license": [
147
- "BSD-3-Clause"
148
- ],
149
- "authors": [
150
- {
151
- "name": "Nikita Popov"
152
- }
153
- ],
154
- "description": "A PHP parser written in PHP",
155
- "keywords": [
156
- "parser",
157
- "php"
158
- ],
159
- "time": "2014-07-23 18:24:17"
160
- },
161
- {
162
- "name": "phing/phing",
163
- "version": "2.14.0",
164
- "source": {
165
- "type": "git",
166
- "url": "https://github.com/phingofficial/phing.git",
167
- "reference": "7dd73c83c377623def54b58121f46b4dcb35dd61"
168
- },
169
- "dist": {
170
- "type": "zip",
171
- "url": "https://api.github.com/repos/phingofficial/phing/zipball/7dd73c83c377623def54b58121f46b4dcb35dd61",
172
- "reference": "7dd73c83c377623def54b58121f46b4dcb35dd61",
173
- "shasum": ""
174
- },
175
- "require": {
176
- "php": ">=5.2.0"
177
- },
178
- "require-dev": {
179
- "ext-pdo_sqlite": "*",
180
- "lastcraft/simpletest": "@dev",
181
- "mikey179/vfsstream": "^1.6",
182
- "pdepend/pdepend": "2.x",
183
- "pear/archive_tar": "1.4.x",
184
- "pear/http_request2": "dev-trunk",
185
- "pear/net_growl": "dev-trunk",
186
- "pear/pear-core-minimal": "1.10.1",
187
- "pear/versioncontrol_git": "@dev",
188
- "pear/versioncontrol_svn": "~0.5",
189
- "phpdocumentor/phpdocumentor": "2.x",
190
- "phploc/phploc": "~2.0.6",
191
- "phpmd/phpmd": "~2.2",
192
- "phpunit/phpunit": ">=3.7",
193
- "sebastian/git": "~1.0",
194
- "sebastian/phpcpd": "2.x",
195
- "squizlabs/php_codesniffer": "~2.2",
196
- "symfony/yaml": "~2.7"
197
- },
198
- "suggest": {
199
- "pdepend/pdepend": "PHP version of JDepend",
200
- "pear/archive_tar": "Tar file management class",
201
- "pear/versioncontrol_git": "A library that provides OO interface to handle Git repository",
202
- "pear/versioncontrol_svn": "A simple OO-style interface for Subversion, the free/open-source version control system",
203
- "phpdocumentor/phpdocumentor": "Documentation Generator for PHP",
204
- "phploc/phploc": "A tool for quickly measuring the size of a PHP project",
205
- "phpmd/phpmd": "PHP version of PMD tool",
206
- "phpunit/php-code-coverage": "Library that provides collection, processing, and rendering functionality for PHP code coverage information",
207
- "phpunit/phpunit": "The PHP Unit Testing Framework",
208
- "sebastian/phpcpd": "Copy/Paste Detector (CPD) for PHP code",
209
- "tedivm/jshrink": "Javascript Minifier built in PHP"
210
- },
211
- "bin": [
212
- "bin/phing"
213
- ],
214
- "type": "library",
215
- "extra": {
216
- "branch-alias": {
217
- "dev-master": "2.14.x-dev"
218
- }
219
- },
220
- "autoload": {
221
- "classmap": [
222
- "classes/phing/"
223
- ]
224
- },
225
- "notification-url": "https://packagist.org/downloads/",
226
- "include-path": [
227
- "classes"
228
- ],
229
- "license": [
230
- "LGPL-3.0"
231
- ],
232
- "authors": [
233
- {
234
- "name": "Michiel Rook",
235
- "email": "mrook@php.net"
236
- },
237
- {
238
- "name": "Phing Community",
239
- "homepage": "https://www.phing.info/trac/wiki/Development/Contributors"
240
- }
241
- ],
242
- "description": "PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.",
243
- "homepage": "https://www.phing.info/",
244
- "keywords": [
245
- "build",
246
- "phing",
247
- "task",
248
- "tool"
249
- ],
250
- "time": "2016-03-10 21:39:23"
251
- },
252
- {
253
- "name": "phpdocumentor/reflection-docblock",
254
- "version": "2.0.4",
255
- "source": {
256
- "type": "git",
257
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
258
- "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
259
- },
260
- "dist": {
261
- "type": "zip",
262
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
263
- "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
264
- "shasum": ""
265
- },
266
- "require": {
267
- "php": ">=5.3.3"
268
- },
269
- "require-dev": {
270
- "phpunit/phpunit": "~4.0"
271
- },
272
- "suggest": {
273
- "dflydev/markdown": "~1.0",
274
- "erusev/parsedown": "~1.0"
275
- },
276
- "type": "library",
277
- "extra": {
278
- "branch-alias": {
279
- "dev-master": "2.0.x-dev"
280
- }
281
- },
282
- "autoload": {
283
- "psr-0": {
284
- "phpDocumentor": [
285
- "src/"
286
- ]
287
- }
288
- },
289
- "notification-url": "https://packagist.org/downloads/",
290
- "license": [
291
- "MIT"
292
- ],
293
- "authors": [
294
- {
295
- "name": "Mike van Riel",
296
- "email": "mike.vanriel@naenius.com"
297
- }
298
- ],
299
- "time": "2015-02-03 12:10:50"
300
- },
301
- {
302
- "name": "phpspec/prophecy",
303
- "version": "v1.6.0",
304
- "source": {
305
- "type": "git",
306
- "url": "https://github.com/phpspec/prophecy.git",
307
- "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
308
- },
309
- "dist": {
310
- "type": "zip",
311
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
312
- "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
313
- "shasum": ""
314
- },
315
- "require": {
316
- "doctrine/instantiator": "^1.0.2",
317
- "php": "^5.3|^7.0",
318
- "phpdocumentor/reflection-docblock": "~2.0",
319
- "sebastian/comparator": "~1.1",
320
- "sebastian/recursion-context": "~1.0"
321
- },
322
- "require-dev": {
323
- "phpspec/phpspec": "~2.0"
324
- },
325
- "type": "library",
326
- "extra": {
327
- "branch-alias": {
328
- "dev-master": "1.5.x-dev"
329
- }
330
- },
331
- "autoload": {
332
- "psr-0": {
333
- "Prophecy\\": "src/"
334
- }
335
- },
336
- "notification-url": "https://packagist.org/downloads/",
337
- "license": [
338
- "MIT"
339
- ],
340
- "authors": [
341
- {
342
- "name": "Konstantin Kudryashov",
343
- "email": "ever.zet@gmail.com",
344
- "homepage": "http://everzet.com"
345
- },
346
- {
347
- "name": "Marcello Duarte",
348
- "email": "marcello.duarte@gmail.com"
349
- }
350
- ],
351
- "description": "Highly opinionated mocking framework for PHP 5.3+",
352
- "homepage": "https://github.com/phpspec/prophecy",
353
- "keywords": [
354
- "Double",
355
- "Dummy",
356
- "fake",
357
- "mock",
358
- "spy",
359
- "stub"
360
- ],
361
- "time": "2016-02-15 07:46:21"
362
- },
363
- {
364
- "name": "phpunit/php-code-coverage",
365
- "version": "2.2.4",
366
- "source": {
367
- "type": "git",
368
- "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
369
- "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
370
- },
371
- "dist": {
372
- "type": "zip",
373
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
374
- "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
375
- "shasum": ""
376
- },
377
- "require": {
378
- "php": ">=5.3.3",
379
- "phpunit/php-file-iterator": "~1.3",
380
- "phpunit/php-text-template": "~1.2",
381
- "phpunit/php-token-stream": "~1.3",
382
- "sebastian/environment": "^1.3.2",
383
- "sebastian/version": "~1.0"
384
- },
385
- "require-dev": {
386
- "ext-xdebug": ">=2.1.4",
387
- "phpunit/phpunit": "~4"
388
- },
389
- "suggest": {
390
- "ext-dom": "*",
391
- "ext-xdebug": ">=2.2.1",
392
- "ext-xmlwriter": "*"
393
- },
394
- "type": "library",
395
- "extra": {
396
- "branch-alias": {
397
- "dev-master": "2.2.x-dev"
398
- }
399
- },
400
- "autoload": {
401
- "classmap": [
402
- "src/"
403
- ]
404
- },
405
- "notification-url": "https://packagist.org/downloads/",
406
- "license": [
407
- "BSD-3-Clause"
408
- ],
409
- "authors": [
410
- {
411
- "name": "Sebastian Bergmann",
412
- "email": "sb@sebastian-bergmann.de",
413
- "role": "lead"
414
- }
415
- ],
416
- "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
417
- "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
418
- "keywords": [
419
- "coverage",
420
- "testing",
421
- "xunit"
422
- ],
423
- "time": "2015-10-06 15:47:00"
424
- },
425
- {
426
- "name": "phpunit/php-file-iterator",
427
- "version": "1.4.1",
428
- "source": {
429
- "type": "git",
430
- "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
431
- "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
432
- },
433
- "dist": {
434
- "type": "zip",
435
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
436
- "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
437
- "shasum": ""
438
- },
439
- "require": {
440
- "php": ">=5.3.3"
441
- },
442
- "type": "library",
443
- "extra": {
444
- "branch-alias": {
445
- "dev-master": "1.4.x-dev"
446
- }
447
- },
448
- "autoload": {
449
- "classmap": [
450
- "src/"
451
- ]
452
- },
453
- "notification-url": "https://packagist.org/downloads/",
454
- "license": [
455
- "BSD-3-Clause"
456
- ],
457
- "authors": [
458
- {
459
- "name": "Sebastian Bergmann",
460
- "email": "sb@sebastian-bergmann.de",
461
- "role": "lead"
462
- }
463
- ],
464
- "description": "FilterIterator implementation that filters files based on a list of suffixes.",
465
- "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
466
- "keywords": [
467
- "filesystem",
468
- "iterator"
469
- ],
470
- "time": "2015-06-21 13:08:43"
471
- },
472
- {
473
- "name": "phpunit/php-text-template",
474
- "version": "1.2.1",
475
- "source": {
476
- "type": "git",
477
- "url": "https://github.com/sebastianbergmann/php-text-template.git",
478
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
479
- },
480
- "dist": {
481
- "type": "zip",
482
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
483
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
484
- "shasum": ""
485
- },
486
- "require": {
487
- "php": ">=5.3.3"
488
- },
489
- "type": "library",
490
- "autoload": {
491
- "classmap": [
492
- "src/"
493
- ]
494
- },
495
- "notification-url": "https://packagist.org/downloads/",
496
- "license": [
497
- "BSD-3-Clause"
498
- ],
499
- "authors": [
500
- {
501
- "name": "Sebastian Bergmann",
502
- "email": "sebastian@phpunit.de",
503
- "role": "lead"
504
- }
505
- ],
506
- "description": "Simple template engine.",
507
- "homepage": "https://github.com/sebastianbergmann/php-text-template/",
508
- "keywords": [
509
- "template"
510
- ],
511
- "time": "2015-06-21 13:50:34"
512
- },
513
- {
514
- "name": "phpunit/php-timer",
515
- "version": "1.0.7",
516
- "source": {
517
- "type": "git",
518
- "url": "https://github.com/sebastianbergmann/php-timer.git",
519
- "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
520
- },
521
- "dist": {
522
- "type": "zip",
523
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
524
- "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
525
- "shasum": ""
526
- },
527
- "require": {
528
- "php": ">=5.3.3"
529
- },
530
- "type": "library",
531
- "autoload": {
532
- "classmap": [
533
- "src/"
534
- ]
535
- },
536
- "notification-url": "https://packagist.org/downloads/",
537
- "license": [
538
- "BSD-3-Clause"
539
- ],
540
- "authors": [
541
- {
542
- "name": "Sebastian Bergmann",
543
- "email": "sb@sebastian-bergmann.de",
544
- "role": "lead"
545
- }
546
- ],
547
- "description": "Utility class for timing",
548
- "homepage": "https://github.com/sebastianbergmann/php-timer/",
549
- "keywords": [
550
- "timer"
551
- ],
552
- "time": "2015-06-21 08:01:12"
553
- },
554
- {
555
- "name": "phpunit/php-token-stream",
556
- "version": "1.4.8",
557
- "source": {
558
- "type": "git",
559
- "url": "https://github.com/sebastianbergmann/php-token-stream.git",
560
- "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
561
- },
562
- "dist": {
563
- "type": "zip",
564
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
565
- "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
566
- "shasum": ""
567
- },
568
- "require": {
569
- "ext-tokenizer": "*",
570
- "php": ">=5.3.3"
571
- },
572
- "require-dev": {
573
- "phpunit/phpunit": "~4.2"
574
- },
575
- "type": "library",
576
- "extra": {
577
- "branch-alias": {
578
- "dev-master": "1.4-dev"
579
- }
580
- },
581
- "autoload": {
582
- "classmap": [
583
- "src/"
584
- ]
585
- },
586
- "notification-url": "https://packagist.org/downloads/",
587
- "license": [
588
- "BSD-3-Clause"
589
- ],
590
- "authors": [
591
- {
592
- "name": "Sebastian Bergmann",
593
- "email": "sebastian@phpunit.de"
594
- }
595
- ],
596
- "description": "Wrapper around PHP's tokenizer extension.",
597
- "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
598
- "keywords": [
599
- "tokenizer"
600
- ],
601
- "time": "2015-09-15 10:49:45"
602
- },
603
- {
604
- "name": "phpunit/phpunit",
605
- "version": "4.8.24",
606
- "source": {
607
- "type": "git",
608
- "url": "https://github.com/sebastianbergmann/phpunit.git",
609
- "reference": "a1066c562c52900a142a0e2bbf0582994671385e"
610
- },
611
- "dist": {
612
- "type": "zip",
613
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e",
614
- "reference": "a1066c562c52900a142a0e2bbf0582994671385e",
615
- "shasum": ""
616
- },
617
- "require": {
618
- "ext-dom": "*",
619
- "ext-json": "*",
620
- "ext-pcre": "*",
621
- "ext-reflection": "*",
622
- "ext-spl": "*",
623
- "php": ">=5.3.3",
624
- "phpspec/prophecy": "^1.3.1",
625
- "phpunit/php-code-coverage": "~2.1",
626
- "phpunit/php-file-iterator": "~1.4",
627
- "phpunit/php-text-template": "~1.2",
628
- "phpunit/php-timer": ">=1.0.6",
629
- "phpunit/phpunit-mock-objects": "~2.3",
630
- "sebastian/comparator": "~1.1",
631
- "sebastian/diff": "~1.2",
632
- "sebastian/environment": "~1.3",
633
- "sebastian/exporter": "~1.2",
634
- "sebastian/global-state": "~1.0",
635
- "sebastian/version": "~1.0",
636
- "symfony/yaml": "~2.1|~3.0"
637
- },
638
- "suggest": {
639
- "phpunit/php-invoker": "~1.1"
640
- },
641
- "bin": [
642
- "phpunit"
643
- ],
644
- "type": "library",
645
- "extra": {
646
- "branch-alias": {
647
- "dev-master": "4.8.x-dev"
648
- }
649
- },
650
- "autoload": {
651
- "classmap": [
652
- "src/"
653
- ]
654
- },
655
- "notification-url": "https://packagist.org/downloads/",
656
- "license": [
657
- "BSD-3-Clause"
658
- ],
659
- "authors": [
660
- {
661
- "name": "Sebastian Bergmann",
662
- "email": "sebastian@phpunit.de",
663
- "role": "lead"
664
- }
665
- ],
666
- "description": "The PHP Unit Testing framework.",
667
- "homepage": "https://phpunit.de/",
668
- "keywords": [
669
- "phpunit",
670
- "testing",
671
- "xunit"
672
- ],
673
- "time": "2016-03-14 06:16:08"
674
- },
675
- {
676
- "name": "phpunit/phpunit-mock-objects",
677
- "version": "2.3.8",
678
- "source": {
679
- "type": "git",
680
- "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
681
- "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
682
- },
683
- "dist": {
684
- "type": "zip",
685
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
686
- "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
687
- "shasum": ""
688
- },
689
- "require": {
690
- "doctrine/instantiator": "^1.0.2",
691
- "php": ">=5.3.3",
692
- "phpunit/php-text-template": "~1.2",
693
- "sebastian/exporter": "~1.2"
694
- },
695
- "require-dev": {
696
- "phpunit/phpunit": "~4.4"
697
- },
698
- "suggest": {
699
- "ext-soap": "*"
700
- },
701
- "type": "library",
702
- "extra": {
703
- "branch-alias": {
704
- "dev-master": "2.3.x-dev"
705
- }
706
- },
707
- "autoload": {
708
- "classmap": [
709
- "src/"
710
- ]
711
- },
712
- "notification-url": "https://packagist.org/downloads/",
713
- "license": [
714
- "BSD-3-Clause"
715
- ],
716
- "authors": [
717
- {
718
- "name": "Sebastian Bergmann",
719
- "email": "sb@sebastian-bergmann.de",
720
- "role": "lead"
721
- }
722
- ],
723
- "description": "Mock Object library for PHPUnit",
724
- "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
725
- "keywords": [
726
- "mock",
727
- "xunit"
728
- ],
729
- "time": "2015-10-02 06:51:40"
730
- },
731
- {
732
- "name": "pimple/pimple",
733
- "version": "v2.1.1",
734
- "source": {
735
- "type": "git",
736
- "url": "https://github.com/silexphp/Pimple.git",
737
- "reference": "ea22fb2880faf7b7b0e17c9809c6fe25b071fd76"
738
- },
739
- "dist": {
740
- "type": "zip",
741
- "url": "https://api.github.com/repos/silexphp/Pimple/zipball/ea22fb2880faf7b7b0e17c9809c6fe25b071fd76",
742
- "reference": "ea22fb2880faf7b7b0e17c9809c6fe25b071fd76",
743
- "shasum": ""
744
- },
745
- "require": {
746
- "php": ">=5.3.0"
747
- },
748
- "type": "library",
749
- "extra": {
750
- "branch-alias": {
751
- "dev-master": "2.1.x-dev"
752
- }
753
- },
754
- "autoload": {
755
- "psr-0": {
756
- "Pimple": "src/"
757
- }
758
- },
759
- "notification-url": "https://packagist.org/downloads/",
760
- "license": [
761
- "MIT"
762
- ],
763
- "authors": [
764
- {
765
- "name": "Fabien Potencier",
766
- "email": "fabien@symfony.com"
767
- }
768
- ],
769
- "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
770
- "homepage": "http://pimple.sensiolabs.org",
771
- "keywords": [
772
- "container",
773
- "dependency injection"
774
- ],
775
- "time": "2014-07-24 07:10:08"
776
- },
777
- {
778
- "name": "sami/sami",
779
- "version": "v2.0.0",
780
- "source": {
781
- "type": "git",
782
- "url": "https://github.com/FriendsOfPHP/Sami.git",
783
- "reference": "fa58b324f41aa2aefe21dac4f22d8c98965fc012"
784
- },
785
- "dist": {
786
- "type": "zip",
787
- "url": "https://api.github.com/repos/FriendsOfPHP/Sami/zipball/fa58b324f41aa2aefe21dac4f22d8c98965fc012",
788
- "reference": "fa58b324f41aa2aefe21dac4f22d8c98965fc012",
789
- "shasum": ""
790
- },
791
- "require": {
792
- "michelf/php-markdown": "~1.3",
793
- "nikic/php-parser": "0.9.*",
794
- "php": ">=5.3.0",
795
- "pimple/pimple": "2.*",
796
- "symfony/console": "~2.1",
797
- "symfony/filesystem": "~2.1",
798
- "symfony/finder": "~2.1",
799
- "symfony/process": "~2.1",
800
- "symfony/yaml": "~2.1",
801
- "twig/twig": "1.*"
802
- },
803
- "bin": [
804
- "sami.php"
805
- ],
806
- "type": "application",
807
- "extra": {
808
- "branch-alias": {
809
- "dev-master": "2.0-dev"
810
- }
811
- },
812
- "autoload": {
813
- "psr-0": {
814
- "Sami": "."
815
- }
816
- },
817
- "notification-url": "https://packagist.org/downloads/",
818
- "license": [
819
- "MIT"
820
- ],
821
- "authors": [
822
- {
823
- "name": "Fabien Potencier",
824
- "email": "fabien@symfony.com"
825
- }
826
- ],
827
- "description": "Sami, an API documentation generator",
828
- "homepage": "http://sami.sensiolabs.org",
829
- "keywords": [
830
- "phpdoc"
831
- ],
832
- "time": "2014-06-25 12:05:18"
833
- },
834
- {
835
- "name": "sebastian/comparator",
836
- "version": "1.2.0",
837
- "source": {
838
- "type": "git",
839
- "url": "https://github.com/sebastianbergmann/comparator.git",
840
- "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
841
- },
842
- "dist": {
843
- "type": "zip",
844
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
845
- "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
846
- "shasum": ""
847
- },
848
- "require": {
849
- "php": ">=5.3.3",
850
- "sebastian/diff": "~1.2",
851
- "sebastian/exporter": "~1.2"
852
- },
853
- "require-dev": {
854
- "phpunit/phpunit": "~4.4"
855
- },
856
- "type": "library",
857
- "extra": {
858
- "branch-alias": {
859
- "dev-master": "1.2.x-dev"
860
- }
861
- },
862
- "autoload": {
863
- "classmap": [
864
- "src/"
865
- ]
866
- },
867
- "notification-url": "https://packagist.org/downloads/",
868
- "license": [
869
- "BSD-3-Clause"
870
- ],
871
- "authors": [
872
- {
873
- "name": "Jeff Welch",
874
- "email": "whatthejeff@gmail.com"
875
- },
876
- {
877
- "name": "Volker Dusch",
878
- "email": "github@wallbash.com"
879
- },
880
- {
881
- "name": "Bernhard Schussek",
882
- "email": "bschussek@2bepublished.at"
883
- },
884
- {
885
- "name": "Sebastian Bergmann",
886
- "email": "sebastian@phpunit.de"
887
- }
888
- ],
889
- "description": "Provides the functionality to compare PHP values for equality",
890
- "homepage": "http://www.github.com/sebastianbergmann/comparator",
891
- "keywords": [
892
- "comparator",
893
- "compare",
894
- "equality"
895
- ],
896
- "time": "2015-07-26 15:48:44"
897
- },
898
- {
899
- "name": "sebastian/diff",
900
- "version": "1.4.1",
901
- "source": {
902
- "type": "git",
903
- "url": "https://github.com/sebastianbergmann/diff.git",
904
- "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
905
- },
906
- "dist": {
907
- "type": "zip",
908
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
909
- "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
910
- "shasum": ""
911
- },
912
- "require": {
913
- "php": ">=5.3.3"
914
- },
915
- "require-dev": {
916
- "phpunit/phpunit": "~4.8"
917
- },
918
- "type": "library",
919
- "extra": {
920
- "branch-alias": {
921
- "dev-master": "1.4-dev"
922
- }
923
- },
924
- "autoload": {
925
- "classmap": [
926
- "src/"
927
- ]
928
- },
929
- "notification-url": "https://packagist.org/downloads/",
930
- "license": [
931
- "BSD-3-Clause"
932
- ],
933
- "authors": [
934
- {
935
- "name": "Kore Nordmann",
936
- "email": "mail@kore-nordmann.de"
937
- },
938
- {
939
- "name": "Sebastian Bergmann",
940
- "email": "sebastian@phpunit.de"
941
- }
942
- ],
943
- "description": "Diff implementation",
944
- "homepage": "https://github.com/sebastianbergmann/diff",
945
- "keywords": [
946
- "diff"
947
- ],
948
- "time": "2015-12-08 07:14:41"
949
- },
950
- {
951
- "name": "sebastian/environment",
952
- "version": "1.3.5",
953
- "source": {
954
- "type": "git",
955
- "url": "https://github.com/sebastianbergmann/environment.git",
956
- "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf"
957
- },
958
- "dist": {
959
- "type": "zip",
960
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
961
- "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
962
- "shasum": ""
963
- },
964
- "require": {
965
- "php": ">=5.3.3"
966
- },
967
- "require-dev": {
968
- "phpunit/phpunit": "~4.4"
969
- },
970
- "type": "library",
971
- "extra": {
972
- "branch-alias": {
973
- "dev-master": "1.3.x-dev"
974
- }
975
- },
976
- "autoload": {
977
- "classmap": [
978
- "src/"
979
- ]
980
- },
981
- "notification-url": "https://packagist.org/downloads/",
982
- "license": [
983
- "BSD-3-Clause"
984
- ],
985
- "authors": [
986
- {
987
- "name": "Sebastian Bergmann",
988
- "email": "sebastian@phpunit.de"
989
- }
990
- ],
991
- "description": "Provides functionality to handle HHVM/PHP environments",
992
- "homepage": "http://www.github.com/sebastianbergmann/environment",
993
- "keywords": [
994
- "Xdebug",
995
- "environment",
996
- "hhvm"
997
- ],
998
- "time": "2016-02-26 18:40:46"
999
- },
1000
- {
1001
- "name": "sebastian/exporter",
1002
- "version": "1.2.1",
1003
- "source": {
1004
- "type": "git",
1005
- "url": "https://github.com/sebastianbergmann/exporter.git",
1006
- "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
1007
- },
1008
- "dist": {
1009
- "type": "zip",
1010
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
1011
- "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
1012
- "shasum": ""
1013
- },
1014
- "require": {
1015
- "php": ">=5.3.3",
1016
- "sebastian/recursion-context": "~1.0"
1017
- },
1018
- "require-dev": {
1019
- "phpunit/phpunit": "~4.4"
1020
- },
1021
- "type": "library",
1022
- "extra": {
1023
- "branch-alias": {
1024
- "dev-master": "1.2.x-dev"
1025
- }
1026
- },
1027
- "autoload": {
1028
- "classmap": [
1029
- "src/"
1030
- ]
1031
- },
1032
- "notification-url": "https://packagist.org/downloads/",
1033
- "license": [
1034
- "BSD-3-Clause"
1035
- ],
1036
- "authors": [
1037
- {
1038
- "name": "Jeff Welch",
1039
- "email": "whatthejeff@gmail.com"
1040
- },
1041
- {
1042
- "name": "Volker Dusch",
1043
- "email": "github@wallbash.com"
1044
- },
1045
- {
1046
- "name": "Bernhard Schussek",
1047
- "email": "bschussek@2bepublished.at"
1048
- },
1049
- {
1050
- "name": "Sebastian Bergmann",
1051
- "email": "sebastian@phpunit.de"
1052
- },
1053
- {
1054
- "name": "Adam Harvey",
1055
- "email": "aharvey@php.net"
1056
- }
1057
- ],
1058
- "description": "Provides the functionality to export PHP variables for visualization",
1059
- "homepage": "http://www.github.com/sebastianbergmann/exporter",
1060
- "keywords": [
1061
- "export",
1062
- "exporter"
1063
- ],
1064
- "time": "2015-06-21 07:55:53"
1065
- },
1066
- {
1067
- "name": "sebastian/global-state",
1068
- "version": "1.1.1",
1069
- "source": {
1070
- "type": "git",
1071
- "url": "https://github.com/sebastianbergmann/global-state.git",
1072
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1073
- },
1074
- "dist": {
1075
- "type": "zip",
1076
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1077
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1078
- "shasum": ""
1079
- },
1080
- "require": {
1081
- "php": ">=5.3.3"
1082
- },
1083
- "require-dev": {
1084
- "phpunit/phpunit": "~4.2"
1085
- },
1086
- "suggest": {
1087
- "ext-uopz": "*"
1088
- },
1089
- "type": "library",
1090
- "extra": {
1091
- "branch-alias": {
1092
- "dev-master": "1.0-dev"
1093
- }
1094
- },
1095
- "autoload": {
1096
- "classmap": [
1097
- "src/"
1098
- ]
1099
- },
1100
- "notification-url": "https://packagist.org/downloads/",
1101
- "license": [
1102
- "BSD-3-Clause"
1103
- ],
1104
- "authors": [
1105
- {
1106
- "name": "Sebastian Bergmann",
1107
- "email": "sebastian@phpunit.de"
1108
- }
1109
- ],
1110
- "description": "Snapshotting of global state",
1111
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
1112
- "keywords": [
1113
- "global state"
1114
- ],
1115
- "time": "2015-10-12 03:26:01"
1116
- },
1117
- {
1118
- "name": "sebastian/recursion-context",
1119
- "version": "1.0.2",
1120
- "source": {
1121
- "type": "git",
1122
- "url": "https://github.com/sebastianbergmann/recursion-context.git",
1123
- "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
1124
- },
1125
- "dist": {
1126
- "type": "zip",
1127
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
1128
- "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
1129
- "shasum": ""
1130
- },
1131
- "require": {
1132
- "php": ">=5.3.3"
1133
- },
1134
- "require-dev": {
1135
- "phpunit/phpunit": "~4.4"
1136
- },
1137
- "type": "library",
1138
- "extra": {
1139
- "branch-alias": {
1140
- "dev-master": "1.0.x-dev"
1141
- }
1142
- },
1143
- "autoload": {
1144
- "classmap": [
1145
- "src/"
1146
- ]
1147
- },
1148
- "notification-url": "https://packagist.org/downloads/",
1149
- "license": [
1150
- "BSD-3-Clause"
1151
- ],
1152
- "authors": [
1153
- {
1154
- "name": "Jeff Welch",
1155
- "email": "whatthejeff@gmail.com"
1156
- },
1157
- {
1158
- "name": "Sebastian Bergmann",
1159
- "email": "sebastian@phpunit.de"
1160
- },
1161
- {
1162
- "name": "Adam Harvey",
1163
- "email": "aharvey@php.net"
1164
- }
1165
- ],
1166
- "description": "Provides functionality to recursively process PHP variables",
1167
- "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1168
- "time": "2015-11-11 19:50:13"
1169
- },
1170
- {
1171
- "name": "sebastian/version",
1172
- "version": "1.0.6",
1173
- "source": {
1174
- "type": "git",
1175
- "url": "https://github.com/sebastianbergmann/version.git",
1176
- "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1177
- },
1178
- "dist": {
1179
- "type": "zip",
1180
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1181
- "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1182
- "shasum": ""
1183
- },
1184
- "type": "library",
1185
- "autoload": {
1186
- "classmap": [
1187
- "src/"
1188
- ]
1189
- },
1190
- "notification-url": "https://packagist.org/downloads/",
1191
- "license": [
1192
- "BSD-3-Clause"
1193
- ],
1194
- "authors": [
1195
- {
1196
- "name": "Sebastian Bergmann",
1197
- "email": "sebastian@phpunit.de",
1198
- "role": "lead"
1199
- }
1200
- ],
1201
- "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1202
- "homepage": "https://github.com/sebastianbergmann/version",
1203
- "time": "2015-06-21 13:59:46"
1204
- },
1205
- {
1206
- "name": "squizlabs/php_codesniffer",
1207
- "version": "2.6.0",
1208
- "source": {
1209
- "type": "git",
1210
- "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
1211
- "reference": "1bcdf03b068a530ac1962ce671dead356eeba43b"
1212
- },
1213
- "dist": {
1214
- "type": "zip",
1215
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1bcdf03b068a530ac1962ce671dead356eeba43b",
1216
- "reference": "1bcdf03b068a530ac1962ce671dead356eeba43b",
1217
- "shasum": ""
1218
- },
1219
- "require": {
1220
- "ext-simplexml": "*",
1221
- "ext-tokenizer": "*",
1222
- "ext-xmlwriter": "*",
1223
- "php": ">=5.1.2"
1224
- },
1225
- "require-dev": {
1226
- "phpunit/phpunit": "~4.0"
1227
- },
1228
- "bin": [
1229
- "scripts/phpcs",
1230
- "scripts/phpcbf"
1231
- ],
1232
- "type": "library",
1233
- "extra": {
1234
- "branch-alias": {
1235
- "dev-master": "2.x-dev"
1236
- }
1237
- },
1238
- "autoload": {
1239
- "classmap": [
1240
- "CodeSniffer.php",
1241
- "CodeSniffer/CLI.php",
1242
- "CodeSniffer/Exception.php",
1243
- "CodeSniffer/File.php",
1244
- "CodeSniffer/Fixer.php",
1245
- "CodeSniffer/Report.php",
1246
- "CodeSniffer/Reporting.php",
1247
- "CodeSniffer/Sniff.php",
1248
- "CodeSniffer/Tokens.php",
1249
- "CodeSniffer/Reports/",
1250
- "CodeSniffer/Tokenizers/",
1251
- "CodeSniffer/DocGenerators/",
1252
- "CodeSniffer/Standards/AbstractPatternSniff.php",
1253
- "CodeSniffer/Standards/AbstractScopeSniff.php",
1254
- "CodeSniffer/Standards/AbstractVariableSniff.php",
1255
- "CodeSniffer/Standards/IncorrectPatternException.php",
1256
- "CodeSniffer/Standards/Generic/Sniffs/",
1257
- "CodeSniffer/Standards/MySource/Sniffs/",
1258
- "CodeSniffer/Standards/PEAR/Sniffs/",
1259
- "CodeSniffer/Standards/PSR1/Sniffs/",
1260
- "CodeSniffer/Standards/PSR2/Sniffs/",
1261
- "CodeSniffer/Standards/Squiz/Sniffs/",
1262
- "CodeSniffer/Standards/Zend/Sniffs/"
1263
- ]
1264
- },
1265
- "notification-url": "https://packagist.org/downloads/",
1266
- "license": [
1267
- "BSD-3-Clause"
1268
- ],
1269
- "authors": [
1270
- {
1271
- "name": "Greg Sherwood",
1272
- "role": "lead"
1273
- }
1274
- ],
1275
- "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
1276
- "homepage": "http://www.squizlabs.com/php-codesniffer",
1277
- "keywords": [
1278
- "phpcs",
1279
- "standards"
1280
- ],
1281
- "time": "2016-04-03 22:58:34"
1282
- },
1283
- {
1284
- "name": "symfony/console",
1285
- "version": "v2.8.4",
1286
- "source": {
1287
- "type": "git",
1288
- "url": "https://github.com/symfony/console.git",
1289
- "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154"
1290
- },
1291
- "dist": {
1292
- "type": "zip",
1293
- "url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154",
1294
- "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154",
1295
- "shasum": ""
1296
- },
1297
- "require": {
1298
- "php": ">=5.3.9",
1299
- "symfony/polyfill-mbstring": "~1.0"
1300
- },
1301
- "require-dev": {
1302
- "psr/log": "~1.0",
1303
- "symfony/event-dispatcher": "~2.1|~3.0.0",
1304
- "symfony/process": "~2.1|~3.0.0"
1305
- },
1306
- "suggest": {
1307
- "psr/log": "For using the console logger",
1308
- "symfony/event-dispatcher": "",
1309
- "symfony/process": ""
1310
- },
1311
- "type": "library",
1312
- "extra": {
1313
- "branch-alias": {
1314
- "dev-master": "2.8-dev"
1315
- }
1316
- },
1317
- "autoload": {
1318
- "psr-4": {
1319
- "Symfony\\Component\\Console\\": ""
1320
- },
1321
- "exclude-from-classmap": [
1322
- "/Tests/"
1323
- ]
1324
- },
1325
- "notification-url": "https://packagist.org/downloads/",
1326
- "license": [
1327
- "MIT"
1328
- ],
1329
- "authors": [
1330
- {
1331
- "name": "Fabien Potencier",
1332
- "email": "fabien@symfony.com"
1333
- },
1334
- {
1335
- "name": "Symfony Community",
1336
- "homepage": "https://symfony.com/contributors"
1337
- }
1338
- ],
1339
- "description": "Symfony Console Component",
1340
- "homepage": "https://symfony.com",
1341
- "time": "2016-03-17 09:19:04"
1342
- },
1343
- {
1344
- "name": "symfony/filesystem",
1345
- "version": "v2.8.4",
1346
- "source": {
1347
- "type": "git",
1348
- "url": "https://github.com/symfony/filesystem.git",
1349
- "reference": "f08ffdf229252cd2745558cb2112df43903bcae4"
1350
- },
1351
- "dist": {
1352
- "type": "zip",
1353
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/f08ffdf229252cd2745558cb2112df43903bcae4",
1354
- "reference": "f08ffdf229252cd2745558cb2112df43903bcae4",
1355
- "shasum": ""
1356
- },
1357
- "require": {
1358
- "php": ">=5.3.9"
1359
- },
1360
- "type": "library",
1361
- "extra": {
1362
- "branch-alias": {
1363
- "dev-master": "2.8-dev"
1364
- }
1365
- },
1366
- "autoload": {
1367
- "psr-4": {
1368
- "Symfony\\Component\\Filesystem\\": ""
1369
- },
1370
- "exclude-from-classmap": [
1371
- "/Tests/"
1372
- ]
1373
- },
1374
- "notification-url": "https://packagist.org/downloads/",
1375
- "license": [
1376
- "MIT"
1377
- ],
1378
- "authors": [
1379
- {
1380
- "name": "Fabien Potencier",
1381
- "email": "fabien@symfony.com"
1382
- },
1383
- {
1384
- "name": "Symfony Community",
1385
- "homepage": "https://symfony.com/contributors"
1386
- }
1387
- ],
1388
- "description": "Symfony Filesystem Component",
1389
- "homepage": "https://symfony.com",
1390
- "time": "2016-03-27 10:20:16"
1391
- },
1392
- {
1393
- "name": "symfony/finder",
1394
- "version": "v2.8.4",
1395
- "source": {
1396
- "type": "git",
1397
- "url": "https://github.com/symfony/finder.git",
1398
- "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1"
1399
- },
1400
- "dist": {
1401
- "type": "zip",
1402
- "url": "https://api.github.com/repos/symfony/finder/zipball/ca24cf2cd4e3826f571e0067e535758e73807aa1",
1403
- "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1",
1404
- "shasum": ""
1405
- },
1406
- "require": {
1407
- "php": ">=5.3.9"
1408
- },
1409
- "type": "library",
1410
- "extra": {
1411
- "branch-alias": {
1412
- "dev-master": "2.8-dev"
1413
- }
1414
- },
1415
- "autoload": {
1416
- "psr-4": {
1417
- "Symfony\\Component\\Finder\\": ""
1418
- },
1419
- "exclude-from-classmap": [
1420
- "/Tests/"
1421
- ]
1422
- },
1423
- "notification-url": "https://packagist.org/downloads/",
1424
- "license": [
1425
- "MIT"
1426
- ],
1427
- "authors": [
1428
- {
1429
- "name": "Fabien Potencier",
1430
- "email": "fabien@symfony.com"
1431
- },
1432
- {
1433
- "name": "Symfony Community",
1434
- "homepage": "https://symfony.com/contributors"
1435
- }
1436
- ],
1437
- "description": "Symfony Finder Component",
1438
- "homepage": "https://symfony.com",
1439
- "time": "2016-03-10 10:53:53"
1440
- },
1441
- {
1442
- "name": "symfony/polyfill-mbstring",
1443
- "version": "v1.1.1",
1444
- "source": {
1445
- "type": "git",
1446
- "url": "https://github.com/symfony/polyfill-mbstring.git",
1447
- "reference": "1289d16209491b584839022f29257ad859b8532d"
1448
- },
1449
- "dist": {
1450
- "type": "zip",
1451
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
1452
- "reference": "1289d16209491b584839022f29257ad859b8532d",
1453
- "shasum": ""
1454
- },
1455
- "require": {
1456
- "php": ">=5.3.3"
1457
- },
1458
- "suggest": {
1459
- "ext-mbstring": "For best performance"
1460
- },
1461
- "type": "library",
1462
- "extra": {
1463
- "branch-alias": {
1464
- "dev-master": "1.1-dev"
1465
- }
1466
- },
1467
- "autoload": {
1468
- "psr-4": {
1469
- "Symfony\\Polyfill\\Mbstring\\": ""
1470
- },
1471
- "files": [
1472
- "bootstrap.php"
1473
- ]
1474
- },
1475
- "notification-url": "https://packagist.org/downloads/",
1476
- "license": [
1477
- "MIT"
1478
- ],
1479
- "authors": [
1480
- {
1481
- "name": "Nicolas Grekas",
1482
- "email": "p@tchwork.com"
1483
- },
1484
- {
1485
- "name": "Symfony Community",
1486
- "homepage": "https://symfony.com/contributors"
1487
- }
1488
- ],
1489
- "description": "Symfony polyfill for the Mbstring extension",
1490
- "homepage": "https://symfony.com",
1491
- "keywords": [
1492
- "compatibility",
1493
- "mbstring",
1494
- "polyfill",
1495
- "portable",
1496
- "shim"
1497
- ],
1498
- "time": "2016-01-20 09:13:37"
1499
- },
1500
- {
1501
- "name": "symfony/process",
1502
- "version": "v2.8.4",
1503
- "source": {
1504
- "type": "git",
1505
- "url": "https://github.com/symfony/process.git",
1506
- "reference": "fb467471952ef5cf8497c029980e556b47545333"
1507
- },
1508
- "dist": {
1509
- "type": "zip",
1510
- "url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333",
1511
- "reference": "fb467471952ef5cf8497c029980e556b47545333",
1512
- "shasum": ""
1513
- },
1514
- "require": {
1515
- "php": ">=5.3.9"
1516
- },
1517
- "type": "library",
1518
- "extra": {
1519
- "branch-alias": {
1520
- "dev-master": "2.8-dev"
1521
- }
1522
- },
1523
- "autoload": {
1524
- "psr-4": {
1525
- "Symfony\\Component\\Process\\": ""
1526
- },
1527
- "exclude-from-classmap": [
1528
- "/Tests/"
1529
- ]
1530
- },
1531
- "notification-url": "https://packagist.org/downloads/",
1532
- "license": [
1533
- "MIT"
1534
- ],
1535
- "authors": [
1536
- {
1537
- "name": "Fabien Potencier",
1538
- "email": "fabien@symfony.com"
1539
- },
1540
- {
1541
- "name": "Symfony Community",
1542
- "homepage": "https://symfony.com/contributors"
1543
- }
1544
- ],
1545
- "description": "Symfony Process Component",
1546
- "homepage": "https://symfony.com",
1547
- "time": "2016-03-23 13:11:46"
1548
- },
1549
- {
1550
- "name": "symfony/yaml",
1551
- "version": "v2.8.4",
1552
- "source": {
1553
- "type": "git",
1554
- "url": "https://github.com/symfony/yaml.git",
1555
- "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb"
1556
- },
1557
- "dist": {
1558
- "type": "zip",
1559
- "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb",
1560
- "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb",
1561
- "shasum": ""
1562
- },
1563
- "require": {
1564
- "php": ">=5.3.9"
1565
- },
1566
- "type": "library",
1567
- "extra": {
1568
- "branch-alias": {
1569
- "dev-master": "2.8-dev"
1570
- }
1571
- },
1572
- "autoload": {
1573
- "psr-4": {
1574
- "Symfony\\Component\\Yaml\\": ""
1575
- },
1576
- "exclude-from-classmap": [
1577
- "/Tests/"
1578
- ]
1579
- },
1580
- "notification-url": "https://packagist.org/downloads/",
1581
- "license": [
1582
- "MIT"
1583
- ],
1584
- "authors": [
1585
- {
1586
- "name": "Fabien Potencier",
1587
- "email": "fabien@symfony.com"
1588
- },
1589
- {
1590
- "name": "Symfony Community",
1591
- "homepage": "https://symfony.com/contributors"
1592
- }
1593
- ],
1594
- "description": "Symfony Yaml Component",
1595
- "homepage": "https://symfony.com",
1596
- "time": "2016-03-04 07:54:35"
1597
- },
1598
- {
1599
- "name": "twig/twig",
1600
- "version": "v1.24.0",
1601
- "source": {
1602
- "type": "git",
1603
- "url": "https://github.com/twigphp/Twig.git",
1604
- "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8"
1605
- },
1606
- "dist": {
1607
- "type": "zip",
1608
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
1609
- "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
1610
- "shasum": ""
1611
- },
1612
- "require": {
1613
- "php": ">=5.2.7"
1614
- },
1615
- "require-dev": {
1616
- "symfony/debug": "~2.7",
1617
- "symfony/phpunit-bridge": "~2.7"
1618
- },
1619
- "type": "library",
1620
- "extra": {
1621
- "branch-alias": {
1622
- "dev-master": "1.24-dev"
1623
- }
1624
- },
1625
- "autoload": {
1626
- "psr-0": {
1627
- "Twig_": "lib/"
1628
- }
1629
- },
1630
- "notification-url": "https://packagist.org/downloads/",
1631
- "license": [
1632
- "BSD-3-Clause"
1633
- ],
1634
- "authors": [
1635
- {
1636
- "name": "Fabien Potencier",
1637
- "email": "fabien@symfony.com",
1638
- "homepage": "http://fabien.potencier.org",
1639
- "role": "Lead Developer"
1640
- },
1641
- {
1642
- "name": "Armin Ronacher",
1643
- "email": "armin.ronacher@active-4.com",
1644
- "role": "Project Founder"
1645
- },
1646
- {
1647
- "name": "Twig Team",
1648
- "homepage": "http://twig.sensiolabs.org/contributors",
1649
- "role": "Contributors"
1650
- }
1651
- ],
1652
- "description": "Twig, the flexible, fast, and secure template language for PHP",
1653
- "homepage": "http://twig.sensiolabs.org",
1654
- "keywords": [
1655
- "templating"
1656
- ],
1657
- "time": "2016-01-25 21:22:18"
1658
- }
1659
- ],
1660
- "aliases": [],
1661
- "minimum-stability": "stable",
1662
- "stability-flags": [],
1663
- "prefer-stable": false,
1664
- "prefer-lowest": false,
1665
- "platform": {
1666
- "php": ">=5.0.0"
1667
- },
1668
- "platform-dev": []
1669
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpseclib/phpseclib/phpseclib/Crypt/Base.php CHANGED
@@ -526,8 +526,8 @@ class Crypt_Base
526
  $this->_setEngine();
527
 
528
  // Determining whether inline crypting can be used by the cipher
529
- if ($this->use_inline_crypt !== false && function_exists('create_function')) {
530
- $this->use_inline_crypt = true;
531
  }
532
  }
533
 
@@ -661,7 +661,7 @@ class Crypt_Base
661
  $count = isset($func_args[4]) ? $func_args[4] : 1000;
662
 
663
  // Keylength
664
- if (isset($func_args[5])) {
665
  $dkLen = $func_args[5];
666
  } else {
667
  $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
@@ -696,10 +696,10 @@ class Crypt_Base
696
  include_once 'Crypt/Hash.php';
697
  }
698
  $i = 1;
 
 
 
699
  while (strlen($key) < $dkLen) {
700
- $hmac = new Crypt_Hash();
701
- $hmac->setHash($hash);
702
- $hmac->setKey($password);
703
  $f = $u = $hmac->hash($salt . pack('N', $i++));
704
  for ($j = 2; $j <= $count; ++$j) {
705
  $u = $hmac->hash($u);
@@ -754,7 +754,7 @@ class Crypt_Base
754
  case CRYPT_MODE_STREAM:
755
  return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
756
  case CRYPT_MODE_ECB:
757
- $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
758
  return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
759
  case CRYPT_MODE_CBC:
760
  $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
@@ -1059,14 +1059,14 @@ class Crypt_Base
1059
  break;
1060
  case CRYPT_MODE_ECB:
1061
  if (!defined('OPENSSL_RAW_DATA')) {
1062
- $ciphertext.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
1063
  }
1064
  $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
1065
  break;
1066
  case CRYPT_MODE_CBC:
1067
  if (!defined('OPENSSL_RAW_DATA')) {
1068
  $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
1069
- $ciphertext.= substr(openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
1070
  $offset = 2 * $this->block_size;
1071
  } else {
1072
  $offset = $this->block_size;
@@ -1349,7 +1349,7 @@ class Crypt_Base
1349
  for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
1350
  $block = substr($plaintext, $i, $block_size);
1351
  if (strlen($block) > strlen($buffer['ciphertext'])) {
1352
- $result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1353
  $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
1354
  $buffer['ciphertext'].= $result;
1355
  }
@@ -1360,7 +1360,7 @@ class Crypt_Base
1360
  } else {
1361
  for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
1362
  $block = substr($plaintext, $i, $block_size);
1363
- $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1364
  $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
1365
  $this->_increment_str($xor);
1366
  $ciphertext.= $block ^ $otp;
@@ -1404,7 +1404,7 @@ class Crypt_Base
1404
  }
1405
  if ($this->continuousBuffer) {
1406
  if (!defined('OPENSSL_RAW_DATA')) {
1407
- $encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1408
  }
1409
  $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1410
  if ($overflow) {
@@ -2550,6 +2550,11 @@ class Crypt_Base
2550
  }
2551
 
2552
  // Create the $inline function and return its name as string. Ready to run!
 
 
 
 
 
2553
  return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
2554
  }
2555
 
@@ -2608,4 +2613,48 @@ class Crypt_Base
2608
  return $result . pack('H*', sha1($hash));
2609
  }
2610
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2611
  }
526
  $this->_setEngine();
527
 
528
  // Determining whether inline crypting can be used by the cipher
529
+ if ($this->use_inline_crypt !== false) {
530
+ $this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function');
531
  }
532
  }
533
 
661
  $count = isset($func_args[4]) ? $func_args[4] : 1000;
662
 
663
  // Keylength
664
+ if (isset($func_args[5]) && $func_args[5] > 0) {
665
  $dkLen = $func_args[5];
666
  } else {
667
  $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
696
  include_once 'Crypt/Hash.php';
697
  }
698
  $i = 1;
699
+ $hmac = new Crypt_Hash();
700
+ $hmac->setHash($hash);
701
+ $hmac->setKey($password);
702
  while (strlen($key) < $dkLen) {
 
 
 
703
  $f = $u = $hmac->hash($salt . pack('N', $i++));
704
  for ($j = 2; $j <= $count; ++$j) {
705
  $u = $hmac->hash($u);
754
  case CRYPT_MODE_STREAM:
755
  return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
756
  case CRYPT_MODE_ECB:
757
+ $result = @openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
758
  return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
759
  case CRYPT_MODE_CBC:
760
  $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
1059
  break;
1060
  case CRYPT_MODE_ECB:
1061
  if (!defined('OPENSSL_RAW_DATA')) {
1062
+ $ciphertext.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
1063
  }
1064
  $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
1065
  break;
1066
  case CRYPT_MODE_CBC:
1067
  if (!defined('OPENSSL_RAW_DATA')) {
1068
  $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
1069
+ $ciphertext.= substr(@openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
1070
  $offset = 2 * $this->block_size;
1071
  } else {
1072
  $offset = $this->block_size;
1349
  for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
1350
  $block = substr($plaintext, $i, $block_size);
1351
  if (strlen($block) > strlen($buffer['ciphertext'])) {
1352
+ $result = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1353
  $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
1354
  $buffer['ciphertext'].= $result;
1355
  }
1360
  } else {
1361
  for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
1362
  $block = substr($plaintext, $i, $block_size);
1363
+ $otp = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1364
  $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
1365
  $this->_increment_str($xor);
1366
  $ciphertext.= $block ^ $otp;
1404
  }
1405
  if ($this->continuousBuffer) {
1406
  if (!defined('OPENSSL_RAW_DATA')) {
1407
+ $encryptIV.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1408
  }
1409
  $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1410
  if ($overflow) {
2550
  }
2551
 
2552
  // Create the $inline function and return its name as string. Ready to run!
2553
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
2554
+ eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };');
2555
+ return $func;
2556
+ }
2557
+
2558
  return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
2559
  }
2560
 
2613
  return $result . pack('H*', sha1($hash));
2614
  }
2615
  }
2616
+
2617
+ /**
2618
+ * Convert float to int
2619
+ *
2620
+ * On 32-bit Linux installs running PHP < 5.3 converting floats to ints doesn't always work
2621
+ *
2622
+ * @access private
2623
+ * @param string $x
2624
+ * @return int
2625
+ */
2626
+ function safe_intval($x)
2627
+ {
2628
+ switch (true) {
2629
+ case is_int($x):
2630
+ // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
2631
+ case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
2632
+ // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
2633
+ case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
2634
+ return $x;
2635
+ }
2636
+ return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
2637
+ ((fmod(floor($x / 0x80000000), 2) & 1) << 31);
2638
+ }
2639
+
2640
+ /**
2641
+ * eval()'able string for in-line float to int
2642
+ *
2643
+ * @access private
2644
+ * @return string
2645
+ */
2646
+ function safe_intval_inline()
2647
+ {
2648
+ // on 32-bit linux systems with PHP < 5.3 float to integer conversion is bad
2649
+ switch (true) {
2650
+ case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8:
2651
+ case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
2652
+ case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
2653
+ return '%s';
2654
+ break;
2655
+ default:
2656
+ $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
2657
+ return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
2658
+ }
2659
+ }
2660
  }
lib/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php CHANGED
@@ -367,7 +367,7 @@ class Crypt_Blowfish extends Crypt_Base
367
  function setKeyLength($length)
368
  {
369
  if ($length < 32) {
370
- $this->key_length = 7;
371
  } elseif ($length > 448) {
372
  $this->key_length = 56;
373
  } else {
@@ -547,17 +547,7 @@ class Crypt_Blowfish extends Crypt_Base
547
  $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
548
  }
549
 
550
- // on 32-bit linux systems with PHP < 5.3 float to integer conversion is bad
551
- switch (true) {
552
- case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8:
553
- case version_compare(PHP_VERSION, '5.3.0') >= 0:
554
- case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
555
- $safeint = '%s';
556
- break;
557
- default:
558
- $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
559
- $safeint.= '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
560
- }
561
 
562
  if (!isset($lambda_functions[$code_hash])) {
563
  switch (true) {
@@ -651,24 +641,4 @@ class Crypt_Blowfish extends Crypt_Base
651
  }
652
  $this->inline_crypt = $lambda_functions[$code_hash];
653
  }
654
-
655
- /**
656
- * Convert float to int
657
- *
658
- * On 32-bit Linux installs running PHP < 5.3 converting floats to ints doesn't always work
659
- *
660
- * @access private
661
- * @param string $x
662
- * @return int
663
- */
664
- function safe_intval($x)
665
- {
666
- // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
667
- // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
668
- if (is_int($x) || version_compare(PHP_VERSION, '5.3.0') >= 0 || (PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
669
- return $x;
670
- }
671
- return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
672
- ((fmod(floor($x / 0x80000000), 2) & 1) << 31);
673
- }
674
  }
367
  function setKeyLength($length)
368
  {
369
  if ($length < 32) {
370
+ $this->key_length = 4;
371
  } elseif ($length > 448) {
372
  $this->key_length = 56;
373
  } else {
547
  $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
548
  }
549
 
550
+ $safeint = $this->safe_intval_inline();
 
 
 
 
 
 
 
 
 
 
551
 
552
  if (!isset($lambda_functions[$code_hash])) {
553
  switch (true) {
641
  }
642
  $this->inline_crypt = $lambda_functions[$code_hash];
643
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
644
  }
lib/phpseclib/phpseclib/phpseclib/Crypt/Hash.php CHANGED
@@ -126,6 +126,15 @@ class Crypt_Hash
126
  */
127
  var $key = false;
128
 
 
 
 
 
 
 
 
 
 
129
  /**
130
  * Outer XOR (Internal HMAC)
131
  *
@@ -144,6 +153,15 @@ class Crypt_Hash
144
  */
145
  var $ipad;
146
 
 
 
 
 
 
 
 
 
 
147
  /**
148
  * Default Constructor.
149
  *
@@ -192,6 +210,43 @@ class Crypt_Hash
192
  function setKey($key = false)
193
  {
194
  $this->key = $key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
196
 
197
  /**
@@ -242,19 +297,38 @@ class Crypt_Hash
242
  }
243
 
244
  switch ($hash) {
 
 
 
 
 
 
 
245
  case 'md2':
246
- $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
 
 
 
 
 
 
 
 
 
 
 
 
247
  CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
248
  break;
249
  case 'sha384':
250
  case 'sha512':
251
- $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
252
  break;
253
  default:
254
- $mode = CRYPT_HASH_MODE;
255
  }
256
 
257
- switch ($mode) {
258
  case CRYPT_HASH_MODE_MHASH:
259
  switch ($hash) {
260
  case 'md5':
@@ -267,6 +341,7 @@ class Crypt_Hash
267
  default:
268
  $this->hash = MHASH_SHA1;
269
  }
 
270
  return;
271
  case CRYPT_HASH_MODE_HASH:
272
  switch ($hash) {
@@ -283,35 +358,33 @@ class Crypt_Hash
283
  default:
284
  $this->hash = 'sha1';
285
  }
 
286
  return;
287
  }
288
 
289
  switch ($hash) {
290
  case 'md2':
291
- $this->b = 16;
292
  $this->hash = array($this, '_md2');
293
  break;
294
  case 'md5':
295
- $this->b = 64;
296
  $this->hash = array($this, '_md5');
297
  break;
298
  case 'sha256':
299
- $this->b = 64;
300
  $this->hash = array($this, '_sha256');
301
  break;
302
  case 'sha384':
303
  case 'sha512':
304
- $this->b = 128;
305
  $this->hash = array($this, '_sha512');
306
  break;
307
  case 'sha1':
308
  default:
309
- $this->b = 64;
310
  $this->hash = array($this, '_sha1');
311
  }
312
 
313
  $this->ipad = str_repeat(chr(0x36), $this->b);
314
  $this->opad = str_repeat(chr(0x5C), $this->b);
 
 
315
  }
316
 
317
  /**
@@ -323,33 +396,25 @@ class Crypt_Hash
323
  */
324
  function hash($text)
325
  {
326
- $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
327
-
328
  if (!empty($this->key) || is_string($this->key)) {
329
- switch ($mode) {
330
  case CRYPT_HASH_MODE_MHASH:
331
- $output = mhash($this->hash, $text, $this->key);
332
  break;
333
  case CRYPT_HASH_MODE_HASH:
334
- $output = hash_hmac($this->hash, $text, $this->key, true);
335
  break;
336
  case CRYPT_HASH_MODE_INTERNAL:
337
- /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
338
- resultant L byte string as the actual key to HMAC."
339
-
340
- -- http://tools.ietf.org/html/rfc2104#section-2 */
341
- $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
342
-
343
- $key = str_pad($key, $this->b, chr(0)); // step 1
344
- $temp = $this->ipad ^ $key; // step 2
345
- $temp .= $text; // step 3
346
- $temp = call_user_func($this->hash, $temp); // step 4
347
- $output = $this->opad ^ $key; // step 5
348
- $output.= $temp; // step 6
349
- $output = call_user_func($this->hash, $output); // step 7
350
  }
351
  } else {
352
- switch ($mode) {
353
  case CRYPT_HASH_MODE_MHASH:
354
  $output = mhash($this->hash, $text);
355
  break;
@@ -832,10 +897,13 @@ class Crypt_Hash
832
  $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
833
  }
834
 
835
- // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
836
- // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
837
- if (is_int($result) || version_compare(PHP_VERSION, '5.3.0') >= 0 || (PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
838
- return fmod($result, $mod);
 
 
 
839
  }
840
 
841
  return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
126
  */
127
  var $key = false;
128
 
129
+ /**
130
+ * Computed Key
131
+ *
132
+ * @see self::_computeKey()
133
+ * @var string
134
+ * @access private
135
+ */
136
+ var $computedKey = false;
137
+
138
  /**
139
  * Outer XOR (Internal HMAC)
140
  *
153
  */
154
  var $ipad;
155
 
156
+ /**
157
+ * Engine
158
+ *
159
+ * @see self::setHash()
160
+ * @var string
161
+ * @access private
162
+ */
163
+ var $engine;
164
+
165
  /**
166
  * Default Constructor.
167
  *
210
  function setKey($key = false)
211
  {
212
  $this->key = $key;
213
+ $this->_computeKey();
214
+ }
215
+
216
+ /**
217
+ * Pre-compute the key used by the HMAC
218
+ *
219
+ * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
220
+ * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
221
+ *
222
+ * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
223
+ * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
224
+ * every call
225
+ *
226
+ * @access private
227
+ */
228
+ function _computeKey()
229
+ {
230
+ if ($this->key === false) {
231
+ $this->computedKey = false;
232
+ return;
233
+ }
234
+
235
+ if (strlen($this->key) <= $this->b) {
236
+ $this->computedKey = $this->key;
237
+ return;
238
+ }
239
+
240
+ switch ($this->engine) {
241
+ case CRYPT_HASH_MODE_MHASH:
242
+ $this->computedKey = mhash($this->hash, $this->key);
243
+ break;
244
+ case CRYPT_HASH_MODE_HASH:
245
+ $this->computedKey = hash($this->hash, $this->key, true);
246
+ break;
247
+ case CRYPT_HASH_MODE_INTERNAL:
248
+ $this->computedKey = call_user_func($this->hash, $this->key);
249
+ }
250
  }
251
 
252
  /**
297
  }
298
 
299
  switch ($hash) {
300
+ case 'md2-96':
301
+ case 'md2':
302
+ $this->b = 16;
303
+ case 'md5-96':
304
+ case 'sha1-96':
305
+ case 'sha224-96':
306
+ case 'sha256-96':
307
  case 'md2':
308
+ case 'md5':
309
+ case 'sha1':
310
+ case 'sha224':
311
+ case 'sha256':
312
+ $this->b = 64;
313
+ break;
314
+ default:
315
+ $this->b = 128;
316
+ }
317
+
318
+ switch ($hash) {
319
+ case 'md2':
320
+ $this->engine = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
321
  CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
322
  break;
323
  case 'sha384':
324
  case 'sha512':
325
+ $this->engine = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
326
  break;
327
  default:
328
+ $this->engine = CRYPT_HASH_MODE;
329
  }
330
 
331
+ switch ($this->engine) {
332
  case CRYPT_HASH_MODE_MHASH:
333
  switch ($hash) {
334
  case 'md5':
341
  default:
342
  $this->hash = MHASH_SHA1;
343
  }
344
+ $this->_computeKey();
345
  return;
346
  case CRYPT_HASH_MODE_HASH:
347
  switch ($hash) {
358
  default:
359
  $this->hash = 'sha1';
360
  }
361
+ $this->_computeKey();
362
  return;
363
  }
364
 
365
  switch ($hash) {
366
  case 'md2':
 
367
  $this->hash = array($this, '_md2');
368
  break;
369
  case 'md5':
 
370
  $this->hash = array($this, '_md5');
371
  break;
372
  case 'sha256':
 
373
  $this->hash = array($this, '_sha256');
374
  break;
375
  case 'sha384':
376
  case 'sha512':
 
377
  $this->hash = array($this, '_sha512');
378
  break;
379
  case 'sha1':
380
  default:
 
381
  $this->hash = array($this, '_sha1');
382
  }
383
 
384
  $this->ipad = str_repeat(chr(0x36), $this->b);
385
  $this->opad = str_repeat(chr(0x5C), $this->b);
386
+
387
+ $this->_computeKey();
388
  }
389
 
390
  /**
396
  */
397
  function hash($text)
398
  {
 
 
399
  if (!empty($this->key) || is_string($this->key)) {
400
+ switch ($this->engine) {
401
  case CRYPT_HASH_MODE_MHASH:
402
+ $output = mhash($this->hash, $text, $this->computedKey);
403
  break;
404
  case CRYPT_HASH_MODE_HASH:
405
+ $output = hash_hmac($this->hash, $text, $this->computedKey, true);
406
  break;
407
  case CRYPT_HASH_MODE_INTERNAL:
408
+ $key = str_pad($this->computedKey, $this->b, chr(0)); // step 1
409
+ $temp = $this->ipad ^ $key; // step 2
410
+ $temp .= $text; // step 3
411
+ $temp = call_user_func($this->hash, $temp); // step 4
412
+ $output = $this->opad ^ $key; // step 5
413
+ $output.= $temp; // step 6
414
+ $output = call_user_func($this->hash, $output); // step 7
 
 
 
 
 
 
415
  }
416
  } else {
417
+ switch ($this->engine) {
418
  case CRYPT_HASH_MODE_MHASH:
419
  $output = mhash($this->hash, $text);
420
  break;
897
  $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
898
  }
899
 
900
+ switch (true) {
901
+ case is_int($result):
902
+ // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
903
+ case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
904
+ // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
905
+ case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
906
+ return fmod($result, $mod);
907
  }
908
 
909
  return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
lib/phpseclib/phpseclib/phpseclib/Crypt/RC2.php CHANGED
@@ -369,7 +369,7 @@ class Crypt_RC2 extends Crypt_Base
369
  function setKeyLength($length)
370
  {
371
  if ($length < 8) {
372
- $this->default_key_length = 8;
373
  } elseif ($length > 1024) {
374
  $this->default_key_length = 128;
375
  } else {
369
  function setKeyLength($length)
370
  {
371
  if ($length < 8) {
372
+ $this->default_key_length = 1;
373
  } elseif ($length > 1024) {
374
  $this->default_key_length = 128;
375
  } else {
lib/phpseclib/phpseclib/phpseclib/Crypt/RC4.php CHANGED
@@ -141,7 +141,7 @@ class Crypt_RC4 extends Crypt_Base
141
  * @var string
142
  * @access private
143
  */
144
- var $key = "\0";
145
 
146
  /**
147
  * The Key Stream for decryption and encryption
141
  * @var string
142
  * @access private
143
  */
144
+ var $key;
145
 
146
  /**
147
  * The Key Stream for decryption and encryption
lib/phpseclib/phpseclib/phpseclib/Crypt/RSA.php CHANGED
@@ -210,6 +210,10 @@ define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2);
210
  * PKCS#8 formatted private key
211
  */
212
  define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 8);
 
 
 
 
213
  /**#@-*/
214
 
215
  /**#@+
@@ -878,6 +882,58 @@ class Crypt_RSA
878
  $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
879
 
880
  return $key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
881
  default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
882
  $components = array();
883
  foreach ($raw as $name => $value) {
@@ -1415,9 +1471,14 @@ class Crypt_RSA
1415
  xml_set_character_data_handler($xml, '_data_handler');
1416
  // add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
1417
  if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
 
 
1418
  return false;
1419
  }
1420
 
 
 
 
1421
  return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
1422
  // from PuTTY's SSHPUBK.C
1423
  case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
@@ -1492,6 +1553,75 @@ class Crypt_RSA
1492
  }
1493
  $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($private, $length), -256));
1494
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1495
  return $components;
1496
  }
1497
  }
@@ -1648,7 +1778,8 @@ class Crypt_RSA
1648
  CRYPT_RSA_PRIVATE_FORMAT_PKCS1,
1649
  CRYPT_RSA_PRIVATE_FORMAT_XML,
1650
  CRYPT_RSA_PRIVATE_FORMAT_PUTTY,
1651
- CRYPT_RSA_PUBLIC_FORMAT_OPENSSH
 
1652
  );
1653
  foreach ($types as $type) {
1654
  $components = $this->_parseKey($key, $type);
@@ -2296,16 +2427,21 @@ class Crypt_RSA
2296
  */
2297
  function _equals($x, $y)
2298
  {
 
 
 
 
2299
  if (strlen($x) != strlen($y)) {
2300
  return false;
2301
  }
2302
 
2303
- $result = 0;
 
2304
  for ($i = 0; $i < strlen($x); $i++) {
2305
- $result |= ord($x[$i]) ^ ord($y[$i]);
2306
  }
2307
 
2308
- return $result == 0;
2309
  }
2310
 
2311
  /**
@@ -2512,19 +2648,26 @@ class Crypt_RSA
2512
  $db = $maskedDB ^ $dbMask;
2513
  $lHash2 = substr($db, 0, $this->hLen);
2514
  $m = substr($db, $this->hLen);
2515
- if ($lHash != $lHash2) {
2516
- user_error('Decryption error');
2517
- return false;
2518
- }
2519
- $m = ltrim($m, chr(0));
2520
- if (ord($m[0]) != 1) {
 
 
 
 
 
 
 
2521
  user_error('Decryption error');
2522
  return false;
2523
  }
2524
 
2525
  // Output the message M
2526
 
2527
- return substr($m, 1);
2528
  }
2529
 
2530
  /**
@@ -2703,7 +2846,7 @@ class Crypt_RSA
2703
  // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2704
  // be output.
2705
 
2706
- $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8);
2707
  $sLen = $this->sLen !== null ? $this->sLen : $this->hLen;
2708
 
2709
  $mHash = $this->hash->hash($m);
@@ -2781,7 +2924,7 @@ class Crypt_RSA
2781
 
2782
  // RSA verification
2783
 
2784
- $modBits = 8 * $this->k;
2785
 
2786
  $s2 = $this->_os2ip($s);
2787
  $m2 = $this->_rsavp1($s2);
@@ -2789,7 +2932,7 @@ class Crypt_RSA
2789
  user_error('Invalid signature');
2790
  return false;
2791
  }
2792
- $em = $this->_i2osp($m2, $modBits >> 3);
2793
  if ($em === false) {
2794
  user_error('Invalid signature');
2795
  return false;
210
  * PKCS#8 formatted private key
211
  */
212
  define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 8);
213
+ /**
214
+ * OpenSSH formatted private key
215
+ */
216
+ define('CRYPT_RSA_PRIVATE_FORMAT_OPENSSH', 9);
217
  /**#@-*/
218
 
219
  /**#@+
882
  $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
883
 
884
  return $key;
885
+ case CRYPT_RSA_PRIVATE_FORMAT_OPENSSH:
886
+ if ($num_primes != 2) {
887
+ return false;
888
+ }
889
+ $publicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']);
890
+ $privateKey = pack(
891
+ 'Na*Na*Na*Na*Na*Na*Na*',
892
+ strlen('ssh-rsa'),
893
+ 'ssh-rsa',
894
+ strlen($raw['modulus']),
895
+ $raw['modulus'],
896
+ strlen($raw['publicExponent']),
897
+ $raw['publicExponent'],
898
+ strlen($raw['privateExponent']),
899
+ $raw['privateExponent'],
900
+ strlen($raw['coefficient']),
901
+ $raw['coefficient'],
902
+ strlen($raw['prime1']),
903
+ $raw['prime1'],
904
+ strlen($raw['prime2']),
905
+ $raw['prime2']
906
+ );
907
+ $checkint = crypt_random_string(4);
908
+ $paddedKey = pack(
909
+ 'a*Na*',
910
+ $checkint . $checkint . $privateKey,
911
+ strlen($this->comment),
912
+ $this->comment
913
+ );
914
+ $paddingLength = (7 * strlen($paddedKey)) % 8;
915
+ for ($i = 1; $i <= $paddingLength; $i++) {
916
+ $paddedKey.= chr($i);
917
+ }
918
+ $key = pack(
919
+ 'Na*Na*Na*NNa*Na*',
920
+ strlen('none'),
921
+ 'none',
922
+ strlen('none'),
923
+ 'none',
924
+ 0,
925
+ '',
926
+ 1,
927
+ strlen($publicKey),
928
+ $publicKey,
929
+ strlen($paddedKey),
930
+ $paddedKey
931
+ );
932
+ $key = "openssh-key-v1\0$key";
933
+
934
+ return "-----BEGIN OPENSSH PRIVATE KEY-----\r\n" .
935
+ chunk_split(base64_encode($key), 70) .
936
+ "-----END OPENSSH PRIVATE KEY-----";
937
  default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
938
  $components = array();
939
  foreach ($raw as $name => $value) {
1471
  xml_set_character_data_handler($xml, '_data_handler');
1472
  // add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
1473
  if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
1474
+ xml_parser_free($xml);
1475
+ unset($xml);
1476
  return false;
1477
  }
1478
 
1479
+ xml_parser_free($xml);
1480
+ unset($xml);
1481
+
1482
  return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
1483
  // from PuTTY's SSHPUBK.C
1484
  case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
1553
  }
1554
  $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($private, $length), -256));
1555
 
1556
+ return $components;
1557
+ case CRYPT_RSA_PRIVATE_FORMAT_OPENSSH:
1558
+ $components = array();
1559
+ $decoded = $this->_extractBER($key);
1560
+ $magic = $this->_string_shift($decoded, 15);
1561
+ if ($magic !== "openssh-key-v1\0") {
1562
+ return false;
1563
+ }
1564
+ $options = $this->_string_shift($decoded, 24);
1565
+ // \0\0\0\4none = ciphername
1566
+ // \0\0\0\4none = kdfname
1567
+ // \0\0\0\0 = kdfoptions
1568
+ // \0\0\0\1 = numkeys
1569
+ if ($options != "\0\0\0\4none\0\0\0\4none\0\0\0\0\0\0\0\1") {
1570
+ return false;
1571
+ }
1572
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
1573
+ if (strlen($decoded) < $length) {
1574
+ return false;
1575
+ }
1576
+ $publicKey = $this->_string_shift($decoded, $length);
1577
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
1578
+ if (strlen($decoded) < $length) {
1579
+ return false;
1580
+ }
1581
+ $paddedKey = $this->_string_shift($decoded, $length);
1582
+
1583
+ if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") {
1584
+ return false;
1585
+ }
1586
+
1587
+ $checkint1 = $this->_string_shift($paddedKey, 4);
1588
+ $checkint2 = $this->_string_shift($paddedKey, 4);
1589
+ if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) {
1590
+ return false;
1591
+ }
1592
+
1593
+ if ($this->_string_shift($paddedKey, 11) !== "\0\0\0\7ssh-rsa") {
1594
+ return false;
1595
+ }
1596
+
1597
+ $values = array(
1598
+ &$components['modulus'],
1599
+ &$components['publicExponent'],
1600
+ &$components['privateExponent'],
1601
+ &$components['coefficients'][2],
1602
+ &$components['primes'][1],
1603
+ &$components['primes'][2]
1604
+ );
1605
+
1606
+ for ($i = 0; $i < count($values); $i++) {
1607
+ extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
1608
+ if (strlen($paddedKey) < $length) {
1609
+ return false;
1610
+ }
1611
+ $values[$i] = new Math_BigInteger($this->_string_shift($paddedKey, $length), -256);
1612
+ }
1613
+
1614
+ extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
1615
+ if (strlen($paddedKey) < $length) {
1616
+ return false;
1617
+ }
1618
+ $components['comment'] = $this->_string_shift($decoded, $length);
1619
+
1620
+ $temp = $components['primes'][1]->subtract($this->one);
1621
+ $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
1622
+ $temp = $components['primes'][2]->subtract($this->one);
1623
+ $components['exponents'][] = $components['publicExponent']->modInverse($temp);
1624
+
1625
  return $components;
1626
  }
1627
  }
1778
  CRYPT_RSA_PRIVATE_FORMAT_PKCS1,
1779
  CRYPT_RSA_PRIVATE_FORMAT_XML,
1780
  CRYPT_RSA_PRIVATE_FORMAT_PUTTY,
1781
+ CRYPT_RSA_PUBLIC_FORMAT_OPENSSH,
1782
+ CRYPT_RSA_PRIVATE_FORMAT_OPENSSH
1783
  );
1784
  foreach ($types as $type) {
1785
  $components = $this->_parseKey($key, $type);
2427
  */
2428
  function _equals($x, $y)
2429
  {
2430
+ if (function_exists('hash_equals')) {
2431
+ return hash_equals($x, $y);
2432
+ }
2433
+
2434
  if (strlen($x) != strlen($y)) {
2435
  return false;
2436
  }
2437
 
2438
+ $result = "\0";
2439
+ $x^= $y;
2440
  for ($i = 0; $i < strlen($x); $i++) {
2441
+ $result|= $x[$i];
2442
  }
2443
 
2444
+ return $result === "\0";
2445
  }
2446
 
2447
  /**
2648
  $db = $maskedDB ^ $dbMask;
2649
  $lHash2 = substr($db, 0, $this->hLen);
2650
  $m = substr($db, $this->hLen);
2651
+ $hashesMatch = $this->_equals($lHash, $lHash2);
2652
+ $leadingZeros = 1;
2653
+ $patternMatch = 0;
2654
+ $offset = 0;
2655
+ for ($i = 0; $i < strlen($m); $i++) {
2656
+ $patternMatch|= $leadingZeros & ($m[$i] === "\1");
2657
+ $leadingZeros&= $m[$i] === "\0";
2658
+ $offset+= $patternMatch ? 0 : 1;
2659
+ }
2660
+
2661
+ // we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation
2662
+ // to protect against timing attacks
2663
+ if (!$hashesMatch & !$patternMatch) {
2664
  user_error('Decryption error');
2665
  return false;
2666
  }
2667
 
2668
  // Output the message M
2669
 
2670
+ return substr($m, $offset + 1);
2671
  }
2672
 
2673
  /**
2846
  // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2847
  // be output.
2848
 
2849
+ $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8);
2850
  $sLen = $this->sLen !== null ? $this->sLen : $this->hLen;
2851
 
2852
  $mHash = $this->hash->hash($m);
2924
 
2925
  // RSA verification
2926
 
2927
+ $modBits = strlen($this->modulus->toBits());
2928
 
2929
  $s2 = $this->_os2ip($s);
2930
  $m2 = $this->_rsavp1($s2);
2932
  user_error('Invalid signature');
2933
  return false;
2934
  }
2935
+ $em = $this->_i2osp($m2, $this->k);
2936
  if ($em === false) {
2937
  user_error('Invalid signature');
2938
  return false;
lib/phpseclib/phpseclib/phpseclib/Crypt/Random.php CHANGED
@@ -67,6 +67,10 @@ if (!function_exists('crypt_random_string')) {
67
  */
68
  function crypt_random_string($length)
69
  {
 
 
 
 
70
  if (CRYPT_RANDOM_IS_WINDOWS) {
71
  // method 1. prior to PHP 5.3, mcrypt_create_iv() would call rand() on windows
72
  if (extension_loaded('mcrypt') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
@@ -101,7 +105,10 @@ if (!function_exists('crypt_random_string')) {
101
  $fp = @fopen('/dev/urandom', 'rb');
102
  }
103
  if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
104
- return fread($fp, $length);
 
 
 
105
  }
106
  // method 3. pretty much does the same thing as method 2 per the following url:
107
  // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
67
  */
68
  function crypt_random_string($length)
69
  {
70
+ if (!$length) {
71
+ return '';
72
+ }
73
+
74
  if (CRYPT_RANDOM_IS_WINDOWS) {
75
  // method 1. prior to PHP 5.3, mcrypt_create_iv() would call rand() on windows
76
  if (extension_loaded('mcrypt') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
105
  $fp = @fopen('/dev/urandom', 'rb');
106
  }
107
  if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
108
+ $temp = fread($fp, $length);
109
+ if (strlen($temp) == $length) {
110
+ return $temp;
111
+ }
112
  }
113
  // method 3. pretty much does the same thing as method 2 per the following url:
114
  // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
lib/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php CHANGED
@@ -505,8 +505,10 @@ class Crypt_Twofish extends Crypt_Base
505
  $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
506
  $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
507
  $B = ($B << 8) | ($B >> 24 & 0xff);
508
- $K[] = $A+= $B;
509
- $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
 
 
510
  }
511
  for ($i = 0; $i < 256; ++$i) {
512
  $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
@@ -529,8 +531,10 @@ class Crypt_Twofish extends Crypt_Base
529
  $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
530
  $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
531
  $B = ($B << 8) | ($B >> 24 & 0xff);
532
- $K[] = $A+= $B;
533
- $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
 
 
534
  }
535
  for ($i = 0; $i < 256; ++$i) {
536
  $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
@@ -554,8 +558,10 @@ class Crypt_Twofish extends Crypt_Base
554
  $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
555
  $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
556
  $B = ($B << 8) | ($B >> 24 & 0xff);
557
- $K[] = $A+= $B;
558
- $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
 
 
559
  }
560
  for ($i = 0; $i < 256; ++$i) {
561
  $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
@@ -651,9 +657,9 @@ class Crypt_Twofish extends Crypt_Base
651
  $S1[ $R1 & 0xff] ^
652
  $S2[($R1 >> 8) & 0xff] ^
653
  $S3[($R1 >> 16) & 0xff];
654
- $R2^= $t0 + $t1 + $K[++$ki];
655
  $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
656
- $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
657
 
658
  $t0 = $S0[ $R2 & 0xff] ^
659
  $S1[($R2 >> 8) & 0xff] ^
@@ -663,9 +669,9 @@ class Crypt_Twofish extends Crypt_Base
663
  $S1[ $R3 & 0xff] ^
664
  $S2[($R3 >> 8) & 0xff] ^
665
  $S3[($R3 >> 16) & 0xff];
666
- $R0^= ($t0 + $t1 + $K[++$ki]);
667
  $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
668
- $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
669
  }
670
 
671
  // @codingStandardsIgnoreStart
@@ -707,9 +713,9 @@ class Crypt_Twofish extends Crypt_Base
707
  $S1[$R1 & 0xff] ^
708
  $S2[$R1 >> 8 & 0xff] ^
709
  $S3[$R1 >> 16 & 0xff];
710
- $R3^= $t0 + ($t1 << 1) + $K[--$ki];
711
  $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
712
- $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K[--$ki]);
713
 
714
  $t0 = $S0[$R2 & 0xff] ^
715
  $S1[$R2 >> 8 & 0xff] ^
@@ -719,9 +725,9 @@ class Crypt_Twofish extends Crypt_Base
719
  $S1[$R3 & 0xff] ^
720
  $S2[$R3 >> 8 & 0xff] ^
721
  $S3[$R3 >> 16 & 0xff];
722
- $R1^= $t0 + ($t1 << 1) + $K[--$ki];
723
  $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
724
- $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
725
  }
726
 
727
  // @codingStandardsIgnoreStart
@@ -752,6 +758,8 @@ class Crypt_Twofish extends Crypt_Base
752
  $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
753
  }
754
 
 
 
755
  if (!isset($lambda_functions[$code_hash])) {
756
  switch (true) {
757
  case $gen_hi_opt_code:
@@ -800,9 +808,9 @@ class Crypt_Twofish extends Crypt_Base
800
  $S1[ $R1 & 0xff] ^
801
  $S2[($R1 >> 8) & 0xff] ^
802
  $S3[($R1 >> 16) & 0xff];
803
- $R2^= ($t0 + $t1 + '.$K[++$ki].');
804
  $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
805
- $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
806
 
807
  $t0 = $S0[ $R2 & 0xff] ^
808
  $S1[($R2 >> 8) & 0xff] ^
@@ -812,16 +820,16 @@ class Crypt_Twofish extends Crypt_Base
812
  $S1[ $R3 & 0xff] ^
813
  $S2[($R3 >> 8) & 0xff] ^
814
  $S3[($R3 >> 16) & 0xff];
815
- $R0^= ($t0 + $t1 + '.$K[++$ki].');
816
  $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
817
- $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
818
  ';
819
  }
820
  $encrypt_block.= '
821
- $in = pack("V4", '.$K[4].' ^ $R2,
822
- '.$K[5].' ^ $R3,
823
- '.$K[6].' ^ $R0,
824
- '.$K[7].' ^ $R1);
825
  ';
826
 
827
  // Generating decrypt code:
@@ -842,9 +850,9 @@ class Crypt_Twofish extends Crypt_Base
842
  $S1[$R1 & 0xff] ^
843
  $S2[$R1 >> 8 & 0xff] ^
844
  $S3[$R1 >> 16 & 0xff];
845
- $R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
846
  $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
847
- $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
848
 
849
  $t0 = $S0[$R2 & 0xff] ^
850
  $S1[$R2 >> 8 & 0xff] ^
@@ -854,16 +862,16 @@ class Crypt_Twofish extends Crypt_Base
854
  $S1[$R3 & 0xff] ^
855
  $S2[$R3 >> 8 & 0xff] ^
856
  $S3[$R3 >> 16 & 0xff];
857
- $R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
858
  $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
859
- $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
860
  ';
861
  }
862
  $decrypt_block.= '
863
- $in = pack("V4", '.$K[0].' ^ $R2,
864
- '.$K[1].' ^ $R3,
865
- '.$K[2].' ^ $R0,
866
- '.$K[3].' ^ $R1);
867
  ';
868
 
869
  $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
505
  $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
506
  $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
507
  $B = ($B << 8) | ($B >> 24 & 0xff);
508
+ $A = $this->safe_intval($A + $B);
509
+ $K[] = $A;
510
+ $A = $this->safe_intval($A + $B);
511
+ $K[] = ($A << 9 | $A >> 23 & 0x1ff);
512
  }
513
  for ($i = 0; $i < 256; ++$i) {
514
  $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
531
  $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
532
  $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
533
  $B = ($B << 8) | ($B >> 24 & 0xff);
534
+ $A = $this->safe_intval($A + $B);
535
+ $K[] = $A;
536
+ $A = $this->safe_intval($A + $B);
537
+ $K[] = ($A << 9 | $A >> 23 & 0x1ff);
538
  }
539
  for ($i = 0; $i < 256; ++$i) {
540
  $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
558
  $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
559
  $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
560
  $B = ($B << 8) | ($B >> 24 & 0xff);
561
+ $A = $this->safe_intval($A + $B);
562
+ $K[] = $A;
563
+ $A = $this->safe_intval($A + $B);
564
+ $K[] = ($A << 9 | $A >> 23 & 0x1ff);
565
  }
566
  for ($i = 0; $i < 256; ++$i) {
567
  $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
657
  $S1[ $R1 & 0xff] ^
658
  $S2[($R1 >> 8) & 0xff] ^
659
  $S3[($R1 >> 16) & 0xff];
660
+ $R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
661
  $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
662
+ $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
663
 
664
  $t0 = $S0[ $R2 & 0xff] ^
665
  $S1[($R2 >> 8) & 0xff] ^
669
  $S1[ $R3 & 0xff] ^
670
  $S2[($R3 >> 8) & 0xff] ^
671
  $S3[($R3 >> 16) & 0xff];
672
+ $R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
673
  $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
674
+ $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
675
  }
676
 
677
  // @codingStandardsIgnoreStart
713
  $S1[$R1 & 0xff] ^
714
  $S2[$R1 >> 8 & 0xff] ^
715
  $S3[$R1 >> 16 & 0xff];
716
+ $R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
717
  $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
718
+ $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
719
 
720
  $t0 = $S0[$R2 & 0xff] ^
721
  $S1[$R2 >> 8 & 0xff] ^
725
  $S1[$R3 & 0xff] ^
726
  $S2[$R3 >> 8 & 0xff] ^
727
  $S3[$R3 >> 16 & 0xff];
728
+ $R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
729
  $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
730
+ $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
731
  }
732
 
733
  // @codingStandardsIgnoreStart
758
  $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
759
  }
760
 
761
+ $safeint = $this->safe_intval_inline();
762
+
763
  if (!isset($lambda_functions[$code_hash])) {
764
  switch (true) {
765
  case $gen_hi_opt_code:
808
  $S1[ $R1 & 0xff] ^
809
  $S2[($R1 >> 8) & 0xff] ^
810
  $S3[($R1 >> 16) & 0xff];
811
+ $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . ';
812
  $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
813
+ $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
814
 
815
  $t0 = $S0[ $R2 & 0xff] ^
816
  $S1[($R2 >> 8) & 0xff] ^
820
  $S1[ $R3 & 0xff] ^
821
  $S2[($R3 >> 8) & 0xff] ^
822
  $S3[($R3 >> 16) & 0xff];
823
+ $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . ';
824
  $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
825
+ $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
826
  ';
827
  }
828
  $encrypt_block.= '
829
+ $in = pack("V4", ' . $K[4] . ' ^ $R2,
830
+ ' . $K[5] . ' ^ $R3,
831
+ ' . $K[6] . ' ^ $R0,
832
+ ' . $K[7] . ' ^ $R1);
833
  ';
834
 
835
  // Generating decrypt code:
850
  $S1[$R1 & 0xff] ^
851
  $S2[$R1 >> 8 & 0xff] ^
852
  $S3[$R1 >> 16 & 0xff];
853
+ $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
854
  $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
855
+ $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
856
 
857
  $t0 = $S0[$R2 & 0xff] ^
858
  $S1[$R2 >> 8 & 0xff] ^
862
  $S1[$R3 & 0xff] ^
863
  $S2[$R3 >> 8 & 0xff] ^
864
  $S3[$R3 >> 16 & 0xff];
865
+ $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
866
  $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
867
+ $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
868
  ';
869
  }
870
  $decrypt_block.= '
871
+ $in = pack("V4", ' . $K[0] . ' ^ $R2,
872
+ ' . $K[1] . ' ^ $R3,
873
+ ' . $K[2] . ' ^ $R0,
874
+ ' . $K[3] . ' ^ $R1);
875
  ';
876
 
877
  $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
lib/phpseclib/phpseclib/phpseclib/File/ANSI.php CHANGED
@@ -299,7 +299,7 @@ class File_ANSI
299
  case "\x1B[K": // Clear screen from cursor right
300
  $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
301
 
302
- array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - $this->x - 1, $this->base_attr_cell));
303
  break;
304
  case "\x1B[2K": // Clear entire line
305
  $this->screen[$this->y] = str_repeat(' ', $this->x);
@@ -332,6 +332,9 @@ class File_ANSI
332
  case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
333
  $this->old_x = $this->x;
334
  $this->x-= $match[1];
 
 
 
335
  break;
336
  case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
337
  break;
@@ -443,7 +446,7 @@ class File_ANSI
443
 
444
  if ($this->x > $this->max_x) {
445
  $this->x = 0;
446
- $this->y++;
447
  } else {
448
  $this->x++;
449
  }
299
  case "\x1B[K": // Clear screen from cursor right
300
  $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
301
 
302
+ array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - ($this->x - 1), $this->base_attr_cell));
303
  break;
304
  case "\x1B[2K": // Clear entire line
305
  $this->screen[$this->y] = str_repeat(' ', $this->x);
332
  case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
333
  $this->old_x = $this->x;
334
  $this->x-= $match[1];
335
+ if ($this->x < 0) {
336
+ $this->x = 0;
337
+ }
338
  break;
339
  case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
340
  break;
446
 
447
  if ($this->x > $this->max_x) {
448
  $this->x = 0;
449
+ $this->_newLine();
450
  } else {
451
  $this->x++;
452
  }
lib/phpseclib/phpseclib/phpseclib/File/ASN1.php CHANGED
@@ -326,9 +326,10 @@ class File_ASN1
326
  $tag = 0;
327
  // process septets (since the eighth bit is ignored, it's not an octet)
328
  do {
329
- $loop = ord($encoded[0]) >> 7;
 
330
  $tag <<= 7;
331
- $tag |= ord($encoded[$encoded_pos++]) & 0x7F;
332
  $start++;
333
  } while ($loop);
334
  }
@@ -390,6 +391,9 @@ class File_ASN1
390
  $remainingLength = $length;
391
  while ($remainingLength > 0) {
392
  $temp = $this->_decode_ber($content, $start, $content_pos);
 
 
 
393
  $length = $temp['length'];
394
  // end-of-content octets - see paragraph 8.1.5
395
  if (substr($content, $content_pos + $length, 2) == "\0\0") {
@@ -441,6 +445,9 @@ class File_ASN1
441
  $current['content'] = substr($content, $content_pos);
442
  } else {
443
  $temp = $this->_decode_ber($content, $start, $content_pos);
 
 
 
444
  $length-= (strlen($content) - $content_pos);
445
  $last = count($temp) - 1;
446
  for ($i = 0; $i < $last; $i++) {
@@ -465,6 +472,9 @@ class File_ASN1
465
  $length = 0;
466
  while (substr($content, $content_pos, 2) != "\0\0") {
467
  $temp = $this->_decode_ber($content, $length + $start, $content_pos);
 
 
 
468
  $content_pos += $temp['length'];
469
  // all subtags should be octet strings
470
  //if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
@@ -497,30 +507,16 @@ class File_ASN1
497
  break 2;
498
  }
499
  $temp = $this->_decode_ber($content, $start + $offset, $content_pos);
 
 
 
500
  $content_pos += $temp['length'];
501
  $current['content'][] = $temp;
502
  $offset+= $temp['length'];
503
  }
504
  break;
505
  case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
506
- $temp = ord($content[$content_pos++]);
507
- $current['content'] = sprintf('%d.%d', floor($temp / 40), $temp % 40);
508
- $valuen = 0;
509
- // process septets
510
- $content_len = strlen($content);
511
- while ($content_pos < $content_len) {
512
- $temp = ord($content[$content_pos++]);
513
- $valuen <<= 7;
514
- $valuen |= $temp & 0x7F;
515
- if (~$temp & 0x80) {
516
- $current['content'].= ".$valuen";
517
- $valuen = 0;
518
- }
519
- }
520
- // the eighth bit of the last byte should not be 1
521
- //if ($temp >> 7) {
522
- // return false;
523
- //}
524
  break;
525
  /* Each character string type shall be encoded as if it had been declared:
526
  [UNIVERSAL x] IMPLICIT OCTET STRING
@@ -554,7 +550,9 @@ class File_ASN1
554
  break;
555
  case FILE_ASN1_TYPE_UTC_TIME:
556
  case FILE_ASN1_TYPE_GENERALIZED_TIME:
557
- $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag);
 
 
558
  default:
559
  }
560
 
@@ -579,6 +577,10 @@ class File_ASN1
579
  */
580
  function asn1map($decoded, $mapping, $special = array())
581
  {
 
 
 
 
582
  if (isset($mapping['explicit']) && is_array($decoded['content'])) {
583
  $decoded = $decoded['content'][0];
584
  }
@@ -664,7 +666,7 @@ class File_ASN1
664
  $childClass = $tempClass = FILE_ASN1_CLASS_UNIVERSAL;
665
  $constant = null;
666
  if (isset($temp['constant'])) {
667
- $tempClass = isset($temp['class']) ? $temp['class'] : FILE_ASN1_CLASS_CONTEXT_SPECIFIC;
668
  }
669
  if (isset($child['class'])) {
670
  $childClass = $child['class'];
@@ -727,7 +729,7 @@ class File_ASN1
727
  $temp = $decoded['content'][$i];
728
  $tempClass = FILE_ASN1_CLASS_UNIVERSAL;
729
  if (isset($temp['constant'])) {
730
- $tempClass = isset($temp['class']) ? $temp['class'] : FILE_ASN1_CLASS_CONTEXT_SPECIFIC;
731
  }
732
 
733
  foreach ($mapping['children'] as $key => $child) {
@@ -788,10 +790,30 @@ class File_ASN1
788
  return isset($this->oids[$decoded['content']]) ? $this->oids[$decoded['content']] : $decoded['content'];
789
  case FILE_ASN1_TYPE_UTC_TIME:
790
  case FILE_ASN1_TYPE_GENERALIZED_TIME:
791
- if (isset($mapping['implicit'])) {
792
- $decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
  }
794
- return @date($this->format, $decoded['content']);
795
  case FILE_ASN1_TYPE_BIT_STRING:
796
  if (isset($mapping['mapping'])) {
797
  $offset = ord($decoded['content'][0]);
@@ -929,7 +951,7 @@ class File_ASN1
929
  if ($mapping['type'] == FILE_ASN1_TYPE_SET) {
930
  sort($value);
931
  }
932
- $value = implode($value, '');
933
  break;
934
  }
935
 
@@ -1040,7 +1062,12 @@ class File_ASN1
1040
  case FILE_ASN1_TYPE_GENERALIZED_TIME:
1041
  $format = $mapping['type'] == FILE_ASN1_TYPE_UTC_TIME ? 'y' : 'Y';
1042
  $format.= 'mdHis';
1043
- $value = @gmdate($format, strtotime($source)) . 'Z';
 
 
 
 
 
1044
  break;
1045
  case FILE_ASN1_TYPE_BIT_STRING:
1046
  if (isset($mapping['mapping'])) {
@@ -1082,27 +1109,7 @@ class File_ASN1
1082
  $value = base64_decode($source);
1083
  break;
1084
  case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
1085
- $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
1086
- if ($oid === false) {
1087
- user_error('Invalid OID');
1088
- return false;
1089
- }
1090
- $value = '';
1091
- $parts = explode('.', $oid);
1092
- $value = chr(40 * $parts[0] + $parts[1]);
1093
- for ($i = 2; $i < count($parts); $i++) {
1094
- $temp = '';
1095
- if (!$parts[$i]) {
1096
- $temp = "\0";
1097
- } else {
1098
- while ($parts[$i]) {
1099
- $temp = chr(0x80 | ($parts[$i] & 0x7F)) . $temp;
1100
- $parts[$i] >>= 7;
1101
- }
1102
- $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
1103
- }
1104
- $value.= $temp;
1105
- }
1106
  break;
1107
  case FILE_ASN1_TYPE_ANY:
1108
  $loc = $this->location;
@@ -1202,7 +1209,109 @@ class File_ASN1
1202
  }
1203
 
1204
  /**
1205
- * BER-decode the time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1206
  *
1207
  * Called by _decode_ber() and in the case of implicit tags asn1map().
1208
  *
@@ -1211,7 +1320,7 @@ class File_ASN1
1211
  * @param int $tag
1212
  * @return string
1213
  */
1214
- function _decodeTime($content, $tag)
1215
  {
1216
  /* UTCTime:
1217
  http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
@@ -1250,6 +1359,55 @@ class File_ASN1
1250
  return @$mktime((int)$hour, (int)$minute, (int)$second, (int)$month, (int)$day, (int)$year) + $timezone;
1251
  }
1252
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1253
  /**
1254
  * Set the time format
1255
  *
326
  $tag = 0;
327
  // process septets (since the eighth bit is ignored, it's not an octet)
328
  do {
329
+ $temp = ord($encoded[$encoded_pos++]);
330
+ $loop = $temp >> 7;
331
  $tag <<= 7;
332
+ $tag |= $temp & 0x7F;
333
  $start++;
334
  } while ($loop);
335
  }
391
  $remainingLength = $length;
392
  while ($remainingLength > 0) {
393
  $temp = $this->_decode_ber($content, $start, $content_pos);
394
+ if ($temp === false) {
395
+ break;
396
+ }
397
  $length = $temp['length'];
398
  // end-of-content octets - see paragraph 8.1.5
399
  if (substr($content, $content_pos + $length, 2) == "\0\0") {
445
  $current['content'] = substr($content, $content_pos);
446
  } else {
447
  $temp = $this->_decode_ber($content, $start, $content_pos);
448
+ if ($temp === false) {
449
+ return false;
450
+ }
451
  $length-= (strlen($content) - $content_pos);
452
  $last = count($temp) - 1;
453
  for ($i = 0; $i < $last; $i++) {
472
  $length = 0;
473
  while (substr($content, $content_pos, 2) != "\0\0") {
474
  $temp = $this->_decode_ber($content, $length + $start, $content_pos);
475
+ if ($temp === false) {
476
+ return false;
477
+ }
478
  $content_pos += $temp['length'];
479
  // all subtags should be octet strings
480
  //if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
507
  break 2;
508
  }
509
  $temp = $this->_decode_ber($content, $start + $offset, $content_pos);
510
+ if ($temp === false) {
511
+ return false;
512
+ }
513
  $content_pos += $temp['length'];
514
  $current['content'][] = $temp;
515
  $offset+= $temp['length'];
516
  }
517
  break;
518
  case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
519
+ $current['content'] = $this->_decodeOID(substr($content, $content_pos));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
  break;
521
  /* Each character string type shall be encoded as if it had been declared:
522
  [UNIVERSAL x] IMPLICIT OCTET STRING
550
  break;
551
  case FILE_ASN1_TYPE_UTC_TIME:
552
  case FILE_ASN1_TYPE_GENERALIZED_TIME:
553
+ $current['content'] = class_exists('DateTime') ?
554
+ $this->_decodeDateTime(substr($content, $content_pos), $tag) :
555
+ $this->_decodeUnixTime(substr($content, $content_pos), $tag);
556
  default:
557
  }
558
 
577
  */
578
  function asn1map($decoded, $mapping, $special = array())
579
  {
580
+ if (!is_array($decoded)) {
581
+ return false;
582
+ }
583
+
584
  if (isset($mapping['explicit']) && is_array($decoded['content'])) {
585
  $decoded = $decoded['content'][0];
586
  }
666
  $childClass = $tempClass = FILE_ASN1_CLASS_UNIVERSAL;
667
  $constant = null;
668
  if (isset($temp['constant'])) {
669
+ $tempClass = $temp['type'];
670
  }
671
  if (isset($child['class'])) {
672
  $childClass = $child['class'];
729
  $temp = $decoded['content'][$i];
730
  $tempClass = FILE_ASN1_CLASS_UNIVERSAL;
731
  if (isset($temp['constant'])) {
732
+ $tempClass = $temp['type'];
733
  }
734
 
735
  foreach ($mapping['children'] as $key => $child) {
790
  return isset($this->oids[$decoded['content']]) ? $this->oids[$decoded['content']] : $decoded['content'];
791
  case FILE_ASN1_TYPE_UTC_TIME:
792
  case FILE_ASN1_TYPE_GENERALIZED_TIME:
793
+ if (class_exists('DateTime')) {
794
+ // for explicitly tagged optional stuff
795
+ if (is_array($decoded['content'])) {
796
+ $decoded['content'] = $decoded['content'][0]['content'];
797
+ }
798
+ // for implicitly tagged optional stuff
799
+ // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist
800
+ // in the wild that OpenSSL decodes without issue so we'll support them as well
801
+ if (!is_object($decoded['content'])) {
802
+ $decoded['content'] = $this->_decodeDateTime($decoded['content'], $decoded['type']);
803
+ }
804
+ if (!$decoded['content']) {
805
+ return false;
806
+ }
807
+ return $decoded['content']->format($this->format);
808
+ } else {
809
+ if (is_array($decoded['content'])) {
810
+ $decoded['content'] = $decoded['content'][0]['content'];
811
+ }
812
+ if (!is_int($decoded['content'])) {
813
+ $decoded['content'] = $this->_decodeUnixTime($decoded['content'], $decoded['type']);
814
+ }
815
+ return @date($this->format, $decoded['content']);
816
  }
 
817
  case FILE_ASN1_TYPE_BIT_STRING:
818
  if (isset($mapping['mapping'])) {
819
  $offset = ord($decoded['content'][0]);
951
  if ($mapping['type'] == FILE_ASN1_TYPE_SET) {
952
  sort($value);
953
  }
954
+ $value = implode('', $value);
955
  break;
956
  }
957
 
1062
  case FILE_ASN1_TYPE_GENERALIZED_TIME:
1063
  $format = $mapping['type'] == FILE_ASN1_TYPE_UTC_TIME ? 'y' : 'Y';
1064
  $format.= 'mdHis';
1065
+ if (!class_exists('DateTime')) {
1066
+ $value = @gmdate($format, strtotime($source)) . 'Z';
1067
+ } else {
1068
+ $date = new DateTime($source, new DateTimeZone('GMT'));
1069
+ $value = $date->format($format) . 'Z';
1070
+ }
1071
  break;
1072
  case FILE_ASN1_TYPE_BIT_STRING:
1073
  if (isset($mapping['mapping'])) {
1109
  $value = base64_decode($source);
1110
  break;
1111
  case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
1112
+ $value = $this->_encodeOID($source);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1113
  break;
1114
  case FILE_ASN1_TYPE_ANY:
1115
  $loc = $this->location;
1209
  }
1210
 
1211
  /**
1212
+ * BER-decode the OID
1213
+ *
1214
+ * Called by _decode_ber()
1215
+ *
1216
+ * @access private
1217
+ * @param string $content
1218
+ * @return string
1219
+ */
1220
+ function _decodeOID($content)
1221
+ {
1222
+ static $eighty;
1223
+ if (!$eighty) {
1224
+ $eighty = new Math_BigInteger(80);
1225
+ }
1226
+
1227
+ $oid = array();
1228
+ $pos = 0;
1229
+ $len = strlen($content);
1230
+ $n = new Math_BigInteger();
1231
+ while ($pos < $len) {
1232
+ $temp = ord($content[$pos++]);
1233
+ $n = $n->bitwise_leftShift(7);
1234
+ $n = $n->bitwise_or(new Math_BigInteger($temp & 0x7F));
1235
+ if (~$temp & 0x80) {
1236
+ $oid[] = $n;
1237
+ $n = new Math_BigInteger();
1238
+ }
1239
+ }
1240
+ $part1 = array_shift($oid);
1241
+ $first = floor(ord($content[0]) / 40);
1242
+ /*
1243
+ "This packing of the first two object identifier components recognizes that only three values are allocated from the root
1244
+ node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1."
1245
+
1246
+ -- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22
1247
+ */
1248
+ if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78)
1249
+ array_unshift($oid, ord($content[0]) % 40);
1250
+ array_unshift($oid, $first);
1251
+ } else {
1252
+ array_unshift($oid, $part1->subtract($eighty));
1253
+ array_unshift($oid, 2);
1254
+ }
1255
+
1256
+ return implode('.', $oid);
1257
+ }
1258
+
1259
+ /**
1260
+ * DER-encode the OID
1261
+ *
1262
+ * Called by _encode_der()
1263
+ *
1264
+ * @access private
1265
+ * @param string $content
1266
+ * @return string
1267
+ */
1268
+ function _encodeOID($source)
1269
+ {
1270
+ static $mask, $zero, $forty;
1271
+ if (!$mask) {
1272
+ $mask = new Math_BigInteger(0x7F);
1273
+ $zero = new Math_BigInteger();
1274
+ $forty = new Math_BigInteger(40);
1275
+ }
1276
+
1277
+ $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
1278
+ if ($oid === false) {
1279
+ user_error('Invalid OID');
1280
+ return false;
1281
+ }
1282
+ $parts = explode('.', $oid);
1283
+ $part1 = array_shift($parts);
1284
+ $part2 = array_shift($parts);
1285
+
1286
+ $first = new Math_BigInteger($part1);
1287
+ $first = $first->multiply($forty);
1288
+ $first = $first->add(new Math_BigInteger($part2));
1289
+
1290
+ array_unshift($parts, $first->toString());
1291
+
1292
+ $value = '';
1293
+ foreach ($parts as $part) {
1294
+ if (!$part) {
1295
+ $temp = "\0";
1296
+ } else {
1297
+ $temp = '';
1298
+ $part = new Math_BigInteger($part);
1299
+ while (!$part->equals($zero)) {
1300
+ $submask = $part->bitwise_and($mask);
1301
+ $submask->setPrecision(8);
1302
+ $temp = (chr(0x80) | $submask->toBytes()) . $temp;
1303
+ $part = $part->bitwise_rightShift(7);
1304
+ }
1305
+ $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
1306
+ }
1307
+ $value.= $temp;
1308
+ }
1309
+
1310
+ return $value;
1311
+ }
1312
+
1313
+ /**
1314
+ * BER-decode the time (using UNIX time)
1315
  *
1316
  * Called by _decode_ber() and in the case of implicit tags asn1map().
1317
  *
1320
  * @param int $tag
1321
  * @return string
1322
  */
1323
+ function _decodeUnixTime($content, $tag)
1324
  {
1325
  /* UTCTime:
1326
  http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
1359
  return @$mktime((int)$hour, (int)$minute, (int)$second, (int)$month, (int)$day, (int)$year) + $timezone;
1360
  }
1361
 
1362
+
1363
+ /**
1364
+ * BER-decode the time (using DateTime)
1365
+ *
1366
+ * Called by _decode_ber() and in the case of implicit tags asn1map().
1367
+ *
1368
+ * @access private
1369
+ * @param string $content
1370
+ * @param int $tag
1371
+ * @return string
1372
+ */
1373
+ function _decodeDateTime($content, $tag)
1374
+ {
1375
+ /* UTCTime:
1376
+ http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
1377
+ http://www.obj-sys.com/asn1tutorial/node15.html
1378
+
1379
+ GeneralizedTime:
1380
+ http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
1381
+ http://www.obj-sys.com/asn1tutorial/node14.html */
1382
+
1383
+ $format = 'YmdHis';
1384
+
1385
+ if ($tag == FILE_ASN1_TYPE_UTC_TIME) {
1386
+ // https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds
1387
+ // element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the
1388
+ // browsers parse it phpseclib ought to too
1389
+ if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) {
1390
+ $content = $matches[1] . '00' . $matches[2];
1391
+ }
1392
+ $prefix = substr($content, 0, 2) >= 50 ? '19' : '20';
1393
+ $content = $prefix . $content;
1394
+ } elseif (strpos($content, '.') !== false) {
1395
+ $format.= '.u';
1396
+ }
1397
+
1398
+ if ($content[strlen($content) - 1] == 'Z') {
1399
+ $content = substr($content, 0, -1) . '+0000';
1400
+ }
1401
+
1402
+ if (strpos($content, '-') !== false || strpos($content, '+') !== false) {
1403
+ $format.= 'O';
1404
+ }
1405
+
1406
+ // error supression isn't necessary as of PHP 7.0:
1407
+ // http://php.net/manual/en/migration70.other-changes.php
1408
+ return @DateTime::createFromFormat($format, $content);
1409
+ }
1410
+
1411
  /**
1412
  * Set the time format
1413
  *
lib/phpseclib/phpseclib/phpseclib/File/X509.php CHANGED
@@ -320,6 +320,22 @@ class File_X509
320
  */
321
  var $challenge;
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  /**
324
  * Default Constructor.
325
  *
@@ -966,6 +982,13 @@ class File_X509
966
  'children' => $AccessDescription
967
  );
968
 
 
 
 
 
 
 
 
969
  $this->SubjectAltName = $GeneralNames;
970
 
971
  $this->PrivateKeyUsagePeriod = array(
@@ -1634,7 +1657,10 @@ class File_X509
1634
  corresponding to the extension type identified by extnID */
1635
  $map = $this->_getMapping($id);
1636
  if (!is_bool($map)) {
1637
- $mapped = $asn1->asn1map($decoded[0], $map, array('iPAddress' => array($this, '_decodeIP')));
 
 
 
1638
  $value = $mapped === false ? $decoded[0] : $mapped;
1639
 
1640
  if ($id == 'id-ce-certificatePolicies') {
@@ -1903,6 +1929,8 @@ class File_X509
1903
  return $this->ExtKeyUsageSyntax;
1904
  case 'id-pe-authorityInfoAccess':
1905
  return $this->AuthorityInfoAccessSyntax;
 
 
1906
  case 'id-ce-subjectAltName':
1907
  return $this->SubjectAltName;
1908
  case 'id-ce-subjectDirectoryAttributes':
@@ -1942,6 +1970,9 @@ class File_X509
1942
  // "Certificate Transparency"
1943
  // https://tools.ietf.org/html/rfc6962
1944
  case '1.3.6.1.4.1.11129.2.4.2':
 
 
 
1945
  return true;
1946
 
1947
  // CSR attributes
@@ -2062,30 +2093,32 @@ class File_X509
2062
  }
2063
 
2064
  if ($names = $this->getExtension('id-ce-subjectAltName')) {
2065
- foreach ($names as $key => $value) {
2066
- $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
2067
- switch ($key) {
2068
- case 'dNSName':
2069
- /* From RFC2818 "HTTP over TLS":
2070
-
2071
- If a subjectAltName extension of type dNSName is present, that MUST
2072
- be used as the identity. Otherwise, the (most specific) Common Name
2073
- field in the Subject field of the certificate MUST be used. Although
2074
- the use of the Common Name is existing practice, it is deprecated and
2075
- Certification Authorities are encouraged to use the dNSName instead. */
2076
- if (preg_match('#^' . $value . '$#', $components['host'])) {
2077
- return true;
2078
- }
2079
- break;
2080
- case 'iPAddress':
2081
- /* From RFC2818 "HTTP over TLS":
2082
-
2083
- In some cases, the URI is specified as an IP address rather than a
2084
- hostname. In this case, the iPAddress subjectAltName must be present
2085
- in the certificate and must exactly match the IP in the URI. */
2086
- if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) {
2087
- return true;
2088
- }
 
 
2089
  }
2090
  }
2091
  return false;
@@ -2104,7 +2137,7 @@ class File_X509
2104
  *
2105
  * If $date isn't defined it is assumed to be the current date.
2106
  *
2107
- * @param int $date optional
2108
  * @access public
2109
  */
2110
  function validateDate($date = null)
@@ -2114,7 +2147,9 @@ class File_X509
2114
  }
2115
 
2116
  if (!isset($date)) {
2117
- $date = time();
 
 
2118
  }
2119
 
2120
  $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
@@ -2124,14 +2159,143 @@ class File_X509
2124
  $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
2125
 
2126
  switch (true) {
2127
- case $date < @strtotime($notBefore):
2128
- case $date > @strtotime($notAfter):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2129
  return false;
2130
  }
2131
 
2132
  return true;
2133
  }
2134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2135
  /**
2136
  * Validate a signature
2137
  *
@@ -2148,11 +2312,30 @@ class File_X509
2148
  * @return mixed
2149
  */
2150
  function validateSignature($caonly = true)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2151
  {
2152
  if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
2153
  return null;
2154
  }
2155
 
 
 
 
 
2156
  /* TODO:
2157
  "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
2158
  -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
@@ -2169,7 +2352,8 @@ class File_X509
2169
  $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
2170
  switch (true) {
2171
  case !is_array($authorityKey):
2172
- case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
 
2173
  $signingCert = $this->currentCert; // working cert
2174
  }
2175
  }
@@ -2186,17 +2370,21 @@ class File_X509
2186
  $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
2187
  switch (true) {
2188
  case !is_array($authorityKey):
2189
- case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
 
 
 
 
2190
  $signingCert = $ca; // working cert
2191
  break 3;
2192
  }
2193
  }
2194
  }
2195
  if (count($this->CAs) == $i && $caonly) {
2196
- return false;
2197
  }
2198
  } elseif (!isset($signingCert) || $caonly) {
2199
- return false;
2200
  }
2201
  return $this->_validateSignature(
2202
  $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
@@ -2232,7 +2420,11 @@ class File_X509
2232
  $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
2233
  switch (true) {
2234
  case !is_array($authorityKey):
2235
- case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
 
 
 
 
2236
  $signingCert = $ca; // working cert
2237
  break 3;
2238
  }
@@ -2302,6 +2494,41 @@ class File_X509
2302
  return true;
2303
  }
2304
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2305
  /**
2306
  * Reformat public keys
2307
  *
@@ -2344,18 +2571,36 @@ class File_X509
2344
  return long2ip($ip);
2345
  }
2346
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2347
  /**
2348
  * Encodes an IP address
2349
  *
2350
  * Takes a human readable IP address into a base64-encoded "blob"
2351
  *
2352
- * @param string $ip
2353
  * @access private
2354
  * @return string
2355
  */
2356
  function _encodeIP($ip)
2357
  {
2358
- return base64_encode(pack('N', ip2long($ip)));
 
 
2359
  }
2360
 
2361
  /**
@@ -2509,6 +2754,10 @@ class File_X509
2509
  }
2510
 
2511
  $dn = array_values($dn);
 
 
 
 
2512
  }
2513
 
2514
  /**
@@ -2753,12 +3002,16 @@ class File_X509
2753
  $value = array_pop($value); // Always strip data type.
2754
  }
2755
  } elseif (is_object($value) && strtolower(get_class($value)) == 'file_asn1_element') {
2756
- $callback = create_function('$x', 'return "\x" . bin2hex($x[0]);');
 
 
 
 
2757
  $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
2758
  }
2759
  $output.= $desc . '=' . $value;
2760
  $result[$desc] = isset($result[$desc]) ?
2761
- array_merge((array) $dn[$prop], array($value)) :
2762
  $value;
2763
  $start = false;
2764
  }
@@ -3385,7 +3638,15 @@ class File_X509
3385
  */
3386
  function _timeField($date)
3387
  {
3388
- $year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
 
 
 
 
 
 
 
 
3389
  if ($year < 2050) {
3390
  return array('utcTime' => $date);
3391
  } else {
@@ -3450,8 +3711,16 @@ class File_X509
3450
  return false;
3451
  }
3452
 
3453
- $startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
3454
- $endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
 
 
 
 
 
 
 
 
3455
  if (!empty($this->serialNumber)) {
3456
  $serialNumber = $this->serialNumber;
3457
  } else {
@@ -3472,7 +3741,7 @@ class File_X509
3472
  'tbsCertificate' =>
3473
  array(
3474
  'version' => 'v3',
3475
- 'serialNumber' => $serialNumber, // $this->setserialNumber()
3476
  'signature' => array('algorithm' => $signatureAlgorithm),
3477
  'issuer' => false, // this is going to be overwritten later
3478
  'validity' => array(
@@ -3724,7 +3993,12 @@ class File_X509
3724
 
3725
  $currentCert = isset($this->currentCert) ? $this->currentCert : null;
3726
  $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
3727
- $thisUpdate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
 
 
 
 
 
3728
 
3729
  if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
3730
  $this->currentCert = $crl->currentCert;
@@ -3876,7 +4150,12 @@ class File_X509
3876
  */
3877
  function setStartDate($date)
3878
  {
3879
- $this->startDate = @date('D, d M Y H:i:s O', @strtotime($date));
 
 
 
 
 
3880
  }
3881
 
3882
  /**
@@ -3900,7 +4179,12 @@ class File_X509
3900
  $temp = chr(FILE_ASN1_TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
3901
  $this->endDate = new File_ASN1_Element($temp);
3902
  } else {
3903
- $this->endDate = @date('D, d M Y H:i:s O', @strtotime($date));
 
 
 
 
 
3904
  }
3905
  }
3906
 
@@ -4110,6 +4394,10 @@ class File_X509
4110
  }
4111
 
4112
  $extensions = array_values($extensions);
 
 
 
 
4113
  return $result;
4114
  }
4115
 
@@ -4640,9 +4928,16 @@ class File_X509
4640
  return false;
4641
  }
4642
 
 
 
 
 
 
 
 
4643
  $i = count($rclist);
4644
  $rclist[] = array('userCertificate' => $serial,
4645
- 'revocationDate' => $this->_timeField(@date('D, d M Y H:i:s O')));
4646
  return $i;
4647
  }
4648
 
320
  */
321
  var $challenge;
322
 
323
+ /**
324
+ * Recursion Limit
325
+ *
326
+ * @var int
327
+ * @access private
328
+ */
329
+ var $recur_limit = 5;
330
+
331
+ /**
332
+ * URL fetch flag
333
+ *
334
+ * @var bool
335
+ * @access private
336
+ */
337
+ var $disable_url_fetch = false;
338
+
339
  /**
340
  * Default Constructor.
341
  *
982
  'children' => $AccessDescription
983
  );
984
 
985
+ $this->SubjectInfoAccessSyntax = array(
986
+ 'type' => FILE_ASN1_TYPE_SEQUENCE,
987
+ 'min' => 1,
988
+ 'max' => -1,
989
+ 'children' => $AccessDescription
990
+ );
991
+
992
  $this->SubjectAltName = $GeneralNames;
993
 
994
  $this->PrivateKeyUsagePeriod = array(
1657
  corresponding to the extension type identified by extnID */
1658
  $map = $this->_getMapping($id);
1659
  if (!is_bool($map)) {
1660
+ $decoder = $id == 'id-ce-nameConstraints' ?
1661
+ array($this, '_decodeNameConstraintIP') :
1662
+ array($this, '_decodeIP');
1663
+ $mapped = $asn1->asn1map($decoded[0], $map, array('iPAddress' => $decoder));
1664
  $value = $mapped === false ? $decoded[0] : $mapped;
1665
 
1666
  if ($id == 'id-ce-certificatePolicies') {
1929
  return $this->ExtKeyUsageSyntax;
1930
  case 'id-pe-authorityInfoAccess':
1931
  return $this->AuthorityInfoAccessSyntax;
1932
+ case 'id-pe-subjectInfoAccess':
1933
+ return $this->SubjectInfoAccessSyntax;
1934
  case 'id-ce-subjectAltName':
1935
  return $this->SubjectAltName;
1936
  case 'id-ce-subjectDirectoryAttributes':
1970
  // "Certificate Transparency"
1971
  // https://tools.ietf.org/html/rfc6962
1972
  case '1.3.6.1.4.1.11129.2.4.2':
1973
+ // "Qualified Certificate statements"
1974
+ // https://tools.ietf.org/html/rfc3739#section-3.2.6
1975
+ case '1.3.6.1.5.5.7.1.3':
1976
  return true;
1977
 
1978
  // CSR attributes
2093
  }
2094
 
2095
  if ($names = $this->getExtension('id-ce-subjectAltName')) {
2096
+ foreach ($names as $name) {
2097
+ foreach ($name as $key => $value) {
2098
+ $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
2099
+ switch ($key) {
2100
+ case 'dNSName':
2101
+ /* From RFC2818 "HTTP over TLS":
2102
+
2103
+ If a subjectAltName extension of type dNSName is present, that MUST
2104
+ be used as the identity. Otherwise, the (most specific) Common Name
2105
+ field in the Subject field of the certificate MUST be used. Although
2106
+ the use of the Common Name is existing practice, it is deprecated and
2107
+ Certification Authorities are encouraged to use the dNSName instead. */
2108
+ if (preg_match('#^' . $value . '$#', $components['host'])) {
2109
+ return true;
2110
+ }
2111
+ break;
2112
+ case 'iPAddress':
2113
+ /* From RFC2818 "HTTP over TLS":
2114
+
2115
+ In some cases, the URI is specified as an IP address rather than a
2116
+ hostname. In this case, the iPAddress subjectAltName must be present
2117
+ in the certificate and must exactly match the IP in the URI. */
2118
+ if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) {
2119
+ return true;
2120
+ }
2121
+ }
2122
  }
2123
  }
2124
  return false;
2137
  *
2138
  * If $date isn't defined it is assumed to be the current date.
2139
  *
2140
+ * @param \DateTime|int|string $date optional
2141
  * @access public
2142
  */
2143
  function validateDate($date = null)
2147
  }
2148
 
2149
  if (!isset($date)) {
2150
+ $date = class_exists('DateTime') ?
2151
+ new DateTime(null, new DateTimeZone(@date_default_timezone_get())) :
2152
+ time();
2153
  }
2154
 
2155
  $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
2159
  $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
2160
 
2161
  switch (true) {
2162
+ case is_string($date) && class_exists('DateTime'):
2163
+ $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
2164
+ case is_object($date) && strtolower(get_class($date)) == 'datetime':
2165
+ $notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
2166
+ $notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
2167
+ break;
2168
+ case is_string($date):
2169
+ $date = @strtotime($date);
2170
+ default:
2171
+ $notBefore = @strtotime($notBefore);
2172
+ $notAfter = @strtotime($notAfter);
2173
+ }
2174
+
2175
+ switch (true) {
2176
+ case $date < $notBefore:
2177
+ case $date > $notAfter:
2178
  return false;
2179
  }
2180
 
2181
  return true;
2182
  }
2183
 
2184
+ /**
2185
+ * Fetches a URL
2186
+ *
2187
+ * @param string $url
2188
+ * @access private
2189
+ * @return bool|string
2190
+ */
2191
+ function _fetchURL($url)
2192
+ {
2193
+ if ($this->disable_url_fetch) {
2194
+ return false;
2195
+ }
2196
+
2197
+ $parts = parse_url($url);
2198
+ $data = '';
2199
+ switch ($parts['scheme']) {
2200
+ case 'http':
2201
+ $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80);
2202
+ if (!$fsock) {
2203
+ return false;
2204
+ }
2205
+ fputs($fsock, "GET $parts[path] HTTP/1.0\r\n");
2206
+ fputs($fsock, "Host: $parts[host]\r\n\r\n");
2207
+ $line = fgets($fsock, 1024);
2208
+ if (strlen($line) < 3) {
2209
+ return false;
2210
+ }
2211
+ preg_match('#HTTP/1.\d (\d{3})#', $line, $temp);
2212
+ if ($temp[1] != '200') {
2213
+ return false;
2214
+ }
2215
+
2216
+ // skip the rest of the headers in the http response
2217
+ while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") {
2218
+ }
2219
+
2220
+ while (!feof($fsock)) {
2221
+ $temp = fread($fsock, 1024);
2222
+ if ($temp === false) {
2223
+ return false;
2224
+ }
2225
+ $data.= $temp;
2226
+ }
2227
+
2228
+ break;
2229
+ //case 'ftp':
2230
+ //case 'ldap':
2231
+ //default:
2232
+ }
2233
+
2234
+ return $data;
2235
+ }
2236
+
2237
+ /**
2238
+ * Validates an intermediate cert as identified via authority info access extension
2239
+ *
2240
+ * See https://tools.ietf.org/html/rfc4325 for more info
2241
+ *
2242
+ * @param bool $caonly
2243
+ * @param int $count
2244
+ * @access private
2245
+ * @return bool
2246
+ */
2247
+ function _testForIntermediate($caonly, $count)
2248
+ {
2249
+ $opts = $this->getExtension('id-pe-authorityInfoAccess');
2250
+ if (!is_array($opts)) {
2251
+ return false;
2252
+ }
2253
+ foreach ($opts as $opt) {
2254
+ if ($opt['accessMethod'] == 'id-ad-caIssuers') {
2255
+ // accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP,
2256
+ // etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325
2257
+ // discusses
2258
+ if (isset($opt['accessLocation']['uniformResourceIdentifier'])) {
2259
+ $url = $opt['accessLocation']['uniformResourceIdentifier'];
2260
+ break;
2261
+ }
2262
+ }
2263
+ }
2264
+
2265
+ if (!isset($url)) {
2266
+ return false;
2267
+ }
2268
+
2269
+ $cert = $this->_fetchURL($url);
2270
+ if (!is_string($cert)) {
2271
+ return false;
2272
+ }
2273
+
2274
+ $parent = new File_X509();
2275
+ $parent->CAs = $this->CAs;
2276
+ /*
2277
+ "Conforming applications that support HTTP or FTP for accessing
2278
+ certificates MUST be able to accept .cer files and SHOULD be able
2279
+ to accept .p7c files." -- https://tools.ietf.org/html/rfc4325
2280
+
2281
+ A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797"
2282
+
2283
+ These are currently unsupported
2284
+ */
2285
+ if (!is_array($parent->loadX509($cert))) {
2286
+ return false;
2287
+ }
2288
+
2289
+ if (!$parent->_validateSignatureCountable($caonly, ++$count)) {
2290
+ return false;
2291
+ }
2292
+
2293
+ $this->CAs[] = $parent->currentCert;
2294
+ //$this->loadCA($cert);
2295
+
2296
+ return true;
2297
+ }
2298
+
2299
  /**
2300
  * Validate a signature
2301
  *
2312
  * @return mixed
2313
  */
2314
  function validateSignature($caonly = true)
2315
+ {
2316
+ return $this->_validateSignatureCountable($caonly, 0);
2317
+ }
2318
+
2319
+ /**
2320
+ * Validate a signature
2321
+ *
2322
+ * Performs said validation whilst keeping track of how many times validation method is called
2323
+ *
2324
+ * @param bool $caonly
2325
+ * @param int $count
2326
+ * @access private
2327
+ * @return mixed
2328
+ */
2329
+ function _validateSignatureCountable($caonly, $count)
2330
  {
2331
  if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
2332
  return null;
2333
  }
2334
 
2335
+ if ($count == $this->recur_limit) {
2336
+ return false;
2337
+ }
2338
+
2339
  /* TODO:
2340
  "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
2341
  -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
2352
  $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
2353
  switch (true) {
2354
  case !is_array($authorityKey):
2355
+ case !$subjectKeyID:
2356
+ case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
2357
  $signingCert = $this->currentCert; // working cert
2358
  }
2359
  }
2370
  $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
2371
  switch (true) {
2372
  case !is_array($authorityKey):
2373
+ case !$subjectKeyID:
2374
+ case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
2375
+ if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
2376
+ break 2; // serial mismatch - check other ca
2377
+ }
2378
  $signingCert = $ca; // working cert
2379
  break 3;
2380
  }
2381
  }
2382
  }
2383
  if (count($this->CAs) == $i && $caonly) {
2384
+ return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
2385
  }
2386
  } elseif (!isset($signingCert) || $caonly) {
2387
+ return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
2388
  }
2389
  return $this->_validateSignature(
2390
  $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
2420
  $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
2421
  switch (true) {
2422
  case !is_array($authorityKey):
2423
+ case !$subjectKeyID:
2424
+ case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
2425
+ if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
2426
+ break 2; // serial mismatch - check other ca
2427
+ }
2428
  $signingCert = $ca; // working cert
2429
  break 3;
2430
  }
2494
  return true;
2495
  }
2496
 
2497
+ /**
2498
+ * Sets the recursion limit
2499
+ *
2500
+ * When validating a signature it may be necessary to download intermediate certs from URI's.
2501
+ * An intermediate cert that linked to itself would result in an infinite loop so to prevent
2502
+ * that we set a recursion limit. A negative number means that there is no recursion limit.
2503
+ *
2504
+ * @param int $count
2505
+ * @access public
2506
+ */
2507
+ function setRecurLimit($count)
2508
+ {
2509
+ $this->recur_limit = $count;
2510
+ }
2511
+
2512
+ /**
2513
+ * Prevents URIs from being automatically retrieved
2514
+ *
2515
+ * @access public
2516
+ */
2517
+ function disableURLFetch()
2518
+ {
2519
+ $this->disable_url_fetch = true;
2520
+ }
2521
+
2522
+ /**
2523
+ * Allows URIs to be automatically retrieved
2524
+ *
2525
+ * @access public
2526
+ */
2527
+ function enableURLFetch()
2528
+ {
2529
+ $this->disable_url_fetch = false;
2530
+ }
2531
+
2532
  /**
2533
  * Reformat public keys
2534
  *
2571
  return long2ip($ip);
2572
  }
2573
 
2574
+ /**
2575
+ * Decodes an IP address in a name constraints extension
2576
+ *
2577
+ * Takes in a base64 encoded "blob" and returns a human readable IP address / mask
2578
+ *
2579
+ * @param string $ip
2580
+ * @access private
2581
+ * @return array
2582
+ */
2583
+ function _decodeNameConstraintIP($ip)
2584
+ {
2585
+ $ip = base64_decode($ip);
2586
+ list(, $ip, $mask) = unpack('N2', $ip);
2587
+ return array(long2ip($ip), long2ip($mask));
2588
+ }
2589
+
2590
  /**
2591
  * Encodes an IP address
2592
  *
2593
  * Takes a human readable IP address into a base64-encoded "blob"
2594
  *
2595
+ * @param string|array $ip
2596
  * @access private
2597
  * @return string
2598
  */
2599
  function _encodeIP($ip)
2600
  {
2601
+ return is_string($ip) ?
2602
+ base64_encode(pack('N', ip2long($ip))) :
2603
+ base64_encode(pack('NN', ip2long($ip[0]), ip2long($ip[1])));
2604
  }
2605
 
2606
  /**
2754
  }
2755
 
2756
  $dn = array_values($dn);
2757
+ // fix for https://bugs.php.net/75433 affecting PHP 7.2
2758
+ if (!isset($dn[0])) {
2759
+ $dn = array_splice($dn, 0, 0);
2760
+ }
2761
  }
2762
 
2763
  /**
3002
  $value = array_pop($value); // Always strip data type.
3003
  }
3004
  } elseif (is_object($value) && strtolower(get_class($value)) == 'file_asn1_element') {
3005
+ // @codingStandardsIgnoreStart
3006
+ $callback = version_compare(PHP_VERSION, '5.3.0') >= 0 ?
3007
+ eval('return function ($x) { return "\x" . bin2hex($x[0]); };') :
3008
+ create_function('$x', 'return "\x" . bin2hex($x[0]);');
3009
+ // @codingStandardsIgnoreEnd
3010
  $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
3011
  }
3012
  $output.= $desc . '=' . $value;
3013
  $result[$desc] = isset($result[$desc]) ?
3014
+ array_merge((array) $result[$desc], array($value)) :
3015
  $value;
3016
  $start = false;
3017
  }
3638
  */
3639
  function _timeField($date)
3640
  {
3641
+ if (is_object($date) && strtolower(get_class($date)) == 'file_asn1_element') {
3642
+ return $date;
3643
+ }
3644
+ if (!class_exists('DateTime')) {
3645
+ $year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
3646
+ } else {
3647
+ $dateObj = new DateTime($date, new DateTimeZone('GMT'));
3648
+ $year = $dateObj->format('Y');
3649
+ }
3650
  if ($year < 2050) {
3651
  return array('utcTime' => $date);
3652
  } else {
3711
  return false;
3712
  }
3713
 
3714
+ if (!class_exists('DateTime')) {
3715
+ $startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
3716
+ $endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
3717
+ } else {
3718
+ $startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
3719
+ $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O');
3720
+
3721
+ $endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get()));
3722
+ $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O');
3723
+ }
3724
  if (!empty($this->serialNumber)) {
3725
  $serialNumber = $this->serialNumber;
3726
  } else {
3741
  'tbsCertificate' =>
3742
  array(
3743
  'version' => 'v3',
3744
+ 'serialNumber' => $serialNumber, // $this->setSerialNumber()
3745
  'signature' => array('algorithm' => $signatureAlgorithm),
3746
  'issuer' => false, // this is going to be overwritten later
3747
  'validity' => array(
3993
 
3994
  $currentCert = isset($this->currentCert) ? $this->currentCert : null;
3995
  $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
3996
+ if (!class_exists('DateTime')) {
3997
+ $thisUpdate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
3998
+ } else {
3999
+ $thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
4000
+ $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O');
4001
+ }
4002
 
4003
  if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
4004
  $this->currentCert = $crl->currentCert;
4150
  */
4151
  function setStartDate($date)
4152
  {
4153
+ if (class_exists('DateTime')) {
4154
+ $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
4155
+ $this->startDate = $date->format('D, d M Y H:i:s O');
4156
+ } else {
4157
+ $this->startDate = @date('D, d M Y H:i:s O', @strtotime($date));
4158
+ }
4159
  }
4160
 
4161
  /**
4179
  $temp = chr(FILE_ASN1_TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
4180
  $this->endDate = new File_ASN1_Element($temp);
4181
  } else {
4182
+ if (class_exists('DateTime')) {
4183
+ $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
4184
+ $this->endDate = $date->format('D, d M Y H:i:s O');
4185
+ } else {
4186
+ $this->endDate = @date('D, d M Y H:i:s O', @strtotime($date));
4187
+ }
4188
  }
4189
  }
4190
 
4394
  }
4395
 
4396
  $extensions = array_values($extensions);
4397
+ // fix for https://bugs.php.net/75433 affecting PHP 7.2
4398
+ if (!isset($extensions[0])) {
4399
+ $extensions = array_splice($extensions, 0, 0);
4400
+ }
4401
  return $result;
4402
  }
4403
 
4928
  return false;
4929
  }
4930
 
4931
+ if (!class_exists('DateTime')) {
4932
+ $revocationDate = @date('D, d M Y H:i:s O');
4933
+ } else {
4934
+ $revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
4935
+ $revocationDate = $revocationDate->format('D, d M Y H:i:s O');
4936
+ }
4937
+
4938
  $i = count($rclist);
4939
  $rclist[] = array('userCertificate' => $serial,
4940
+ 'revocationDate' => $this->_timeField($revocationDate));
4941
  return $i;
4942
  }
4943
 
lib/phpseclib/phpseclib/phpseclib/Math/BigInteger.php CHANGED
@@ -65,7 +65,6 @@
65
  * @author Jim Wigginton <terrafrost@php.net>
66
  * @copyright 2006 Jim Wigginton
67
  * @license http://www.opensource.org/licenses/mit-license.html MIT License
68
- * @link http://pear.php.net/package/Math_BigInteger
69
  */
70
 
71
  /**#@+
@@ -360,8 +359,12 @@ class Math_BigInteger
360
  case 256:
361
  switch (MATH_BIGINTEGER_MODE) {
362
  case MATH_BIGINTEGER_MODE_GMP:
363
- $sign = $this->is_negative ? '-' : '';
364
- $this->value = gmp_init($sign . '0x' . bin2hex($x));
 
 
 
 
365
  break;
366
  case MATH_BIGINTEGER_MODE_BCMATH:
367
  // round $len to the nearest 4 (thanks, DavidMJ!)
@@ -438,6 +441,9 @@ class Math_BigInteger
438
  // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
439
  // [^-0-9].*: find any non-numeric characters and then any characters that follow that
440
  $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
 
 
 
441
 
442
  switch (MATH_BIGINTEGER_MODE) {
443
  case MATH_BIGINTEGER_MODE_GMP:
@@ -546,11 +552,11 @@ class Math_BigInteger
546
  $temp = $comparison < 0 ? $this->add(new Math_BigInteger(1)) : $this->copy();
547
  $bytes = $temp->toBytes();
548
 
549
- if (empty($bytes)) { // eg. if the number we're trying to convert is -1
550
  $bytes = chr(0);
551
  }
552
 
553
- if (ord($bytes[0]) & 0x80) {
554
  $bytes = chr(0) . $bytes;
555
  }
556
 
@@ -563,9 +569,13 @@ class Math_BigInteger
563
  return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
564
  }
565
 
566
- $temp = gmp_strval(gmp_abs($this->value), 16);
567
- $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
568
- $temp = pack('H*', $temp);
 
 
 
 
569
 
570
  return $this->precision > 0 ?
571
  substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
@@ -714,6 +724,7 @@ class Math_BigInteger
714
  }
715
 
716
  $temp = $this->copy();
 
717
  $temp->is_negative = false;
718
 
719
  $divisor = new Math_BigInteger();
@@ -850,7 +861,7 @@ class Math_BigInteger
850
  $opts[] = 'OpenSSL';
851
  }
852
  if (!empty($opts)) {
853
- $engine.= ' (' . implode($opts, ', ') . ')';
854
  }
855
  return array(
856
  'value' => '0x' . $this->toHex(true),
@@ -1576,7 +1587,9 @@ class Math_BigInteger
1576
  $temp_value = array($quotient_value[$q_index]);
1577
  $temp = $temp->multiply($y);
1578
  $temp_value = &$temp->value;
1579
- $temp_value = array_merge($adjust, $temp_value);
 
 
1580
 
1581
  $x = $x->subtract($temp);
1582
 
@@ -2717,7 +2730,14 @@ class Math_BigInteger
2717
  {
2718
  switch (MATH_BIGINTEGER_MODE) {
2719
  case MATH_BIGINTEGER_MODE_GMP:
2720
- return gmp_cmp($this->value, $y->value);
 
 
 
 
 
 
 
2721
  case MATH_BIGINTEGER_MODE_BCMATH:
2722
  return bccomp($this->value, $y->value, 0);
2723
  }
@@ -2897,7 +2917,7 @@ class Math_BigInteger
2897
  switch (MATH_BIGINTEGER_MODE) {
2898
  case MATH_BIGINTEGER_MODE_GMP:
2899
  $temp = new Math_BigInteger();
2900
- $temp->value = gmp_xor($this->value, $x->value);
2901
 
2902
  return $this->_normalize($temp);
2903
  case MATH_BIGINTEGER_MODE_BCMATH:
@@ -2914,6 +2934,7 @@ class Math_BigInteger
2914
 
2915
  $length = max(count($this->value), count($x->value));
2916
  $result = $this->copy();
 
2917
  $result->value = array_pad($result->value, $length, 0);
2918
  $x->value = array_pad($x->value, $length, 0);
2919
 
@@ -2937,7 +2958,7 @@ class Math_BigInteger
2937
  // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
2938
  $temp = $this->toBytes();
2939
  if ($temp == '') {
2940
- return '';
2941
  }
2942
  $pre_msb = decbin(ord($temp[0]));
2943
  $temp = ~$temp;
@@ -3484,7 +3505,7 @@ class Math_BigInteger
3484
  break;
3485
  }
3486
  }
3487
- $s = 26 * $i + $j - 1;
3488
  $r->_rshift($s);
3489
  }
3490
 
@@ -3595,7 +3616,14 @@ class Math_BigInteger
3595
  switch (MATH_BIGINTEGER_MODE) {
3596
  case MATH_BIGINTEGER_MODE_GMP:
3597
  if ($this->bitmask !== false) {
 
 
 
 
3598
  $result->value = gmp_and($result->value, $result->bitmask->value);
 
 
 
3599
  }
3600
 
3601
  return $result;
@@ -3610,6 +3638,7 @@ class Math_BigInteger
3610
  $value = &$result->value;
3611
 
3612
  if (!count($value)) {
 
3613
  return $result;
3614
  }
3615
 
65
  * @author Jim Wigginton <terrafrost@php.net>
66
  * @copyright 2006 Jim Wigginton
67
  * @license http://www.opensource.org/licenses/mit-license.html MIT License
 
68
  */
69
 
70
  /**#@+
359
  case 256:
360
  switch (MATH_BIGINTEGER_MODE) {
361
  case MATH_BIGINTEGER_MODE_GMP:
362
+ $this->value = function_exists('gmp_import') ?
363
+ gmp_import($x) :
364
+ gmp_init('0x' . bin2hex($x));
365
+ if ($this->is_negative) {
366
+ $this->value = gmp_neg($this->value);
367
+ }
368
  break;
369
  case MATH_BIGINTEGER_MODE_BCMATH:
370
  // round $len to the nearest 4 (thanks, DavidMJ!)
441
  // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
442
  // [^-0-9].*: find any non-numeric characters and then any characters that follow that
443
  $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
444
+ if (!strlen($x) || $x == '-') {
445
+ $x = '0';
446
+ }
447
 
448
  switch (MATH_BIGINTEGER_MODE) {
449
  case MATH_BIGINTEGER_MODE_GMP:
552
  $temp = $comparison < 0 ? $this->add(new Math_BigInteger(1)) : $this->copy();
553
  $bytes = $temp->toBytes();
554
 
555
+ if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1
556
  $bytes = chr(0);
557
  }
558
 
559
+ if ($this->precision <= 0 && (ord($bytes[0]) & 0x80)) {
560
  $bytes = chr(0) . $bytes;
561
  }
562
 
569
  return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
570
  }
571
 
572
+ if (function_exists('gmp_export')) {
573
+ $temp = gmp_export($this->value);
574
+ } else {
575
+ $temp = gmp_strval(gmp_abs($this->value), 16);
576
+ $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
577
+ $temp = pack('H*', $temp);
578
+ }
579
 
580
  return $this->precision > 0 ?
581
  substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
724
  }
725
 
726
  $temp = $this->copy();
727
+ $temp->bitmask = false;
728
  $temp->is_negative = false;
729
 
730
  $divisor = new Math_BigInteger();
861
  $opts[] = 'OpenSSL';
862
  }
863
  if (!empty($opts)) {
864
+ $engine.= ' (' . implode('.', $opts) . ')';
865
  }
866
  return array(
867
  'value' => '0x' . $this->toHex(true),
1587
  $temp_value = array($quotient_value[$q_index]);
1588
  $temp = $temp->multiply($y);
1589
  $temp_value = &$temp->value;
1590
+ if (count($temp_value)) {
1591
+ $temp_value = array_merge($adjust, $temp_value);
1592
+ }
1593
 
1594
  $x = $x->subtract($temp);
1595
 
2730
  {
2731
  switch (MATH_BIGINTEGER_MODE) {
2732
  case MATH_BIGINTEGER_MODE_GMP:
2733
+ $r = gmp_cmp($this->value, $y->value);
2734
+ if ($r < -1) {
2735
+ $r = -1;
2736
+ }
2737
+ if ($r > 1) {
2738
+ $r = 1;
2739
+ }
2740
+ return $r;
2741
  case MATH_BIGINTEGER_MODE_BCMATH:
2742
  return bccomp($this->value, $y->value, 0);
2743
  }
2917
  switch (MATH_BIGINTEGER_MODE) {
2918
  case MATH_BIGINTEGER_MODE_GMP:
2919
  $temp = new Math_BigInteger();
2920
+ $temp->value = gmp_xor(gmp_abs($this->value), gmp_abs($x->value));
2921
 
2922
  return $this->_normalize($temp);
2923
  case MATH_BIGINTEGER_MODE_BCMATH:
2934
 
2935
  $length = max(count($this->value), count($x->value));
2936
  $result = $this->copy();
2937
+ $result->is_negative = false;
2938
  $result->value = array_pad($result->value, $length, 0);
2939
  $x->value = array_pad($x->value, $length, 0);
2940
 
2958
  // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
2959
  $temp = $this->toBytes();
2960
  if ($temp == '') {
2961
+ return $this->_normalize(new Math_BigInteger());
2962
  }
2963
  $pre_msb = decbin(ord($temp[0]));
2964
  $temp = ~$temp;
3505
  break;
3506
  }
3507
  }
3508
+ $s = 26 * $i + $j;
3509
  $r->_rshift($s);
3510
  }
3511
 
3616
  switch (MATH_BIGINTEGER_MODE) {
3617
  case MATH_BIGINTEGER_MODE_GMP:
3618
  if ($this->bitmask !== false) {
3619
+ $flip = gmp_cmp($result->value, gmp_init(0)) < 0;
3620
+ if ($flip) {
3621
+ $result->value = gmp_neg($result->value);
3622
+ }
3623
  $result->value = gmp_and($result->value, $result->bitmask->value);
3624
+ if ($flip) {
3625
+ $result->value = gmp_neg($result->value);
3626
+ }
3627
  }
3628
 
3629
  return $result;
3638
  $value = &$result->value;
3639
 
3640
  if (!count($value)) {
3641
+ $result->is_negative = false;
3642
  return $result;
3643
  }
3644
 
lib/phpseclib/phpseclib/phpseclib/Net/SCP.php CHANGED
@@ -180,6 +180,11 @@ class Net_SCP
180
  return false;
181
  }
182
 
 
 
 
 
 
183
  if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
184
  return false;
185
  }
180
  return false;
181
  }
182
 
183
+ if (empty($remote_file)) {
184
+ user_error('remote_file cannot be blank', E_USER_NOTICE);
185
+ return false;
186
+ }
187
+
188
  if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
189
  return false;
190
  }
lib/phpseclib/phpseclib/phpseclib/Net/SFTP.php CHANGED
@@ -150,11 +150,11 @@ class Net_SFTP extends Net_SSH2
150
  * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
151
  * concurrent actions, so it's somewhat academic, here.
152
  *
153
- * @var int
154
  * @see self::_send_sftp_packet()
155
  * @access private
156
  */
157
- var $request_id = false;
158
 
159
  /**
160
  * The Packet Type
@@ -199,7 +199,7 @@ class Net_SFTP extends Net_SSH2
199
  * Current working directory
200
  *
201
  * @var string
202
- * @see self::_realpath()
203
  * @see self::chdir()
204
  * @access private
205
  */
@@ -228,7 +228,7 @@ class Net_SFTP extends Net_SSH2
228
  *
229
  * @see self::getSFTPErrors()
230
  * @see self::getLastSFTPError()
231
- * @var string
232
  * @access private
233
  */
234
  var $sftp_errors = array();
@@ -277,6 +277,29 @@ class Net_SFTP extends Net_SSH2
277
  */
278
  var $sortOptions = array();
279
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  /**
281
  * Default Constructor.
282
  *
@@ -376,7 +399,7 @@ class Net_SFTP extends Net_SSH2
376
  // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
377
  // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
378
  // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
379
- -1 << 31 => 'NET_SFTP_ATTR_EXTENDED'
380
  );
381
  // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
382
  // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
@@ -415,6 +438,9 @@ class Net_SFTP extends Net_SSH2
415
  if (!defined('NET_SFTP_QUEUE_SIZE')) {
416
  define('NET_SFTP_QUEUE_SIZE', 32);
417
  }
 
 
 
418
  }
419
 
420
  /**
@@ -442,7 +468,10 @@ class Net_SFTP extends Net_SSH2
442
  function login($username)
443
  {
444
  $args = func_get_args();
445
- if (!call_user_func_array(array(&$this, '_login'), $args)) {
 
 
 
446
  return false;
447
  }
448
 
@@ -464,7 +493,7 @@ class Net_SFTP extends Net_SSH2
464
 
465
  $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
466
 
467
- $response = $this->_get_channel_packet(NET_SFTP_CHANNEL);
468
  if ($response === false) {
469
  return false;
470
  }
@@ -485,7 +514,7 @@ class Net_SFTP extends Net_SSH2
485
 
486
  $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
487
 
488
- $response = $this->_get_channel_packet(NET_SFTP_CHANNEL);
489
  if ($response === false) {
490
  // from PuTTY's psftp.exe
491
  $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
@@ -509,7 +538,7 @@ class Net_SFTP extends Net_SSH2
509
 
510
  $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
511
 
512
- $response = $this->_get_channel_packet(NET_SFTP_CHANNEL);
513
  if ($response === false) {
514
  return false;
515
  }
@@ -560,7 +589,7 @@ class Net_SFTP extends Net_SSH2
560
  }
561
  */
562
 
563
- $this->request_id = 1;
564
 
565
  /*
566
  A Note on SFTPv4/5/6 support:
@@ -630,6 +659,26 @@ class Net_SFTP extends Net_SSH2
630
  $this->stat_cache = array();
631
  }
632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
633
  /**
634
  * Returns the current directory name
635
  *
@@ -688,13 +737,20 @@ class Net_SFTP extends Net_SSH2
688
  * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns
689
  * the absolute (canonicalized) path.
690
  *
 
 
691
  * @see self::chdir()
 
692
  * @param string $path
693
  * @return mixed
694
  * @access private
695
  */
696
  function _realpath($path)
697
  {
 
 
 
 
698
  if ($this->pwd === false) {
699
  // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
700
  if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
@@ -722,7 +778,7 @@ class Net_SFTP extends Net_SSH2
722
  }
723
  }
724
 
725
- if ($path[0] != '/') {
726
  $path = $this->pwd . '/' . $path;
727
  }
728
 
@@ -847,6 +903,7 @@ class Net_SFTP extends Net_SSH2
847
  }
848
  if (is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $value)))) {
849
  $temp = $this->_nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/');
 
850
  $result = array_merge($result, $temp);
851
  } else {
852
  $result[] = $relativeDir . $value;
@@ -878,7 +935,17 @@ class Net_SFTP extends Net_SSH2
878
  unset($files[$key]);
879
  continue;
880
  }
881
- if ($key != '.' && $key != '..' && is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)))) {
 
 
 
 
 
 
 
 
 
 
882
  $depth++;
883
  $files[$key] = $this->rawlist($dir . '/' . $key, true);
884
  $depth--;
@@ -1161,7 +1228,7 @@ class Net_SFTP extends Net_SSH2
1161
  $temp[$dir] = array();
1162
  }
1163
  if ($i === $max) {
1164
- if (is_object($temp[$dir])) {
1165
  if (!isset($value->stat) && isset($temp[$dir]->stat)) {
1166
  $value->stat = $temp[$dir]->stat;
1167
  }
@@ -1190,6 +1257,9 @@ class Net_SFTP extends Net_SSH2
1190
  $temp = &$this->stat_cache;
1191
  $max = count($dirs) - 1;
1192
  foreach ($dirs as $i => $dir) {
 
 
 
1193
  if ($i === $max) {
1194
  unset($temp[$dir]);
1195
  return true;
@@ -1216,6 +1286,9 @@ class Net_SFTP extends Net_SSH2
1216
 
1217
  $temp = &$this->stat_cache;
1218
  foreach ($dirs as $dir) {
 
 
 
1219
  if (!isset($temp[$dir])) {
1220
  return null;
1221
  }
@@ -1349,7 +1422,7 @@ class Net_SFTP extends Net_SSH2
1349
  /**
1350
  * Returns general information about a file or symbolic link
1351
  *
1352
- * Determines information without calling Net_SFTP::_realpath().
1353
  * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
1354
  *
1355
  * @param string $filename
@@ -1510,7 +1583,7 @@ class Net_SFTP extends Net_SSH2
1510
  return true;
1511
  }
1512
 
1513
- $filename = $this->_realPath($filename);
1514
  // rather than return what the permissions *should* be, we'll return what they actually are. this will also
1515
  // tell us if the file actually exists.
1516
  // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
@@ -1768,9 +1841,6 @@ class Net_SFTP extends Net_SSH2
1768
  }
1769
 
1770
  $dir = $this->_realpath($dir);
1771
- // by not providing any permissions, hopefully the server will use the logged in users umask - their
1772
- // default permissions.
1773
- $attr = $mode == -1 ? "\0\0\0\0" : pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
1774
 
1775
  if ($recursive) {
1776
  $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir));
@@ -1781,12 +1851,12 @@ class Net_SFTP extends Net_SSH2
1781
  for ($i = 0; $i < count($dirs); $i++) {
1782
  $temp = array_slice($dirs, 0, $i + 1);
1783
  $temp = implode('/', $temp);
1784
- $result = $this->_mkdir_helper($temp, $attr);
1785
  }
1786
  return $result;
1787
  }
1788
 
1789
- return $this->_mkdir_helper($dir, $attr);
1790
  }
1791
 
1792
  /**
@@ -1796,9 +1866,10 @@ class Net_SFTP extends Net_SSH2
1796
  * @return bool
1797
  * @access private
1798
  */
1799
- function _mkdir_helper($dir, $attr)
1800
  {
1801
- if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*a*', strlen($dir), $dir, $attr))) {
 
1802
  return false;
1803
  }
1804
 
@@ -1817,6 +1888,10 @@ class Net_SFTP extends Net_SSH2
1817
  return false;
1818
  }
1819
 
 
 
 
 
1820
  return true;
1821
  }
1822
 
@@ -1995,7 +2070,7 @@ class Net_SFTP extends Net_SSH2
1995
 
1996
  if (isset($fp)) {
1997
  $stat = fstat($fp);
1998
- $size = $stat['size'];
1999
 
2000
  if ($local_start >= 0) {
2001
  fseek($fp, $local_start);
@@ -2013,7 +2088,7 @@ class Net_SFTP extends Net_SSH2
2013
  $sftp_packet_size = 4096; // PuTTY uses 4096
2014
  // make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
2015
  $sftp_packet_size-= strlen($handle) + 25;
2016
- $i = 0;
2017
  while ($dataCallback || ($size === 0 || $sent < $size)) {
2018
  if ($dataCallback) {
2019
  $temp = call_user_func($dataCallback, $sftp_packet_size);
@@ -2029,7 +2104,7 @@ class Net_SFTP extends Net_SSH2
2029
 
2030
  $subtemp = $offset + $sent;
2031
  $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
2032
- if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
2033
  if ($mode & NET_SFTP_LOCAL_FILE) {
2034
  fclose($fp);
2035
  }
@@ -2041,8 +2116,9 @@ class Net_SFTP extends Net_SSH2
2041
  }
2042
 
2043
  $i++;
 
2044
 
2045
- if ($i == NET_SFTP_QUEUE_SIZE) {
2046
  if (!$this->_read_put_responses($i)) {
2047
  $i = 0;
2048
  break;
@@ -2144,10 +2220,11 @@ class Net_SFTP extends Net_SSH2
2144
  * @param string $local_file
2145
  * @param int $offset
2146
  * @param int $length
 
2147
  * @return mixed
2148
  * @access public
2149
  */
2150
- function get($remote_file, $local_file = false, $offset = 0, $length = -1)
2151
  {
2152
  if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
2153
  return false;
@@ -2205,7 +2282,7 @@ class Net_SFTP extends Net_SSH2
2205
  $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
2206
 
2207
  $packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
2208
- if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
2209
  if ($fclose_check) {
2210
  fclose($fp);
2211
  }
@@ -2213,6 +2290,9 @@ class Net_SFTP extends Net_SSH2
2213
  }
2214
  $packet = null;
2215
  $read+= $packet_size;
 
 
 
2216
  $i++;
2217
  }
2218
 
@@ -2220,15 +2300,17 @@ class Net_SFTP extends Net_SSH2
2220
  break;
2221
  }
2222
 
 
 
2223
  $clear_responses = false;
2224
  while ($i > 0) {
2225
  $i--;
2226
 
2227
  if ($clear_responses) {
2228
- $this->_get_sftp_packet();
2229
  continue;
2230
  } else {
2231
- $response = $this->_get_sftp_packet();
2232
  }
2233
 
2234
  switch ($this->packet_type) {
@@ -2937,10 +3019,10 @@ class Net_SFTP extends Net_SSH2
2937
  * @return bool
2938
  * @access private
2939
  */
2940
- function _send_sftp_packet($type, $data)
2941
  {
2942
- $packet = $this->request_id !== false ?
2943
- pack('NCNa*', strlen($data) + 5, $type, $this->request_id, $data) :
2944
  pack('NCa*', strlen($data) + 1, $type, $data);
2945
 
2946
  $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
@@ -2965,6 +3047,20 @@ class Net_SFTP extends Net_SSH2
2965
  return $result;
2966
  }
2967
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2968
  /**
2969
  * Receives SFTP Packets
2970
  *
@@ -2978,15 +3074,24 @@ class Net_SFTP extends Net_SSH2
2978
  * @return string
2979
  * @access private
2980
  */
2981
- function _get_sftp_packet()
2982
  {
2983
- $this->curTimeout = false;
 
 
 
 
 
 
 
 
 
2984
 
2985
  $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
2986
 
2987
  // SFTP packet length
2988
  while (strlen($this->packet_buffer) < 4) {
2989
- $temp = $this->_get_channel_packet(NET_SFTP_CHANNEL);
2990
  if (is_bool($temp)) {
2991
  $this->packet_type = false;
2992
  $this->packet_buffer = '';
@@ -3001,9 +3106,16 @@ class Net_SFTP extends Net_SSH2
3001
  $tempLength = $length;
3002
  $tempLength-= strlen($this->packet_buffer);
3003
 
 
 
 
 
 
 
 
3004
  // SFTP packet type and data payload
3005
  while ($tempLength > 0) {
3006
- $temp = $this->_get_channel_packet(NET_SFTP_CHANNEL);
3007
  if (is_bool($temp)) {
3008
  $this->packet_type = false;
3009
  $this->packet_buffer = '';
@@ -3017,8 +3129,8 @@ class Net_SFTP extends Net_SSH2
3017
 
3018
  $this->packet_type = ord($this->_string_shift($this->packet_buffer));
3019
 
3020
- if ($this->request_id !== false) {
3021
- $this->_string_shift($this->packet_buffer, 4); // remove the request id
3022
  $length-= 5; // account for the request id and the packet type
3023
  } else {
3024
  $length-= 1; // account for the packet type
@@ -3041,6 +3153,14 @@ class Net_SFTP extends Net_SSH2
3041
  }
3042
  }
3043
 
 
 
 
 
 
 
 
 
3044
  return $packet;
3045
  }
3046
 
@@ -3071,7 +3191,7 @@ class Net_SFTP extends Net_SSH2
3071
  /**
3072
  * Returns all errors
3073
  *
3074
- * @return string
3075
  * @access public
3076
  */
3077
  function getSFTPErrors()
150
  * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
151
  * concurrent actions, so it's somewhat academic, here.
152
  *
153
+ * @var boolean
154
  * @see self::_send_sftp_packet()
155
  * @access private
156
  */
157
+ var $use_request_id = false;
158
 
159
  /**
160
  * The Packet Type
199
  * Current working directory
200
  *
201
  * @var string
202
+ * @see self::realpath()
203
  * @see self::chdir()
204
  * @access private
205
  */
228
  *
229
  * @see self::getSFTPErrors()
230
  * @see self::getLastSFTPError()
231
+ * @var array
232
  * @access private
233
  */
234
  var $sftp_errors = array();
277
  */
278
  var $sortOptions = array();
279
 
280
+ /**
281
+ * Canonicalization Flag
282
+ *
283
+ * Determines whether or not paths should be canonicalized before being
284
+ * passed on to the remote server.
285
+ *
286
+ * @see self::enablePathCanonicalization()
287
+ * @see self::disablePathCanonicalization()
288
+ * @see self::realpath()
289
+ * @var bool
290
+ * @access private
291
+ */
292
+ var $canonicalize_paths = true;
293
+
294
+ /**
295
+ * Request Buffers
296
+ *
297
+ * @see self::_get_sftp_packet()
298
+ * @var array
299
+ * @access private
300
+ */
301
+ var $requestBuffer = array();
302
+
303
  /**
304
  * Default Constructor.
305
  *
399
  // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
400
  // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
401
  // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
402
+ (-1 << 31) & 0xFFFFFFFF => 'NET_SFTP_ATTR_EXTENDED'
403
  );
404
  // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
405
  // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
438
  if (!defined('NET_SFTP_QUEUE_SIZE')) {
439
  define('NET_SFTP_QUEUE_SIZE', 32);
440
  }
441
+ if (!defined('NET_SFTP_UPLOAD_QUEUE_SIZE')) {
442
+ define('NET_SFTP_UPLOAD_QUEUE_SIZE', 1024);
443
+ }
444
  }
445
 
446
  /**
468
  function login($username)
469
  {
470
  $args = func_get_args();
471
+ $callback = version_compare(PHP_VERSION, '5.3.0') < 0 ?
472
+ array(&$this, 'parent::login') :
473
+ 'parent::login';
474
+ if (!call_user_func_array($callback, $args)) {
475
  return false;
476
  }
477
 
493
 
494
  $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
495
 
496
+ $response = $this->_get_channel_packet(NET_SFTP_CHANNEL, true);
497
  if ($response === false) {
498
  return false;
499
  }
514
 
515
  $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
516
 
517
+ $response = $this->_get_channel_packet(NET_SFTP_CHANNEL, true);
518
  if ($response === false) {
519
  // from PuTTY's psftp.exe
520
  $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
538
 
539
  $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
540
 
541
+ $response = $this->_get_channel_packet(NET_SFTP_CHANNEL, true);
542
  if ($response === false) {
543
  return false;
544
  }
589
  }
590
  */
591
 
592
+ $this->use_request_id = true;
593
 
594
  /*
595
  A Note on SFTPv4/5/6 support:
659
  $this->stat_cache = array();
660
  }
661
 
662
+ /**
663
+ * Enable path canonicalization
664
+ *
665
+ * @access public
666
+ */
667
+ function enablePathCanonicalization()
668
+ {
669
+ $this->canonicalize_paths = true;
670
+ }
671
+
672
+ /**
673
+ * Enable path canonicalization
674
+ *
675
+ * @access public
676
+ */
677
+ function disablePathCanonicalization()
678
+ {
679
+ $this->canonicalize_paths = false;
680
+ }
681
+
682
  /**
683
  * Returns the current directory name
684
  *
737
  * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns
738
  * the absolute (canonicalized) path.
739
  *
740
+ * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is.
741
+ *
742
  * @see self::chdir()
743
+ * @see self::disablePathCanonicalization()
744
  * @param string $path
745
  * @return mixed
746
  * @access private
747
  */
748
  function _realpath($path)
749
  {
750
+ if (!$this->canonicalize_paths) {
751
+ return $path;
752
+ }
753
+
754
  if ($this->pwd === false) {
755
  // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
756
  if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
778
  }
779
  }
780
 
781
+ if (!strlen($path) || $path[0] != '/') {
782
  $path = $this->pwd . '/' . $path;
783
  }
784
 
903
  }
904
  if (is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $value)))) {
905
  $temp = $this->_nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/');
906
+ $temp = is_array($temp) ? $temp : array();
907
  $result = array_merge($result, $temp);
908
  } else {
909
  $result[] = $relativeDir . $value;
935
  unset($files[$key]);
936
  continue;
937
  }
938
+ $is_directory = false;
939
+ if ($key != '.' && $key != '..') {
940
+ if ($this->use_stat_cache) {
941
+ $is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)));
942
+ } else {
943
+ $stat = $this->lstat($dir . '/' . $key);
944
+ $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY;
945
+ }
946
+ }
947
+
948
+ if ($is_directory) {
949
  $depth++;
950
  $files[$key] = $this->rawlist($dir . '/' . $key, true);
951
  $depth--;
1228
  $temp[$dir] = array();
1229
  }
1230
  if ($i === $max) {
1231
+ if (is_object($temp[$dir]) && is_object($value)) {
1232
  if (!isset($value->stat) && isset($temp[$dir]->stat)) {
1233
  $value->stat = $temp[$dir]->stat;
1234
  }
1257
  $temp = &$this->stat_cache;
1258
  $max = count($dirs) - 1;
1259
  foreach ($dirs as $i => $dir) {
1260
+ if (!is_array($temp)) {
1261
+ return false;
1262
+ }
1263
  if ($i === $max) {
1264
  unset($temp[$dir]);
1265
  return true;
1286
 
1287
  $temp = &$this->stat_cache;
1288
  foreach ($dirs as $dir) {
1289
+ if (!is_array($temp)) {
1290
+ return null;
1291
+ }
1292
  if (!isset($temp[$dir])) {
1293
  return null;
1294
  }
1422
  /**
1423
  * Returns general information about a file or symbolic link
1424
  *
1425
+ * Determines information without calling Net_SFTP::realpath().
1426
  * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
1427
  *
1428
  * @param string $filename
1583
  return true;
1584
  }
1585
 
1586
+ $filename = $this->realpath($filename);
1587
  // rather than return what the permissions *should* be, we'll return what they actually are. this will also
1588
  // tell us if the file actually exists.
1589
  // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
1841
  }
1842
 
1843
  $dir = $this->_realpath($dir);
 
 
 
1844
 
1845
  if ($recursive) {
1846
  $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir));
1851
  for ($i = 0; $i < count($dirs); $i++) {
1852
  $temp = array_slice($dirs, 0, $i + 1);
1853
  $temp = implode('/', $temp);
1854
+ $result = $this->_mkdir_helper($temp, $mode);
1855
  }
1856
  return $result;
1857
  }
1858
 
1859
+ return $this->_mkdir_helper($dir, $mode);
1860
  }
1861
 
1862
  /**
1866
  * @return bool
1867
  * @access private
1868
  */
1869
+ function _mkdir_helper($dir, $mode)
1870
  {
1871
+ // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing)
1872
+ if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*a*', strlen($dir), $dir, "\0\0\0\0"))) {
1873
  return false;
1874
  }
1875
 
1888
  return false;
1889
  }
1890
 
1891
+ if ($mode !== -1) {
1892
+ $this->chmod($mode, $dir);
1893
+ }
1894
+
1895
  return true;
1896
  }
1897
 
2070
 
2071
  if (isset($fp)) {
2072
  $stat = fstat($fp);
2073
+ $size = !empty($stat) ? $stat['size'] : 0;
2074
 
2075
  if ($local_start >= 0) {
2076
  fseek($fp, $local_start);
2088
  $sftp_packet_size = 4096; // PuTTY uses 4096
2089
  // make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
2090
  $sftp_packet_size-= strlen($handle) + 25;
2091
+ $i = $j = 0;
2092
  while ($dataCallback || ($size === 0 || $sent < $size)) {
2093
  if ($dataCallback) {
2094
  $temp = call_user_func($dataCallback, $sftp_packet_size);
2104
 
2105
  $subtemp = $offset + $sent;
2106
  $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
2107
+ if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet, $j)) {
2108
  if ($mode & NET_SFTP_LOCAL_FILE) {
2109
  fclose($fp);
2110
  }
2116
  }
2117
 
2118
  $i++;
2119
+ $j++;
2120
 
2121
+ if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) {
2122
  if (!$this->_read_put_responses($i)) {
2123
  $i = 0;
2124
  break;
2220
  * @param string $local_file
2221
  * @param int $offset
2222
  * @param int $length
2223
+ * @param callable|null $progressCallback
2224
  * @return mixed
2225
  * @access public
2226
  */
2227
+ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null)
2228
  {
2229
  if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
2230
  return false;
2282
  $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
2283
 
2284
  $packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
2285
+ if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet, $i)) {
2286
  if ($fclose_check) {
2287
  fclose($fp);
2288
  }
2290
  }
2291
  $packet = null;
2292
  $read+= $packet_size;
2293
+ if (is_callable($progressCallback)) {
2294
+ call_user_func($progressCallback, $read);
2295
+ }
2296
  $i++;
2297
  }
2298
 
2300
  break;
2301
  }
2302
 
2303
+ $packets_sent = $i - 1;
2304
+
2305
  $clear_responses = false;
2306
  while ($i > 0) {
2307
  $i--;
2308
 
2309
  if ($clear_responses) {
2310
+ $this->_get_sftp_packet($packets_sent - $i);
2311
  continue;
2312
  } else {
2313
+ $response = $this->_get_sftp_packet($packets_sent - $i);
2314
  }
2315
 
2316
  switch ($this->packet_type) {
3019
  * @return bool
3020
  * @access private
3021
  */
3022
+ function _send_sftp_packet($type, $data, $request_id = 1)
3023
  {
3024
+ $packet = $this->use_request_id ?
3025
+ pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) :
3026
  pack('NCa*', strlen($data) + 1, $type, $data);
3027
 
3028
  $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
3047
  return $result;
3048
  }
3049
 
3050
+ /**
3051
+ * Resets a connection for re-use
3052
+ *
3053
+ * @param int $reason
3054
+ * @access private
3055
+ */
3056
+ function _reset_connection($reason)
3057
+ {
3058
+ parent::_reset_connection($reason);
3059
+ $this->use_request_id = false;
3060
+ $this->pwd = false;
3061
+ $this->requestBuffer = array();
3062
+ }
3063
+
3064
  /**
3065
  * Receives SFTP Packets
3066
  *
3074
  * @return string
3075
  * @access private
3076
  */
3077
+ function _get_sftp_packet($request_id = null)
3078
  {
3079
+ if (isset($request_id) && isset($this->requestBuffer[$request_id])) {
3080
+ $this->packet_type = $this->requestBuffer[$request_id]['packet_type'];
3081
+ $temp = $this->requestBuffer[$request_id]['packet'];
3082
+ unset($this->requestBuffer[$request_id]);
3083
+ return $temp;
3084
+ }
3085
+
3086
+ // in SSH2.php the timeout is cumulative per function call. eg. exec() will
3087
+ // timeout after 10s. but for SFTP.php it's cumulative per packet
3088
+ $this->curTimeout = $this->timeout;
3089
 
3090
  $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
3091
 
3092
  // SFTP packet length
3093
  while (strlen($this->packet_buffer) < 4) {
3094
+ $temp = $this->_get_channel_packet(NET_SFTP_CHANNEL, true);
3095
  if (is_bool($temp)) {
3096
  $this->packet_type = false;
3097
  $this->packet_buffer = '';
3106
  $tempLength = $length;
3107
  $tempLength-= strlen($this->packet_buffer);
3108
 
3109
+
3110
+ // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h
3111
+ if ($tempLength > 256 * 1024) {
3112
+ user_error('Invalid SFTP packet size');
3113
+ return false;
3114
+ }
3115
+
3116
  // SFTP packet type and data payload
3117
  while ($tempLength > 0) {
3118
+ $temp = $this->_get_channel_packet(NET_SFTP_CHANNEL, true);
3119
  if (is_bool($temp)) {
3120
  $this->packet_type = false;
3121
  $this->packet_buffer = '';
3129
 
3130
  $this->packet_type = ord($this->_string_shift($this->packet_buffer));
3131
 
3132
+ if ($this->use_request_id) {
3133
+ extract(unpack('Npacket_id', $this->_string_shift($this->packet_buffer, 4))); // remove the request id
3134
  $length-= 5; // account for the request id and the packet type
3135
  } else {
3136
  $length-= 1; // account for the packet type
3153
  }
3154
  }
3155
 
3156
+ if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) {
3157
+ $this->requestBuffer[$packet_id] = array(
3158
+ 'packet_type' => $this->packet_type,
3159
+ 'packet' => $packet
3160
+ );
3161
+ return $this->_get_sftp_packet($request_id);
3162
+ }
3163
+
3164
  return $packet;
3165
  }
3166
 
3191
  /**
3192
  * Returns all errors
3193
  *
3194
+ * @return array
3195
  * @access public
3196
  */
3197
  function getSFTPErrors()
lib/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php CHANGED
@@ -197,7 +197,7 @@ class Net_SFTP_Stream
197
 
198
  if ($host[0] == '$') {
199
  $host = substr($host, 1);
200
- global $$host;
201
  if (!is_object($$host) || get_class($$host) != 'Net_SFTP') {
202
  return false;
203
  }
197
 
198
  if ($host[0] == '$') {
199
  $host = substr($host, 1);
200
+ global ${$host};
201
  if (!is_object($$host) || get_class($$host) != 'Net_SFTP') {
202
  return false;
203
  }
lib/phpseclib/phpseclib/phpseclib/Net/SSH1.php CHANGED
@@ -1169,6 +1169,9 @@ class Net_SSH1
1169
 
1170
  while ($length > 0) {
1171
  $temp = fread($this->fsock, $length);
 
 
 
1172
  $raw.= $temp;
1173
  $length-= strlen($temp);
1174
  }
1169
 
1170
  while ($length > 0) {
1171
  $temp = fread($this->fsock, $length);
1172
+ if (strlen($temp) != $length) {
1173
+ return false;
1174
+ }
1175
  $raw.= $temp;
1176
  $length-= strlen($temp);
1177
  }
lib/phpseclib/phpseclib/phpseclib/Net/SSH2.php CHANGED
@@ -96,10 +96,11 @@ define('NET_SSH2_MASK_WINDOW_ADJUST', 0x00000020);
96
  * @see self::_get_channel_packet()
97
  * @access private
98
  */
99
- define('NET_SSH2_CHANNEL_EXEC', 0); // PuTTy uses 0x100
100
- define('NET_SSH2_CHANNEL_SHELL', 1);
101
- define('NET_SSH2_CHANNEL_SUBSYSTEM', 2);
102
- define('NET_SSH2_CHANNEL_AGENT_FORWARD', 3);
 
103
  /**#@-*/
104
 
105
  /**#@+
@@ -122,6 +123,10 @@ define('NET_SSH2_LOG_REALTIME', 3);
122
  * Dumps the content real-time to a file
123
  */
124
  define('NET_SSH2_LOG_REALTIME_FILE', 4);
 
 
 
 
125
  /**#@-*/
126
 
127
  /**#@+
@@ -137,9 +142,12 @@ define('NET_SSH2_READ_SIMPLE', 1);
137
  */
138
  define('NET_SSH2_READ_REGEX', 2);
139
  /**
140
- * Make sure that the log never gets larger than this
 
 
 
141
  */
142
- define('NET_SSH2_LOG_MAX_SIZE', 1024 * 1024);
143
  /**#@-*/
144
 
145
  /**
@@ -206,6 +214,15 @@ class Net_SSH2
206
  */
207
  var $kex_algorithms = false;
208
 
 
 
 
 
 
 
 
 
 
209
  /**
210
  * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
211
  *
@@ -314,6 +331,15 @@ class Net_SSH2
314
  */
315
  var $languages_client_to_server = false;
316
 
 
 
 
 
 
 
 
 
 
317
  /**
318
  * Block Size for Server to Client Encryption
319
  *
@@ -571,6 +597,20 @@ class Net_SSH2
571
  */
572
  var $window_size = 0x7FFFFFFF;
573
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
574
  /**
575
  * Window size, server to client
576
  *
@@ -871,6 +911,62 @@ class Net_SSH2
871
  */
872
  var $agent;
873
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
874
  /**
875
  * Default Constructor.
876
  *
@@ -1013,13 +1109,69 @@ class Net_SSH2
1013
  * CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT
1014
  *
1015
  * @param int $engine
1016
- * @access private
1017
  */
1018
  function setCryptoEngine($engine)
1019
  {
1020
  $this->crypto_engine = $engine;
1021
  }
1022
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1023
  /**
1024
  * Connect to an SSHv2 server
1025
  *
@@ -1051,17 +1203,20 @@ class Net_SSH2
1051
  }
1052
  $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
1053
 
1054
- $this->curTimeout-= $elapsed;
1055
-
1056
- if ($this->curTimeout <= 0) {
1057
- $this->is_timeout = true;
1058
- return false;
 
1059
  }
1060
  }
1061
 
1062
  $this->identifier = $this->_generate_identifier();
1063
 
1064
- fputs($this->fsock, $this->identifier . "\r\n");
 
 
1065
 
1066
  /* According to the SSH2 specs,
1067
 
@@ -1097,11 +1252,15 @@ class Net_SSH2
1097
  $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
1098
  $this->curTimeout-= $elapsed;
1099
  }
1100
-
1101
- $temp.= fgets($this->fsock, 255);
 
 
 
1102
  }
1103
 
1104
  if (feof($this->fsock)) {
 
1105
  user_error('Connection closed by server');
1106
  return false;
1107
  }
@@ -1113,26 +1272,37 @@ class Net_SSH2
1113
 
1114
  $this->server_identifier = trim($temp, "\r\n");
1115
  if (strlen($extra)) {
1116
- $this->errors[] = utf8_decode($extra);
1117
  }
1118
 
1119
- if ($matches[1] != '1.99' && $matches[1] != '2.0') {
1120
  user_error("Cannot connect to SSH $matches[1] servers");
1121
  return false;
1122
  }
1123
 
1124
- $response = $this->_get_binary_packet();
1125
- if ($response === false) {
1126
- user_error('Connection closed by server');
1127
- return false;
1128
  }
1129
 
1130
- if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
1131
- user_error('Expected SSH_MSG_KEXINIT');
1132
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
1133
  }
1134
 
1135
- if (!$this->_key_exchange($response)) {
1136
  return false;
1137
  }
1138
 
@@ -1176,142 +1346,113 @@ class Net_SSH2
1176
  /**
1177
  * Key Exchange
1178
  *
1179
- * @param string $kexinit_payload_server
1180
  * @access private
1181
  */
1182
- function _key_exchange($kexinit_payload_server)
1183
  {
1184
- static $kex_algorithms = array(
1185
- 'diffie-hellman-group1-sha1', // REQUIRED
1186
- 'diffie-hellman-group14-sha1', // REQUIRED
1187
- 'diffie-hellman-group-exchange-sha1', // RFC 4419
1188
- 'diffie-hellman-group-exchange-sha256', // RFC 4419
1189
- );
1190
-
1191
- static $server_host_key_algorithms = array(
1192
- 'ssh-rsa', // RECOMMENDED sign Raw RSA Key
1193
- 'ssh-dss' // REQUIRED sign Raw DSS Key
1194
- );
1195
-
1196
- static $encryption_algorithms = false;
1197
- if ($encryption_algorithms === false) {
1198
- $encryption_algorithms = array(
1199
- // from <http://tools.ietf.org/html/rfc4345#section-4>:
1200
- 'arcfour256',
1201
- 'arcfour128',
1202
-
1203
- //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
1204
-
1205
- // CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
1206
- 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
1207
- 'aes192-ctr', // RECOMMENDED AES with 192-bit key
1208
- 'aes256-ctr', // RECOMMENDED AES with 256-bit key
1209
-
1210
- 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key
1211
- 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key
1212
- 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key
1213
-
1214
- 'aes128-cbc', // RECOMMENDED AES with a 128-bit key
1215
- 'aes192-cbc', // OPTIONAL AES with a 192-bit key
1216
- 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
1217
-
1218
- 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key
1219
- 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key
1220
- 'twofish256-cbc',
1221
- 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc"
1222
- // (this is being retained for historical reasons)
1223
 
1224
- 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode
1225
-
1226
- 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode
1227
-
1228
- '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
1229
-
1230
- '3des-cbc', // REQUIRED three-key 3DES in CBC mode
1231
- //'none' // OPTIONAL no encryption; NOT RECOMMENDED
1232
- );
1233
-
1234
- if (extension_loaded('openssl') && !extension_loaded('mcrypt')) {
1235
- // OpenSSL does not support arcfour256 in any capacity and arcfour128 / arcfour support is limited to
1236
- // instances that do not use continuous buffers
1237
- $encryption_algorithms = array_diff(
1238
- $encryption_algorithms,
1239
- array('arcfour256', 'arcfour128', 'arcfour')
1240
- );
1241
- }
1242
-
1243
- if (phpseclib_resolve_include_path('Crypt/RC4.php') === false) {
1244
- $encryption_algorithms = array_diff(
1245
- $encryption_algorithms,
1246
- array('arcfour256', 'arcfour128', 'arcfour')
1247
- );
1248
- }
1249
- if (phpseclib_resolve_include_path('Crypt/Rijndael.php') === false) {
1250
- $encryption_algorithms = array_diff(
1251
- $encryption_algorithms,
1252
- array('aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', 'aes192-cbc', 'aes256-cbc')
1253
- );
1254
- }
1255
- if (phpseclib_resolve_include_path('Crypt/Twofish.php') === false) {
1256
- $encryption_algorithms = array_diff(
1257
- $encryption_algorithms,
1258
- array('twofish128-ctr', 'twofish192-ctr', 'twofish256-ctr', 'twofish128-cbc', 'twofish192-cbc', 'twofish256-cbc', 'twofish-cbc')
1259
- );
1260
- }
1261
- if (phpseclib_resolve_include_path('Crypt/Blowfish.php') === false) {
1262
- $encryption_algorithms = array_diff(
1263
- $encryption_algorithms,
1264
- array('blowfish-ctr', 'blowfish-cbc')
1265
- );
1266
- }
1267
- if (phpseclib_resolve_include_path('Crypt/TripleDES.php') === false) {
1268
- $encryption_algorithms = array_diff(
1269
- $encryption_algorithms,
1270
- array('3des-ctr', '3des-cbc')
1271
- );
1272
- }
1273
- $encryption_algorithms = array_values($encryption_algorithms);
1274
  }
1275
 
1276
- $mac_algorithms = array(
1277
- // from <http://www.ietf.org/rfc/rfc6668.txt>:
1278
- 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32)
 
 
 
 
 
1279
 
1280
- 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20)
1281
- 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20)
1282
- 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16)
1283
- 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16)
1284
- //'none' // OPTIONAL no MAC; NOT RECOMMENDED
1285
- );
1286
 
1287
- static $compression_algorithms = array(
1288
- 'none' // REQUIRED no compression
1289
- //'zlib' // OPTIONAL ZLIB (LZ77) compression
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1290
  );
1291
 
1292
- // some SSH servers have buggy implementations of some of the above algorithms
1293
- switch ($this->server_identifier) {
1294
- case 'SSH-2.0-SSHD':
1295
- $mac_algorithms = array_values(array_diff(
1296
- $mac_algorithms,
1297
- array('hmac-sha1-96', 'hmac-md5-96')
1298
- ));
1299
- }
1300
 
1301
- static $str_kex_algorithms, $str_server_host_key_algorithms,
1302
- $encryption_algorithms_server_to_client, $mac_algorithms_server_to_client, $compression_algorithms_server_to_client,
1303
- $encryption_algorithms_client_to_server, $mac_algorithms_client_to_server, $compression_algorithms_client_to_server;
 
 
 
1304
 
1305
- if (empty($str_kex_algorithms)) {
1306
- $str_kex_algorithms = implode(',', $kex_algorithms);
1307
- $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
1308
- $encryption_algorithms_server_to_client = $encryption_algorithms_client_to_server = implode(',', $encryption_algorithms);
1309
- $mac_algorithms_server_to_client = $mac_algorithms_client_to_server = implode(',', $mac_algorithms);
1310
- $compression_algorithms_server_to_client = $compression_algorithms_client_to_server = implode(',', $compression_algorithms);
1311
  }
1312
 
1313
- $client_cookie = crypt_random_string(16);
1314
-
1315
  $response = $kexinit_payload_server;
1316
  $this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
1317
  $server_cookie = $this->_string_shift($response, 16);
@@ -1382,51 +1523,21 @@ class Net_SSH2
1382
  extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
1383
  $first_kex_packet_follows = $first_kex_packet_follows != 0;
1384
 
1385
- // the sending of SSH2_MSG_KEXINIT could go in one of two places. this is the second place.
1386
- $kexinit_payload_client = pack(
1387
- 'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
1388
- NET_SSH2_MSG_KEXINIT,
1389
- $client_cookie,
1390
- strlen($str_kex_algorithms),
1391
- $str_kex_algorithms,
1392
- strlen($str_server_host_key_algorithms),
1393
- $str_server_host_key_algorithms,
1394
- strlen($encryption_algorithms_client_to_server),
1395
- $encryption_algorithms_client_to_server,
1396
- strlen($encryption_algorithms_server_to_client),
1397
- $encryption_algorithms_server_to_client,
1398
- strlen($mac_algorithms_client_to_server),
1399
- $mac_algorithms_client_to_server,
1400
- strlen($mac_algorithms_server_to_client),
1401
- $mac_algorithms_server_to_client,
1402
- strlen($compression_algorithms_client_to_server),
1403
- $compression_algorithms_client_to_server,
1404
- strlen($compression_algorithms_server_to_client),
1405
- $compression_algorithms_server_to_client,
1406
- 0,
1407
- '',
1408
- 0,
1409
- '',
1410
- 0,
1411
- 0
1412
- );
1413
-
1414
- if (!$this->_send_binary_packet($kexinit_payload_client)) {
1415
  return false;
1416
  }
1417
- // here ends the second place.
1418
 
1419
  // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
1420
  // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
1421
  // diffie-hellman key exchange as fast as possible
1422
- $decrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_server_to_client);
1423
  $decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
1424
  if ($decryptKeyLength === null) {
1425
  user_error('No compatible server to client encryption algorithms found');
1426
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1427
  }
1428
 
1429
- $encrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_client_to_server);
1430
  $encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
1431
  if ($encryptKeyLength === null) {
1432
  user_error('No compatible client to server encryption algorithms found');
@@ -1436,7 +1547,7 @@ class Net_SSH2
1436
  $keyLength = $decryptKeyLength > $encryptKeyLength ? $decryptKeyLength : $encryptKeyLength;
1437
 
1438
  // through diffie-hellman key exchange a symmetric key is obtained
1439
- $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
1440
  if ($kex_algorithm === false) {
1441
  user_error('No compatible key exchange algorithms found');
1442
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
@@ -1456,9 +1567,11 @@ class Net_SSH2
1456
  if (!$this->_send_binary_packet($packet)) {
1457
  return false;
1458
  }
 
1459
 
1460
  $response = $this->_get_binary_packet();
1461
  if ($response === false) {
 
1462
  user_error('Connection closed by server');
1463
  return false;
1464
  }
@@ -1470,6 +1583,7 @@ class Net_SSH2
1470
  user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP');
1471
  return false;
1472
  }
 
1473
 
1474
  if (strlen($response) < 4) {
1475
  return false;
@@ -1554,12 +1668,17 @@ class Net_SSH2
1554
  $data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
1555
 
1556
  if (!$this->_send_binary_packet($data)) {
 
1557
  user_error('Connection closed by server');
1558
  return false;
1559
  }
 
 
 
1560
 
1561
  $response = $this->_get_binary_packet();
1562
  if ($response === false) {
 
1563
  user_error('Connection closed by server');
1564
  return false;
1565
  }
@@ -1569,9 +1688,15 @@ class Net_SSH2
1569
  extract(unpack('Ctype', $this->_string_shift($response, 1)));
1570
 
1571
  if ($type != $serverKexReplyMessage) {
1572
- user_error('Expected SSH_MSG_KEXDH_REPLY');
 
 
 
1573
  return false;
1574
  }
 
 
 
1575
 
1576
  if (strlen($response) < 4) {
1577
  return false;
@@ -1640,9 +1765,25 @@ class Net_SSH2
1640
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1641
  }
1642
 
1643
- if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) {
1644
- user_error('Server Host Key Algorithm Mismatch');
1645
- return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1646
  }
1647
 
1648
  $packet = pack(
@@ -1657,6 +1798,7 @@ class Net_SSH2
1657
  $response = $this->_get_binary_packet();
1658
 
1659
  if ($response === false) {
 
1660
  user_error('Connection closed by server');
1661
  return false;
1662
  }
@@ -1671,169 +1813,22 @@ class Net_SSH2
1671
  return false;
1672
  }
1673
 
1674
- switch ($encrypt) {
1675
- case '3des-cbc':
1676
- if (!class_exists('Crypt_TripleDES')) {
1677
- include_once 'Crypt/TripleDES.php';
1678
- }
1679
- $this->encrypt = new Crypt_TripleDES();
1680
- // $this->encrypt_block_size = 64 / 8 == the default
1681
- break;
1682
- case '3des-ctr':
1683
- if (!class_exists('Crypt_TripleDES')) {
1684
- include_once 'Crypt/TripleDES.php';
1685
- }
1686
- $this->encrypt = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
1687
- // $this->encrypt_block_size = 64 / 8 == the default
1688
- break;
1689
- case 'aes256-cbc':
1690
- case 'aes192-cbc':
1691
- case 'aes128-cbc':
1692
- if (!class_exists('Crypt_Rijndael')) {
1693
- include_once 'Crypt/Rijndael.php';
1694
- }
1695
- $this->encrypt = new Crypt_Rijndael();
1696
- $this->encrypt_block_size = 16; // eg. 128 / 8
1697
- break;
1698
- case 'aes256-ctr':
1699
- case 'aes192-ctr':
1700
- case 'aes128-ctr':
1701
- if (!class_exists('Crypt_Rijndael')) {
1702
- include_once 'Crypt/Rijndael.php';
1703
- }
1704
- $this->encrypt = new Crypt_Rijndael(CRYPT_RIJNDAEL_MODE_CTR);
1705
- $this->encrypt_block_size = 16; // eg. 128 / 8
1706
- break;
1707
- case 'blowfish-cbc':
1708
- if (!class_exists('Crypt_Blowfish')) {
1709
- include_once 'Crypt/Blowfish.php';
1710
- }
1711
- $this->encrypt = new Crypt_Blowfish();
1712
- $this->encrypt_block_size = 8;
1713
- break;
1714
- case 'blowfish-ctr':
1715
- if (!class_exists('Crypt_Blowfish')) {
1716
- include_once 'Crypt/Blowfish.php';
1717
- }
1718
- $this->encrypt = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
1719
- $this->encrypt_block_size = 8;
1720
- break;
1721
- case 'twofish128-cbc':
1722
- case 'twofish192-cbc':
1723
- case 'twofish256-cbc':
1724
- case 'twofish-cbc':
1725
- if (!class_exists('Crypt_Twofish')) {
1726
- include_once 'Crypt/Twofish.php';
1727
- }
1728
- $this->encrypt = new Crypt_Twofish();
1729
- $this->encrypt_block_size = 16;
1730
- break;
1731
- case 'twofish128-ctr':
1732
- case 'twofish192-ctr':
1733
- case 'twofish256-ctr':
1734
- if (!class_exists('Crypt_Twofish')) {
1735
- include_once 'Crypt/Twofish.php';
1736
- }
1737
- $this->encrypt = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
1738
- $this->encrypt_block_size = 16;
1739
- break;
1740
- case 'arcfour':
1741
- case 'arcfour128':
1742
- case 'arcfour256':
1743
- if (!class_exists('Crypt_RC4')) {
1744
- include_once 'Crypt/RC4.php';
1745
- }
1746
- $this->encrypt = new Crypt_RC4();
1747
- break;
1748
- case 'none':
1749
- //$this->encrypt = new Crypt_Null();
1750
- }
1751
-
1752
- switch ($decrypt) {
1753
- case '3des-cbc':
1754
- if (!class_exists('Crypt_TripleDES')) {
1755
- include_once 'Crypt/TripleDES.php';
1756
- }
1757
- $this->decrypt = new Crypt_TripleDES();
1758
- break;
1759
- case '3des-ctr':
1760
- if (!class_exists('Crypt_TripleDES')) {
1761
- include_once 'Crypt/TripleDES.php';
1762
- }
1763
- $this->decrypt = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
1764
- break;
1765
- case 'aes256-cbc':
1766
- case 'aes192-cbc':
1767
- case 'aes128-cbc':
1768
- if (!class_exists('Crypt_Rijndael')) {
1769
- include_once 'Crypt/Rijndael.php';
1770
- }
1771
- $this->decrypt = new Crypt_Rijndael();
1772
- $this->decrypt_block_size = 16;
1773
- break;
1774
- case 'aes256-ctr':
1775
- case 'aes192-ctr':
1776
- case 'aes128-ctr':
1777
- if (!class_exists('Crypt_Rijndael')) {
1778
- include_once 'Crypt/Rijndael.php';
1779
- }
1780
- $this->decrypt = new Crypt_Rijndael(CRYPT_RIJNDAEL_MODE_CTR);
1781
- $this->decrypt_block_size = 16;
1782
- break;
1783
- case 'blowfish-cbc':
1784
- if (!class_exists('Crypt_Blowfish')) {
1785
- include_once 'Crypt/Blowfish.php';
1786
- }
1787
- $this->decrypt = new Crypt_Blowfish();
1788
- $this->decrypt_block_size = 8;
1789
- break;
1790
- case 'blowfish-ctr':
1791
- if (!class_exists('Crypt_Blowfish')) {
1792
- include_once 'Crypt/Blowfish.php';
1793
- }
1794
- $this->decrypt = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
1795
- $this->decrypt_block_size = 8;
1796
- break;
1797
- case 'twofish128-cbc':
1798
- case 'twofish192-cbc':
1799
- case 'twofish256-cbc':
1800
- case 'twofish-cbc':
1801
- if (!class_exists('Crypt_Twofish')) {
1802
- include_once 'Crypt/Twofish.php';
1803
- }
1804
- $this->decrypt = new Crypt_Twofish();
1805
- $this->decrypt_block_size = 16;
1806
- break;
1807
- case 'twofish128-ctr':
1808
- case 'twofish192-ctr':
1809
- case 'twofish256-ctr':
1810
- if (!class_exists('Crypt_Twofish')) {
1811
- include_once 'Crypt/Twofish.php';
1812
- }
1813
- $this->decrypt = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
1814
- $this->decrypt_block_size = 16;
1815
- break;
1816
- case 'arcfour':
1817
- case 'arcfour128':
1818
- case 'arcfour256':
1819
- if (!class_exists('Crypt_RC4')) {
1820
- include_once 'Crypt/RC4.php';
1821
- }
1822
- $this->decrypt = new Crypt_RC4();
1823
- break;
1824
- case 'none':
1825
- //$this->decrypt = new Crypt_Null();
1826
- }
1827
 
1828
  $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
1829
 
1830
  if ($this->encrypt) {
1831
  if ($this->crypto_engine) {
1832
- $this->encrypt->setEngine($this->crypto_engine);
1833
  }
1834
  $this->encrypt->enableContinuousBuffer();
1835
  $this->encrypt->disablePadding();
1836
 
 
 
 
 
1837
  $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
1838
  while ($this->encrypt_block_size > strlen($iv)) {
1839
  $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
@@ -1845,15 +1840,21 @@ class Net_SSH2
1845
  $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
1846
  }
1847
  $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
 
 
1848
  }
1849
 
1850
  if ($this->decrypt) {
1851
  if ($this->crypto_engine) {
1852
- $this->decrypt->setEngine($this->crypto_engine);
1853
  }
1854
  $this->decrypt->enableContinuousBuffer();
1855
  $this->decrypt->disablePadding();
1856
 
 
 
 
 
1857
  $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
1858
  while ($this->decrypt_block_size > strlen($iv)) {
1859
  $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
@@ -1865,6 +1866,8 @@ class Net_SSH2
1865
  $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
1866
  }
1867
  $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
 
 
1868
  }
1869
 
1870
  /* The "arcfour128" algorithm is the RC4 cipher, as described in
@@ -1881,7 +1884,7 @@ class Net_SSH2
1881
  $this->decrypt->decrypt(str_repeat("\0", 1536));
1882
  }
1883
 
1884
- $mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_client_to_server);
1885
  if ($mac_algorithm === false) {
1886
  user_error('No compatible client to server message authentication algorithms found');
1887
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
@@ -1909,8 +1912,9 @@ class Net_SSH2
1909
  $this->hmac_create = new Crypt_Hash('md5-96');
1910
  $createKeyLength = 16;
1911
  }
 
1912
 
1913
- $mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_server_to_client);
1914
  if ($mac_algorithm === false) {
1915
  user_error('No compatible server to client message authentication algorithms found');
1916
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
@@ -1944,6 +1948,7 @@ class Net_SSH2
1944
  $checkKeyLength = 16;
1945
  $this->hmac_size = 12;
1946
  }
 
1947
 
1948
  $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id);
1949
  while ($createKeyLength > strlen($key)) {
@@ -1957,19 +1962,19 @@ class Net_SSH2
1957
  }
1958
  $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
1959
 
1960
- $compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_server_to_client);
1961
  if ($compression_algorithm === false) {
1962
- user_error('No compatible server to client compression algorithms found');
1963
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1964
  }
1965
- $this->decompress = $compression_algorithm == 'zlib';
1966
 
1967
- $compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_client_to_server);
1968
  if ($compression_algorithm === false) {
1969
- user_error('No compatible client to server compression algorithms found');
1970
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1971
  }
1972
- $this->compress = $compression_algorithm == 'zlib';
1973
 
1974
  return true;
1975
  }
@@ -1983,6 +1988,10 @@ class Net_SSH2
1983
  */
1984
  function _encryption_algorithm_to_key_size($algorithm)
1985
  {
 
 
 
 
1986
  switch ($algorithm) {
1987
  case 'none':
1988
  return 0;
@@ -2013,6 +2022,100 @@ class Net_SSH2
2013
  return null;
2014
  }
2015
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2016
  /**
2017
  * Login
2018
  *
@@ -2028,6 +2131,16 @@ class Net_SSH2
2028
  function login($username)
2029
  {
2030
  $args = func_get_args();
 
 
 
 
 
 
 
 
 
 
2031
  return call_user_func_array(array(&$this, '_login'), $args);
2032
  }
2033
 
@@ -2092,6 +2205,14 @@ class Net_SSH2
2092
 
2093
  $response = $this->_get_binary_packet();
2094
  if ($response === false) {
 
 
 
 
 
 
 
 
2095
  user_error('Connection closed by server');
2096
  return false;
2097
  }
@@ -2148,6 +2269,7 @@ class Net_SSH2
2148
 
2149
  $response = $this->_get_binary_packet();
2150
  if ($response === false) {
 
2151
  user_error('Connection closed by server');
2152
  return false;
2153
  }
@@ -2206,6 +2328,7 @@ class Net_SSH2
2206
 
2207
  $response = $this->_get_binary_packet();
2208
  if ($response === false) {
 
2209
  user_error('Connection closed by server');
2210
  return false;
2211
  }
@@ -2217,14 +2340,12 @@ class Net_SSH2
2217
 
2218
  switch ($type) {
2219
  case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed
2220
- if (defined('NET_SSH2_LOGGING')) {
2221
- $this->message_number_log[count($this->message_number_log) - 1] = 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ';
2222
- }
2223
  if (strlen($response) < 4) {
2224
  return false;
2225
  }
2226
  extract(unpack('Nlength', $this->_string_shift($response, 4)));
2227
- $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . utf8_decode($this->_string_shift($response, $length));
2228
  return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
2229
  case NET_SSH2_MSG_USERAUTH_FAILURE:
2230
  // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
@@ -2306,6 +2427,7 @@ class Net_SSH2
2306
  } else {
2307
  $orig = $response = $this->_get_binary_packet();
2308
  if ($response === false) {
 
2309
  user_error('Connection closed by server');
2310
  return false;
2311
  }
@@ -2369,12 +2491,8 @@ class Net_SSH2
2369
  // see http://tools.ietf.org/html/rfc4256#section-3.2
2370
  if (strlen($this->last_interactive_response)) {
2371
  $this->last_interactive_response = '';
2372
- } elseif (defined('NET_SSH2_LOGGING')) {
2373
- $this->message_number_log[count($this->message_number_log) - 1] = str_replace(
2374
- 'UNKNOWN',
2375
- 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
2376
- $this->message_number_log[count($this->message_number_log) - 1]
2377
- );
2378
  }
2379
 
2380
  if (!count($responses) && $num_prompts) {
@@ -2397,13 +2515,7 @@ class Net_SSH2
2397
  return false;
2398
  }
2399
 
2400
- if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {
2401
- $this->message_number_log[count($this->message_number_log) - 1] = str_replace(
2402
- 'UNKNOWN',
2403
- 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE',
2404
- $this->message_number_log[count($this->message_number_log) - 1]
2405
- );
2406
- }
2407
 
2408
  /*
2409
  After receiving the response, the server MUST send either an
@@ -2475,6 +2587,21 @@ class Net_SSH2
2475
  $publickey['n']
2476
  );
2477
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2478
  $part1 = pack(
2479
  'CNa*Na*Na*',
2480
  NET_SSH2_MSG_USERAUTH_REQUEST,
@@ -2485,7 +2612,7 @@ class Net_SSH2
2485
  strlen('publickey'),
2486
  'publickey'
2487
  );
2488
- $part2 = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey), $publickey);
2489
 
2490
  $packet = $part1 . chr(0) . $part2;
2491
  if (!$this->_send_binary_packet($packet)) {
@@ -2494,6 +2621,7 @@ class Net_SSH2
2494
 
2495
  $response = $this->_get_binary_packet();
2496
  if ($response === false) {
 
2497
  user_error('Connection closed by server');
2498
  return false;
2499
  }
@@ -2514,19 +2642,14 @@ class Net_SSH2
2514
  case NET_SSH2_MSG_USERAUTH_PK_OK:
2515
  // we'll just take it on faith that the public key blob and the public key algorithm name are as
2516
  // they should be
2517
- if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {
2518
- $this->message_number_log[count($this->message_number_log) - 1] = str_replace(
2519
- 'UNKNOWN',
2520
- 'NET_SSH2_MSG_USERAUTH_PK_OK',
2521
- $this->message_number_log[count($this->message_number_log) - 1]
2522
- );
2523
- }
2524
  }
2525
 
2526
  $packet = $part1 . chr(1) . $part2;
2527
  $privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
 
2528
  $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
2529
- $signature = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($signature), $signature);
2530
  $packet.= pack('Na*', strlen($signature), $signature);
2531
 
2532
  if (!$this->_send_binary_packet($packet)) {
@@ -2535,6 +2658,7 @@ class Net_SSH2
2535
 
2536
  $response = $this->_get_binary_packet();
2537
  if ($response === false) {
 
2538
  user_error('Connection closed by server');
2539
  return false;
2540
  }
@@ -2661,6 +2785,7 @@ class Net_SSH2
2661
 
2662
  $response = $this->_get_binary_packet();
2663
  if ($response === false) {
 
2664
  user_error('Connection closed by server');
2665
  return false;
2666
  }
@@ -2801,6 +2926,7 @@ class Net_SSH2
2801
 
2802
  $response = $this->_get_binary_packet();
2803
  if ($response === false) {
 
2804
  user_error('Connection closed by server');
2805
  return false;
2806
  }
@@ -2893,7 +3019,7 @@ class Net_SSH2
2893
  * @see self::write()
2894
  * @param string $expect
2895
  * @param int $mode
2896
- * @return string
2897
  * @access public
2898
  */
2899
  function read($expect = '', $mode = NET_SSH2_READ_SIMPLE)
@@ -2913,6 +3039,10 @@ class Net_SSH2
2913
 
2914
  $channel = $this->_get_interactive_channel();
2915
 
 
 
 
 
2916
  $match = $expect;
2917
  while (true) {
2918
  if ($mode == NET_SSH2_READ_REGEX) {
@@ -3112,26 +3242,107 @@ class Net_SSH2
3112
  }
3113
 
3114
  /**
3115
- * Gets Binary Packets
3116
  *
3117
- * See '6. Binary Packet Protocol' of rfc4253 for more info.
3118
  *
3119
- * @see self::_send_binary_packet()
3120
- * @return string
3121
- * @access private
3122
  */
3123
- function _get_binary_packet()
3124
  {
3125
- if (!is_resource($this->fsock) || feof($this->fsock)) {
3126
- user_error('Connection closed prematurely');
3127
- $this->bitmap = 0;
 
3128
  return false;
3129
  }
3130
 
3131
- $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
3132
- $raw = fread($this->fsock, $this->decrypt_block_size);
 
 
 
 
 
 
 
 
 
3133
 
3134
- if (!strlen($raw)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3135
  return '';
3136
  }
3137
 
@@ -3154,6 +3365,11 @@ class Net_SSH2
3154
  // "implementations SHOULD check that the packet length is reasonable"
3155
  // PuTTY uses 0x9000 as the actual max packet size and so to shall we
3156
  if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
 
 
 
 
 
3157
  user_error('Invalid size');
3158
  return false;
3159
  }
@@ -3162,13 +3378,14 @@ class Net_SSH2
3162
  while ($remaining_length > 0) {
3163
  $temp = fread($this->fsock, $remaining_length);
3164
  if ($temp === false || feof($this->fsock)) {
3165
- user_error('Error reading from socket');
3166
  $this->bitmap = 0;
 
3167
  return false;
3168
  }
3169
  $buffer.= $temp;
3170
  $remaining_length-= strlen($temp);
3171
  }
 
3172
  $stop = strtok(microtime(), ' ') + strtok('');
3173
  if (strlen($buffer)) {
3174
  $raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
@@ -3180,8 +3397,8 @@ class Net_SSH2
3180
  if ($this->hmac_check !== false) {
3181
  $hmac = fread($this->fsock, $this->hmac_size);
3182
  if ($hmac === false || strlen($hmac) != $this->hmac_size) {
3183
- user_error('Error reading socket');
3184
  $this->bitmap = 0;
 
3185
  return false;
3186
  } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
3187
  user_error('Invalid HMAC');
@@ -3204,7 +3421,7 @@ class Net_SSH2
3204
  $this->last_packet = $current;
3205
  }
3206
 
3207
- return $this->_filter($payload);
3208
  }
3209
 
3210
  /**
@@ -3216,7 +3433,7 @@ class Net_SSH2
3216
  * @return string
3217
  * @access private
3218
  */
3219
- function _filter($payload)
3220
  {
3221
  switch (ord($payload[0])) {
3222
  case NET_SSH2_MSG_DISCONNECT:
@@ -3225,11 +3442,11 @@ class Net_SSH2
3225
  return false;
3226
  }
3227
  extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
3228
- $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode($this->_string_shift($payload, $length));
3229
  $this->bitmap = 0;
3230
  return false;
3231
  case NET_SSH2_MSG_IGNORE:
3232
- $payload = $this->_get_binary_packet();
3233
  break;
3234
  case NET_SSH2_MSG_DEBUG:
3235
  $this->_string_shift($payload, 2);
@@ -3237,18 +3454,19 @@ class Net_SSH2
3237
  return false;
3238
  }
3239
  extract(unpack('Nlength', $this->_string_shift($payload, 4)));
3240
- $this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode($this->_string_shift($payload, $length));
3241
- $payload = $this->_get_binary_packet();
3242
  break;
3243
  case NET_SSH2_MSG_UNIMPLEMENTED:
3244
  return false;
3245
  case NET_SSH2_MSG_KEXINIT:
3246
  if ($this->session_id !== false) {
 
3247
  if (!$this->_key_exchange($payload)) {
3248
  $this->bitmap = 0;
3249
  return false;
3250
  }
3251
- $payload = $this->_get_binary_packet();
3252
  }
3253
  }
3254
 
@@ -3259,13 +3477,24 @@ class Net_SSH2
3259
  return false;
3260
  }
3261
  extract(unpack('Nlength', $this->_string_shift($payload, 4)));
3262
- $this->banner_message = utf8_decode($this->_string_shift($payload, $length));
3263
  $payload = $this->_get_binary_packet();
3264
  }
3265
 
3266
  // only called when we've already logged in
3267
  if (($this->bitmap & NET_SSH2_MASK_CONNECTED) && $this->isAuthenticated()) {
3268
  switch (ord($payload[0])) {
 
 
 
 
 
 
 
 
 
 
 
3269
  case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
3270
  if (strlen($payload) < 4) {
3271
  return false;
@@ -3277,7 +3506,7 @@ class Net_SSH2
3277
  return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
3278
  }
3279
 
3280
- $payload = $this->_get_binary_packet();
3281
  break;
3282
  case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
3283
  $this->_string_shift($payload, 1);
@@ -3340,7 +3569,7 @@ class Net_SSH2
3340
  return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
3341
  }
3342
  }
3343
- $payload = $this->_get_binary_packet();
3344
  break;
3345
  case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
3346
  $this->_string_shift($payload, 1);
@@ -3351,7 +3580,7 @@ class Net_SSH2
3351
  extract(unpack('Nwindow_size', $this->_string_shift($payload, 4)));
3352
  $this->window_size_client_to_server[$channel]+= $window_size;
3353
 
3354
- $payload = ($this->bitmap & NET_SSH2_MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet();
3355
  }
3356
  }
3357
 
@@ -3450,39 +3679,50 @@ class Net_SSH2
3450
  }
3451
 
3452
  while (true) {
3453
- if ($this->curTimeout) {
3454
- if ($this->curTimeout < 0) {
3455
- $this->is_timeout = true;
3456
- return true;
3457
- }
3458
-
3459
  $read = array($this->fsock);
3460
  $write = $except = null;
3461
 
3462
- $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
3463
- $sec = floor($this->curTimeout);
3464
- $usec = 1000000 * ($this->curTimeout - $sec);
3465
- // on windows this returns a "Warning: Invalid CRT parameters detected" error
3466
- if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
3467
- $this->is_timeout = true;
3468
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3469
  }
3470
- $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
3471
- $this->curTimeout-= $elapsed;
3472
- }
3473
 
3474
- $response = $this->_get_binary_packet();
3475
- if ($response === false) {
3476
- user_error('Connection closed by server');
3477
- return false;
 
 
3478
  }
 
3479
  if ($client_channel == -1 && $response === true) {
3480
  return true;
3481
  }
3482
- if (!strlen($response)) {
3483
- return '';
3484
- }
3485
-
3486
  if (!strlen($response)) {
3487
  return false;
3488
  }
@@ -3503,11 +3743,89 @@ class Net_SSH2
3503
 
3504
  // resize the window, if appropriate
3505
  if ($this->window_size_server_to_client[$channel] < 0) {
3506
- $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_size);
 
 
3507
  if (!$this->_send_binary_packet($packet)) {
3508
  return false;
3509
  }
3510
- $this->window_size_server_to_client[$channel]+= $this->window_size;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3511
  }
3512
 
3513
  switch ($this->channel_status[$channel]) {
@@ -3592,78 +3910,8 @@ class Net_SSH2
3592
  }
3593
  $this->channel_buffers[$channel][] = $data;
3594
  break;
3595
- case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
3596
- /*
3597
- if ($client_channel == NET_SSH2_CHANNEL_EXEC) {
3598
- $this->_send_channel_packet($client_channel, chr(0));
3599
- }
3600
- */
3601
- // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
3602
- if (strlen($response) < 8) {
3603
- return false;
3604
- }
3605
- extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8)));
3606
- $data = $this->_string_shift($response, $length);
3607
- $this->stdErrorLog.= $data;
3608
- if ($skip_extended || $this->quiet_mode) {
3609
- break;
3610
- }
3611
- if ($client_channel == $channel) {
3612
- return $data;
3613
- }
3614
- if (!isset($this->channel_buffers[$channel])) {
3615
- $this->channel_buffers[$channel] = array();
3616
- }
3617
- $this->channel_buffers[$channel][] = $data;
3618
- break;
3619
- case NET_SSH2_MSG_CHANNEL_REQUEST:
3620
- if (strlen($response) < 4) {
3621
- return false;
3622
- }
3623
- extract(unpack('Nlength', $this->_string_shift($response, 4)));
3624
- $value = $this->_string_shift($response, $length);
3625
- switch ($value) {
3626
- case 'exit-signal':
3627
- $this->_string_shift($response, 1);
3628
- if (strlen($response) < 4) {
3629
- return false;
3630
- }
3631
- extract(unpack('Nlength', $this->_string_shift($response, 4)));
3632
- $this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);
3633
- $this->_string_shift($response, 1);
3634
- if (strlen($response) < 4) {
3635
- return false;
3636
- }
3637
- extract(unpack('Nlength', $this->_string_shift($response, 4)));
3638
- if ($length) {
3639
- $this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);
3640
- }
3641
-
3642
- $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel]));
3643
- $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
3644
-
3645
- $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF;
3646
-
3647
- break;
3648
- case 'exit-status':
3649
- if (strlen($response) < 5) {
3650
- return false;
3651
- }
3652
- extract(unpack('Cfalse/Nexit_status', $this->_string_shift($response, 5)));
3653
- $this->exit_status = $exit_status;
3654
-
3655
- // "The client MAY ignore these messages."
3656
- // -- http://tools.ietf.org/html/rfc4254#section-6.10
3657
-
3658
- break;
3659
- default:
3660
- // "Some systems may not implement signals, in which case they SHOULD ignore this message."
3661
- // -- http://tools.ietf.org/html/rfc4254#section-6.9
3662
- break;
3663
- }
3664
- break;
3665
  case NET_SSH2_MSG_CHANNEL_CLOSE:
3666
- $this->curTimeout = 0;
3667
 
3668
  if ($this->bitmap & NET_SSH2_MASK_SHELL) {
3669
  $this->bitmap&= ~NET_SSH2_MASK_SHELL;
@@ -3699,8 +3947,8 @@ class Net_SSH2
3699
  function _send_binary_packet($data, $logged = null)
3700
  {
3701
  if (!is_resource($this->fsock) || feof($this->fsock)) {
3702
- user_error('Connection closed prematurely');
3703
  $this->bitmap = 0;
 
3704
  return false;
3705
  }
3706
 
@@ -3892,11 +4140,15 @@ class Net_SSH2
3892
 
3893
  $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
3894
 
3895
- $this->curTimeout = 0;
3896
 
3897
  while (!is_bool($this->_get_channel_packet($client_channel))) {
3898
  }
3899
 
 
 
 
 
3900
  if ($want_reply) {
3901
  $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
3902
  }
@@ -3918,10 +4170,14 @@ class Net_SSH2
3918
  if ($this->bitmap & NET_SSH2_MASK_CONNECTED) {
3919
  $data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, '');
3920
  $this->_send_binary_packet($data);
3921
- $this->bitmap = 0;
 
 
 
3922
  fclose($this->fsock);
3923
- return false;
3924
  }
 
 
3925
  }
3926
 
3927
  /**
@@ -4242,6 +4498,294 @@ class Net_SSH2
4242
  return $this->languages_client_to_server;
4243
  }
4244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4245
  /**
4246
  * Returns the banner message.
4247
  *
@@ -4361,6 +4905,8 @@ class Net_SSH2
4361
 
4362
  break;
4363
  case 'ssh-rsa':
 
 
4364
  if (strlen($server_public_host_key) < 4) {
4365
  return false;
4366
  }
@@ -4387,6 +4933,18 @@ class Net_SSH2
4387
  }
4388
 
4389
  $rsa = new Crypt_RSA();
 
 
 
 
 
 
 
 
 
 
 
 
4390
  $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
4391
  $rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
4392
  if (!$rsa->verify($this->exchange_hash, $signature)) {
@@ -4415,7 +4973,30 @@ class Net_SSH2
4415
  $s = $s->modPow($e, $n);
4416
  $s = $s->toBytes();
4417
 
4418
- $h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->exchange_hash));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4419
  $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
4420
 
4421
  if ($s != $h) {
@@ -4501,4 +5082,22 @@ class Net_SSH2
4501
  $this->windowColumns = $columns;
4502
  $this->windowRows = $rows;
4503
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4504
  }
96
  * @see self::_get_channel_packet()
97
  * @access private
98
  */
99
+ define('NET_SSH2_CHANNEL_EXEC', 1); // PuTTy uses 0x100
100
+ define('NET_SSH2_CHANNEL_SHELL', 2);
101
+ define('NET_SSH2_CHANNEL_SUBSYSTEM', 3);
102
+ define('NET_SSH2_CHANNEL_AGENT_FORWARD', 4);
103
+ define('NET_SSH2_CHANNEL_KEEP_ALIVE', 5);
104
  /**#@-*/
105
 
106
  /**#@+
123
  * Dumps the content real-time to a file
124
  */
125
  define('NET_SSH2_LOG_REALTIME_FILE', 4);
126
+ /**
127
+ * Make sure that the log never gets larger than this
128
+ */
129
+ define('NET_SSH2_LOG_MAX_SIZE', 1024 * 1024);
130
  /**#@-*/
131
 
132
  /**#@+
142
  */
143
  define('NET_SSH2_READ_REGEX', 2);
144
  /**
145
+ * Returns whenever a data packet is received.
146
+ *
147
+ * Some data packets may only contain a single character so it may be necessary
148
+ * to call read() multiple times when using this option
149
  */
150
+ define('NET_SSH2_READ_NEXT', 3);
151
  /**#@-*/
152
 
153
  /**
214
  */
215
  var $kex_algorithms = false;
216
 
217
+ /**
218
+ * Key Exchange Algorithm
219
+ *
220
+ * @see self::getMethodsNegotiated()
221
+ * @var string|false
222
+ * @access private
223
+ */
224
+ var $kex_algorithm = false;
225
+
226
  /**
227
  * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
228
  *
331
  */
332
  var $languages_client_to_server = false;
333
 
334
+ /**
335
+ * Preferred Algorithms
336
+ *
337
+ * @see self::setPreferredAlgorithms()
338
+ * @var array
339
+ * @access private
340
+ */
341
+ var $preferred = array();
342
+
343
  /**
344
  * Block Size for Server to Client Encryption
345
  *
597
  */
598
  var $window_size = 0x7FFFFFFF;
599
 
600
+ /**
601
+ * What we resize the window to
602
+ *
603
+ * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes.
604
+ * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so
605
+ * we'll just do what PuTTY does
606
+ *
607
+ * @var int
608
+ * @see self::_send_channel_packet()
609
+ * @see self::exec()
610
+ * @access private
611
+ */
612
+ var $window_resize = 0x40000000;
613
+
614
  /**
615
  * Window size, server to client
616
  *
911
  */
912
  var $agent;
913
 
914
+ /**
915
+ * Send the identification string first?
916
+ *
917
+ * @var bool
918
+ * @access private
919
+ */
920
+ var $send_id_string_first = true;
921
+
922
+ /**
923
+ * Send the key exchange initiation packet first?
924
+ *
925
+ * @var bool
926
+ * @access private
927
+ */
928
+ var $send_kex_first = true;
929
+
930
+ /**
931
+ * Some versions of OpenSSH incorrectly calculate the key size
932
+ *
933
+ * @var bool
934
+ * @access private
935
+ */
936
+ var $bad_key_size_fix = false;
937
+
938
+ /**
939
+ * Should we try to re-connect to re-establish keys?
940
+ *
941
+ * @var bool
942
+ * @access private
943
+ */
944
+ var $retry_connect = false;
945
+
946
+ /**
947
+ * Binary Packet Buffer
948
+ *
949
+ * @var string|false
950
+ * @access private
951
+ */
952
+ var $binary_packet_buffer = false;
953
+
954
+ /**
955
+ * Preferred Signature Format
956
+ *
957
+ * @var string|false
958
+ * @access private
959
+ */
960
+ var $preferred_signature_format = false;
961
+
962
+ /**
963
+ * Authentication Credentials
964
+ *
965
+ * @var array
966
+ * @access private
967
+ */
968
+ var $auth = array();
969
+
970
  /**
971
  * Default Constructor.
972
  *
1109
  * CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT
1110
  *
1111
  * @param int $engine
1112
+ * @access public
1113
  */
1114
  function setCryptoEngine($engine)
1115
  {
1116
  $this->crypto_engine = $engine;
1117
  }
1118
 
1119
+ /**
1120
+ * Send Identification String First
1121
+ *
1122
+ * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
1123
+ * both sides MUST send an identification string". It does not say which side sends it first. In
1124
+ * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
1125
+ *
1126
+ * @access public
1127
+ */
1128
+ function sendIdentificationStringFirst()
1129
+ {
1130
+ $this->send_id_string_first = true;
1131
+ }
1132
+
1133
+ /**
1134
+ * Send Identification String Last
1135
+ *
1136
+ * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
1137
+ * both sides MUST send an identification string". It does not say which side sends it first. In
1138
+ * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
1139
+ *
1140
+ * @access public
1141
+ */
1142
+ function sendIdentificationStringLast()
1143
+ {
1144
+ $this->send_id_string_first = false;
1145
+ }
1146
+
1147
+ /**
1148
+ * Send SSH_MSG_KEXINIT First
1149
+ *
1150
+ * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
1151
+ * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
1152
+ * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
1153
+ *
1154
+ * @access public
1155
+ */
1156
+ function sendKEXINITFirst()
1157
+ {
1158
+ $this->send_kex_first = true;
1159
+ }
1160
+
1161
+ /**
1162
+ * Send SSH_MSG_KEXINIT Last
1163
+ *
1164
+ * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
1165
+ * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
1166
+ * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
1167
+ *
1168
+ * @access public
1169
+ */
1170
+ function sendKEXINITLast()
1171
+ {
1172
+ $this->send_kex_first = false;
1173
+ }
1174
+
1175
  /**
1176
  * Connect to an SSHv2 server
1177
  *
1203
  }
1204
  $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
1205
 
1206
+ if ($this->curTimeout) {
1207
+ $this->curTimeout-= $elapsed;
1208
+ if ($this->curTimeout < 0) {
1209
+ $this->is_timeout = true;
1210
+ return false;
1211
+ }
1212
  }
1213
  }
1214
 
1215
  $this->identifier = $this->_generate_identifier();
1216
 
1217
+ if ($this->send_id_string_first) {
1218
+ fputs($this->fsock, $this->identifier . "\r\n");
1219
+ }
1220
 
1221
  /* According to the SSH2 specs,
1222
 
1252
  $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
1253
  $this->curTimeout-= $elapsed;
1254
  }
1255
+ $subtemp = fgets($this->fsock, 255);
1256
+ if ($subtemp === '' || $subtemp === false) {
1257
+ return false;
1258
+ }
1259
+ $temp.= $subtemp;
1260
  }
1261
 
1262
  if (feof($this->fsock)) {
1263
+ $this->bitmap = 0;
1264
  user_error('Connection closed by server');
1265
  return false;
1266
  }
1272
 
1273
  $this->server_identifier = trim($temp, "\r\n");
1274
  if (strlen($extra)) {
1275
+ $this->errors[] = $extra;
1276
  }
1277
 
1278
+ if (version_compare($matches[1], '1.99', '<')) {
1279
  user_error("Cannot connect to SSH $matches[1] servers");
1280
  return false;
1281
  }
1282
 
1283
+ if (!$this->send_id_string_first) {
1284
+ fputs($this->fsock, $this->identifier . "\r\n");
 
 
1285
  }
1286
 
1287
+ if (!$this->send_kex_first) {
1288
+ $response = $this->_get_binary_packet();
1289
+ if ($response === false) {
1290
+ $this->bitmap = 0;
1291
+ user_error('Connection closed by server');
1292
+ return false;
1293
+ }
1294
+
1295
+ if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
1296
+ user_error('Expected SSH_MSG_KEXINIT');
1297
+ return false;
1298
+ }
1299
+
1300
+ if (!$this->_key_exchange($response)) {
1301
+ return false;
1302
+ }
1303
  }
1304
 
1305
+ if ($this->send_kex_first && !$this->_key_exchange()) {
1306
  return false;
1307
  }
1308
 
1346
  /**
1347
  * Key Exchange
1348
  *
1349
+ * @param string $kexinit_payload_server optional
1350
  * @access private
1351
  */
1352
+ function _key_exchange($kexinit_payload_server = false)
1353
  {
1354
+ $preferred = $this->preferred;
1355
+
1356
+ $kex_algorithms = isset($preferred['kex']) ?
1357
+ $preferred['kex'] :
1358
+ $this->getSupportedKEXAlgorithms();
1359
+ $server_host_key_algorithms = isset($preferred['hostkey']) ?
1360
+ $preferred['hostkey'] :
1361
+ $this->getSupportedHostKeyAlgorithms();
1362
+ $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ?
1363
+ $preferred['server_to_client']['crypt'] :
1364
+ $this->getSupportedEncryptionAlgorithms();
1365
+ $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ?
1366
+ $preferred['client_to_server']['crypt'] :
1367
+ $this->getSupportedEncryptionAlgorithms();
1368
+ $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ?
1369
+ $preferred['server_to_client']['mac'] :
1370
+ $this->getSupportedMACAlgorithms();
1371
+ $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ?
1372
+ $preferred['client_to_server']['mac'] :
1373
+ $this->getSupportedMACAlgorithms();
1374
+ $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ?
1375
+ $preferred['server_to_client']['comp'] :
1376
+ $this->getSupportedCompressionAlgorithms();
1377
+ $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ?
1378
+ $preferred['client_to_server']['comp'] :
1379
+ $this->getSupportedCompressionAlgorithms();
 
 
 
 
 
 
 
 
 
 
 
 
 
1380
 
1381
+ // some SSH servers have buggy implementations of some of the above algorithms
1382
+ switch (true) {
1383
+ case $this->server_identifier == 'SSH-2.0-SSHD':
1384
+ case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK':
1385
+ if (!isset($preferred['server_to_client']['mac'])) {
1386
+ $s2c_mac_algorithms = array_values(array_diff(
1387
+ $s2c_mac_algorithms,
1388
+ array('hmac-sha1-96', 'hmac-md5-96')
1389
+ ));
1390
+ }
1391
+ if (!isset($preferred['client_to_server']['mac'])) {
1392
+ $c2s_mac_algorithms = array_values(array_diff(
1393
+ $c2s_mac_algorithms,
1394
+ array('hmac-sha1-96', 'hmac-md5-96')
1395
+ ));
1396
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1397
  }
1398
 
1399
+ $str_kex_algorithms = implode(',', $kex_algorithms);
1400
+ $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
1401
+ $encryption_algorithms_server_to_client = implode(',', $s2c_encryption_algorithms);
1402
+ $encryption_algorithms_client_to_server = implode(',', $c2s_encryption_algorithms);
1403
+ $mac_algorithms_server_to_client = implode(',', $s2c_mac_algorithms);
1404
+ $mac_algorithms_client_to_server = implode(',', $c2s_mac_algorithms);
1405
+ $compression_algorithms_server_to_client = implode(',', $s2c_compression_algorithms);
1406
+ $compression_algorithms_client_to_server = implode(',', $c2s_compression_algorithms);
1407
 
1408
+ $client_cookie = crypt_random_string(16);
 
 
 
 
 
1409
 
1410
+ $kexinit_payload_client = pack(
1411
+ 'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
1412
+ NET_SSH2_MSG_KEXINIT,
1413
+ $client_cookie,
1414
+ strlen($str_kex_algorithms),
1415
+ $str_kex_algorithms,
1416
+ strlen($str_server_host_key_algorithms),
1417
+ $str_server_host_key_algorithms,
1418
+ strlen($encryption_algorithms_client_to_server),
1419
+ $encryption_algorithms_client_to_server,
1420
+ strlen($encryption_algorithms_server_to_client),
1421
+ $encryption_algorithms_server_to_client,
1422
+ strlen($mac_algorithms_client_to_server),
1423
+ $mac_algorithms_client_to_server,
1424
+ strlen($mac_algorithms_server_to_client),
1425
+ $mac_algorithms_server_to_client,
1426
+ strlen($compression_algorithms_client_to_server),
1427
+ $compression_algorithms_client_to_server,
1428
+ strlen($compression_algorithms_server_to_client),
1429
+ $compression_algorithms_server_to_client,
1430
+ 0,
1431
+ '',
1432
+ 0,
1433
+ '',
1434
+ 0,
1435
+ 0
1436
  );
1437
 
1438
+ if ($this->send_kex_first) {
1439
+ if (!$this->_send_binary_packet($kexinit_payload_client)) {
1440
+ return false;
1441
+ }
 
 
 
 
1442
 
1443
+ $kexinit_payload_server = $this->_get_binary_packet();
1444
+ if ($kexinit_payload_server === false) {
1445
+ $this->bitmap = 0;
1446
+ user_error('Connection closed by server');
1447
+ return false;
1448
+ }
1449
 
1450
+ if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) {
1451
+ user_error('Expected SSH_MSG_KEXINIT');
1452
+ return false;
1453
+ }
 
 
1454
  }
1455
 
 
 
1456
  $response = $kexinit_payload_server;
1457
  $this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
1458
  $server_cookie = $this->_string_shift($response, 16);
1523
  extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
1524
  $first_kex_packet_follows = $first_kex_packet_follows != 0;
1525
 
1526
+ if (!$this->send_kex_first && !$this->_send_binary_packet($kexinit_payload_client)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1527
  return false;
1528
  }
 
1529
 
1530
  // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
1531
  // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
1532
  // diffie-hellman key exchange as fast as possible
1533
+ $decrypt = $this->_array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client);
1534
  $decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
1535
  if ($decryptKeyLength === null) {
1536
  user_error('No compatible server to client encryption algorithms found');
1537
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1538
  }
1539
 
1540
+ $encrypt = $this->_array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server);
1541
  $encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
1542
  if ($encryptKeyLength === null) {
1543
  user_error('No compatible client to server encryption algorithms found');
1547
  $keyLength = $decryptKeyLength > $encryptKeyLength ? $decryptKeyLength : $encryptKeyLength;
1548
 
1549
  // through diffie-hellman key exchange a symmetric key is obtained
1550
+ $this->kex_algorithm = $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
1551
  if ($kex_algorithm === false) {
1552
  user_error('No compatible key exchange algorithms found');
1553
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1567
  if (!$this->_send_binary_packet($packet)) {
1568
  return false;
1569
  }
1570
+ $this->_updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST');
1571
 
1572
  $response = $this->_get_binary_packet();
1573
  if ($response === false) {
1574
+ $this->bitmap = 0;
1575
  user_error('Connection closed by server');
1576
  return false;
1577
  }
1583
  user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP');
1584
  return false;
1585
  }
1586
+ $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP');
1587
 
1588
  if (strlen($response) < 4) {
1589
  return false;
1668
  $data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
1669
 
1670
  if (!$this->_send_binary_packet($data)) {
1671
+ $this->bitmap = 0;
1672
  user_error('Connection closed by server');
1673
  return false;
1674
  }
1675
+ if ($clientKexInitMessage == NET_SSH2_MSG_KEXDH_GEX_INIT) {
1676
+ $this->_updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT');
1677
+ }
1678
 
1679
  $response = $this->_get_binary_packet();
1680
  if ($response === false) {
1681
+ $this->bitmap = 0;
1682
  user_error('Connection closed by server');
1683
  return false;
1684
  }
1688
  extract(unpack('Ctype', $this->_string_shift($response, 1)));
1689
 
1690
  if ($type != $serverKexReplyMessage) {
1691
+ $expected = $serverKexReplyMessage == NET_SSH2_MSG_KEXDH_GEX_REPLY ?
1692
+ 'SSH_MSG_KEXDH_GEX_REPLY' :
1693
+ 'SSH_MSG_KEXDH_REPLY';
1694
+ user_error("Expected $expected");
1695
  return false;
1696
  }
1697
+ if ($serverKexReplyMessage == NET_SSH2_MSG_KEXDH_GEX_REPLY) {
1698
+ $this->_updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY');
1699
+ }
1700
 
1701
  if (strlen($response) < 4) {
1702
  return false;
1765
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1766
  }
1767
 
1768
+ switch ($server_host_key_algorithm) {
1769
+ case 'ssh-dss':
1770
+ $expected_key_format = 'ssh-dss';
1771
+ break;
1772
+ //case 'rsa-sha2-256':
1773
+ //case 'rsa-sha2-512':
1774
+ //case 'ssh-rsa':
1775
+ default:
1776
+ $expected_key_format = 'ssh-rsa';
1777
+ }
1778
+
1779
+ if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) {
1780
+ switch (true) {
1781
+ case $this->signature_format == $server_host_key_algorithm:
1782
+ case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512':
1783
+ case $this->signature_format != 'ssh-rsa':
1784
+ user_error('Server Host Key Algorithm Mismatch');
1785
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1786
+ }
1787
  }
1788
 
1789
  $packet = pack(
1798
  $response = $this->_get_binary_packet();
1799
 
1800
  if ($response === false) {
1801
+ $this->bitmap = 0;
1802
  user_error('Connection closed by server');
1803
  return false;
1804
  }
1813
  return false;
1814
  }
1815
 
1816
+ $this->encrypt = $this->_encryption_algorithm_to_crypt_instance($encrypt);
1817
+ $this->decrypt = $this->_encryption_algorithm_to_crypt_instance($decrypt);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1818
 
1819
  $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
1820
 
1821
  if ($this->encrypt) {
1822
  if ($this->crypto_engine) {
1823
+ $this->encrypt->setPreferredEngine($this->crypto_engine);
1824
  }
1825
  $this->encrypt->enableContinuousBuffer();
1826
  $this->encrypt->disablePadding();
1827
 
1828
+ if ($this->encrypt->getBlockLength()) {
1829
+ $this->encrypt_block_size = $this->encrypt->getBlockLength() >> 3;
1830
+ }
1831
+
1832
  $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
1833
  while ($this->encrypt_block_size > strlen($iv)) {
1834
  $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
1840
  $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
1841
  }
1842
  $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
1843
+
1844
+ $this->encrypt->name = $decrypt;
1845
  }
1846
 
1847
  if ($this->decrypt) {
1848
  if ($this->crypto_engine) {
1849
+ $this->decrypt->setPreferredEngine($this->crypto_engine);
1850
  }
1851
  $this->decrypt->enableContinuousBuffer();
1852
  $this->decrypt->disablePadding();
1853
 
1854
+ if ($this->decrypt->getBlockLength()) {
1855
+ $this->decrypt_block_size = $this->decrypt->getBlockLength() >> 3;
1856
+ }
1857
+
1858
  $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
1859
  while ($this->decrypt_block_size > strlen($iv)) {
1860
  $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
1866
  $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
1867
  }
1868
  $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
1869
+
1870
+ $this->decrypt->name = $decrypt;
1871
  }
1872
 
1873
  /* The "arcfour128" algorithm is the RC4 cipher, as described in
1884
  $this->decrypt->decrypt(str_repeat("\0", 1536));
1885
  }
1886
 
1887
+ $mac_algorithm = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server);
1888
  if ($mac_algorithm === false) {
1889
  user_error('No compatible client to server message authentication algorithms found');
1890
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1912
  $this->hmac_create = new Crypt_Hash('md5-96');
1913
  $createKeyLength = 16;
1914
  }
1915
+ $this->hmac_create->name = $mac_algorithm;
1916
 
1917
+ $mac_algorithm = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client);
1918
  if ($mac_algorithm === false) {
1919
  user_error('No compatible server to client message authentication algorithms found');
1920
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1948
  $checkKeyLength = 16;
1949
  $this->hmac_size = 12;
1950
  }
1951
+ $this->hmac_check->name = $mac_algorithm;
1952
 
1953
  $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id);
1954
  while ($createKeyLength > strlen($key)) {
1962
  }
1963
  $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
1964
 
1965
+ $compression_algorithm = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server);
1966
  if ($compression_algorithm === false) {
1967
+ user_error('No compatible client to server compression algorithms found');
1968
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1969
  }
1970
+ //$this->decompress = $compression_algorithm == 'zlib';
1971
 
1972
+ $compression_algorithm = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_client_to_server);
1973
  if ($compression_algorithm === false) {
1974
+ user_error('No compatible server to client compression algorithms found');
1975
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1976
  }
1977
+ //$this->compress = $compression_algorithm == 'zlib';
1978
 
1979
  return true;
1980
  }
1988
  */
1989
  function _encryption_algorithm_to_key_size($algorithm)
1990
  {
1991
+ if ($this->bad_key_size_fix && $this->_bad_algorithm_candidate($algorithm)) {
1992
+ return 16;
1993
+ }
1994
+
1995
  switch ($algorithm) {
1996
  case 'none':
1997
  return 0;
2022
  return null;
2023
  }
2024
 
2025
+ /**
2026
+ * Maps an encryption algorithm name to an instance of a subclass of
2027
+ * \phpseclib\Crypt\Base.
2028
+ *
2029
+ * @param string $algorithm Name of the encryption algorithm
2030
+ * @return mixed Instance of \phpseclib\Crypt\Base or null for unknown
2031
+ * @access private
2032
+ */
2033
+ function _encryption_algorithm_to_crypt_instance($algorithm)
2034
+ {
2035
+ switch ($algorithm) {
2036
+ case '3des-cbc':
2037
+ if (!class_exists('Crypt_TripleDES')) {
2038
+ include_once 'Crypt/TripleDES.php';
2039
+ }
2040
+ return new Crypt_TripleDES();
2041
+ case '3des-ctr':
2042
+ if (!class_exists('Crypt_TripleDES')) {
2043
+ include_once 'Crypt/TripleDES.php';
2044
+ }
2045
+ return new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
2046
+ case 'aes256-cbc':
2047
+ case 'aes192-cbc':
2048
+ case 'aes128-cbc':
2049
+ if (!class_exists('Crypt_Rijndael')) {
2050
+ include_once 'Crypt/Rijndael.php';
2051
+ }
2052
+ return new Crypt_Rijndael();
2053
+ case 'aes256-ctr':
2054
+ case 'aes192-ctr':
2055
+ case 'aes128-ctr':
2056
+ if (!class_exists('Crypt_Rijndael')) {
2057
+ include_once 'Crypt/Rijndael.php';
2058
+ }
2059
+ return new Crypt_Rijndael(CRYPT_RIJNDAEL_MODE_CTR);
2060
+ case 'blowfish-cbc':
2061
+ if (!class_exists('Crypt_Blowfish')) {
2062
+ include_once 'Crypt/Blowfish.php';
2063
+ }
2064
+ return new Crypt_Blowfish();
2065
+ case 'blowfish-ctr':
2066
+ if (!class_exists('Crypt_Blowfish')) {
2067
+ include_once 'Crypt/Blowfish.php';
2068
+ }
2069
+ return new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
2070
+ case 'twofish128-cbc':
2071
+ case 'twofish192-cbc':
2072
+ case 'twofish256-cbc':
2073
+ case 'twofish-cbc':
2074
+ if (!class_exists('Crypt_Twofish')) {
2075
+ include_once 'Crypt/Twofish.php';
2076
+ }
2077
+ return new Crypt_Twofish();
2078
+ case 'twofish128-ctr':
2079
+ case 'twofish192-ctr':
2080
+ case 'twofish256-ctr':
2081
+ if (!class_exists('Crypt_Twofish')) {
2082
+ include_once 'Crypt/Twofish.php';
2083
+ }
2084
+ return new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
2085
+ case 'arcfour':
2086
+ case 'arcfour128':
2087
+ case 'arcfour256':
2088
+ if (!class_exists('Crypt_RC4')) {
2089
+ include_once 'Crypt/RC4.php';
2090
+ }
2091
+ return new Crypt_RC4();
2092
+ case 'none':
2093
+ //return new Crypt_Null();
2094
+ }
2095
+ return null;
2096
+ }
2097
+
2098
+ /**
2099
+ * Tests whether or not proposed algorithm has a potential for issues
2100
+ *
2101
+ * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html
2102
+ * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291
2103
+ * @param string $algorithm Name of the encryption algorithm
2104
+ * @return bool
2105
+ * @access private
2106
+ */
2107
+ function _bad_algorithm_candidate($algorithm)
2108
+ {
2109
+ switch ($algorithm) {
2110
+ case 'arcfour256':
2111
+ case 'aes192-ctr':
2112
+ case 'aes256-ctr':
2113
+ return true;
2114
+ }
2115
+
2116
+ return false;
2117
+ }
2118
+
2119
  /**
2120
  * Login
2121
  *
2131
  function login($username)
2132
  {
2133
  $args = func_get_args();
2134
+ $this->auth[] = $args;
2135
+
2136
+ // try logging with 'none' as an authentication method first since that's what
2137
+ // PuTTY does
2138
+ if ($this->_login($username)) {
2139
+ return true;
2140
+ }
2141
+ if (count($args) == 1) {
2142
+ return false;
2143
+ }
2144
  return call_user_func_array(array(&$this, '_login'), $args);
2145
  }
2146
 
2205
 
2206
  $response = $this->_get_binary_packet();
2207
  if ($response === false) {
2208
+ if ($this->retry_connect) {
2209
+ $this->retry_connect = false;
2210
+ if (!$this->_connect()) {
2211
+ return false;
2212
+ }
2213
+ return $this->_login_helper($username, $password);
2214
+ }
2215
+ $this->bitmap = 0;
2216
  user_error('Connection closed by server');
2217
  return false;
2218
  }
2269
 
2270
  $response = $this->_get_binary_packet();
2271
  if ($response === false) {
2272
+ $this->bitmap = 0;
2273
  user_error('Connection closed by server');
2274
  return false;
2275
  }
2328
 
2329
  $response = $this->_get_binary_packet();
2330
  if ($response === false) {
2331
+ $this->bitmap = 0;
2332
  user_error('Connection closed by server');
2333
  return false;
2334
  }
2340
 
2341
  switch ($type) {
2342
  case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed
2343
+ $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ');
 
 
2344
  if (strlen($response) < 4) {
2345
  return false;
2346
  }
2347
  extract(unpack('Nlength', $this->_string_shift($response, 4)));
2348
+ $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $this->_string_shift($response, $length);
2349
  return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
2350
  case NET_SSH2_MSG_USERAUTH_FAILURE:
2351
  // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
2427
  } else {
2428
  $orig = $response = $this->_get_binary_packet();
2429
  if ($response === false) {
2430
+ $this->bitmap = 0;
2431
  user_error('Connection closed by server');
2432
  return false;
2433
  }
2491
  // see http://tools.ietf.org/html/rfc4256#section-3.2
2492
  if (strlen($this->last_interactive_response)) {
2493
  $this->last_interactive_response = '';
2494
+ } else {
2495
+ $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST');
 
 
 
 
2496
  }
2497
 
2498
  if (!count($responses) && $num_prompts) {
2515
  return false;
2516
  }
2517
 
2518
+ $this->_updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE');
 
 
 
 
 
 
2519
 
2520
  /*
2521
  After receiving the response, the server MUST send either an
2587
  $publickey['n']
2588
  );
2589
 
2590
+ switch ($this->signature_format) {
2591
+ case 'rsa-sha2-512':
2592
+ $hash = 'sha512';
2593
+ $signatureType = 'rsa-sha2-512';
2594
+ break;
2595
+ case 'rsa-sha2-256':
2596
+ $hash = 'sha256';
2597
+ $signatureType = 'rsa-sha2-256';
2598
+ break;
2599
+ //case 'ssh-rsa':
2600
+ default:
2601
+ $hash = 'sha1';
2602
+ $signatureType = 'ssh-rsa';
2603
+ }
2604
+
2605
  $part1 = pack(
2606
  'CNa*Na*Na*',
2607
  NET_SSH2_MSG_USERAUTH_REQUEST,
2612
  strlen('publickey'),
2613
  'publickey'
2614
  );
2615
+ $part2 = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($publickey), $publickey);
2616
 
2617
  $packet = $part1 . chr(0) . $part2;
2618
  if (!$this->_send_binary_packet($packet)) {
2621
 
2622
  $response = $this->_get_binary_packet();
2623
  if ($response === false) {
2624
+ $this->bitmap = 0;
2625
  user_error('Connection closed by server');
2626
  return false;
2627
  }
2642
  case NET_SSH2_MSG_USERAUTH_PK_OK:
2643
  // we'll just take it on faith that the public key blob and the public key algorithm name are as
2644
  // they should be
2645
+ $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK');
 
 
 
 
 
 
2646
  }
2647
 
2648
  $packet = $part1 . chr(1) . $part2;
2649
  $privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
2650
+ $privatekey->setHash($hash);
2651
  $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
2652
+ $signature = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($signature), $signature);
2653
  $packet.= pack('Na*', strlen($signature), $signature);
2654
 
2655
  if (!$this->_send_binary_packet($packet)) {
2658
 
2659
  $response = $this->_get_binary_packet();
2660
  if ($response === false) {
2661
+ $this->bitmap = 0;
2662
  user_error('Connection closed by server');
2663
  return false;
2664
  }
2785
 
2786
  $response = $this->_get_binary_packet();
2787
  if ($response === false) {
2788
+ $this->bitmap = 0;
2789
  user_error('Connection closed by server');
2790
  return false;
2791
  }
2926
 
2927
  $response = $this->_get_binary_packet();
2928
  if ($response === false) {
2929
+ $this->bitmap = 0;
2930
  user_error('Connection closed by server');
2931
  return false;
2932
  }
3019
  * @see self::write()
3020
  * @param string $expect
3021
  * @param int $mode
3022
+ * @return string|bool
3023
  * @access public
3024
  */
3025
  function read($expect = '', $mode = NET_SSH2_READ_SIMPLE)
3039
 
3040
  $channel = $this->_get_interactive_channel();
3041
 
3042
+ if ($mode == NET_SSH2_READ_NEXT) {
3043
+ return $this->_get_channel_packet($channel);
3044
+ }
3045
+
3046
  $match = $expect;
3047
  while (true) {
3048
  if ($mode == NET_SSH2_READ_REGEX) {
3242
  }
3243
 
3244
  /**
3245
+ * Pings a server connection, or tries to reconnect if the connection has gone down
3246
  *
3247
+ * Inspired by http://php.net/manual/en/mysqli.ping.php
3248
  *
3249
+ * @return bool
3250
+ * @access public
 
3251
  */
3252
+ function ping()
3253
  {
3254
+ if (!$this->isAuthenticated()) {
3255
+ if (!empty($this->auth)) {
3256
+ return $this->_reconnect();
3257
+ }
3258
  return false;
3259
  }
3260
 
3261
+ $this->window_size_server_to_client[NET_SSH2_CHANNEL_KEEP_ALIVE] = $this->window_size;
3262
+ $packet_size = 0x4000;
3263
+ $packet = pack(
3264
+ 'CNa*N3',
3265
+ NET_SSH2_MSG_CHANNEL_OPEN,
3266
+ strlen('session'),
3267
+ 'session',
3268
+ NET_SSH2_CHANNEL_KEEP_ALIVE,
3269
+ $this->window_size_server_to_client[NET_SSH2_CHANNEL_KEEP_ALIVE],
3270
+ $packet_size
3271
+ );
3272
 
3273
+ if (!@$this->_send_binary_packet($packet)) {
3274
+ return $this->_reconnect();
3275
+ }
3276
+
3277
+ $this->channel_status[NET_SSH2_CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN;
3278
+
3279
+ $response = @$this->_get_channel_packet(NET_SSH2_CHANNEL_KEEP_ALIVE);
3280
+ if ($response !== false) {
3281
+ $this->_close_channel(NET_SSH2_CHANNEL_KEEP_ALIVE);
3282
+ return true;
3283
+ }
3284
+
3285
+ return $this->_reconnect();
3286
+ }
3287
+
3288
+ /**
3289
+ * In situ reconnect method
3290
+ *
3291
+ * @return boolean
3292
+ * @access private
3293
+ */
3294
+ function _reconnect()
3295
+ {
3296
+ $this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
3297
+ $this->retry_connect = true;
3298
+ if (!$this->_connect()) {
3299
+ return false;
3300
+ }
3301
+ foreach ($this->auth as $auth) {
3302
+ $result = call_user_func_array(array(&$this, 'login'), $auth);
3303
+ }
3304
+ return $result;
3305
+ }
3306
+
3307
+ /**
3308
+ * Resets a connection for re-use
3309
+ *
3310
+ * @param int $reason
3311
+ * @access private
3312
+ */
3313
+ function _reset_connection($reason)
3314
+ {
3315
+ $this->_disconnect($reason);
3316
+ $this->decrypt = $this->encrypt = false;
3317
+ $this->decrypt_block_size = $this->encrypt_block_size = 8;
3318
+ $this->hmac_check = $this->hmac_create = false;
3319
+ $this->hmac_size = false;
3320
+ $this->session_id = false;
3321
+ $this->retry_connect = true;
3322
+ $this->get_seq_no = $this->send_seq_no = 0;
3323
+ }
3324
+
3325
+ /**
3326
+ * Gets Binary Packets
3327
+ *
3328
+ * See '6. Binary Packet Protocol' of rfc4253 for more info.
3329
+ *
3330
+ * @see self::_send_binary_packet()
3331
+ * @return string
3332
+ * @access private
3333
+ */
3334
+ function _get_binary_packet($skip_channel_filter = false)
3335
+ {
3336
+ if (!is_resource($this->fsock) || feof($this->fsock)) {
3337
+ $this->bitmap = 0;
3338
+ user_error('Connection closed prematurely');
3339
+ return false;
3340
+ }
3341
+
3342
+ $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
3343
+ $raw = fread($this->fsock, $this->decrypt_block_size);
3344
+
3345
+ if (!strlen($raw)) {
3346
  return '';
3347
  }
3348
 
3365
  // "implementations SHOULD check that the packet length is reasonable"
3366
  // PuTTY uses 0x9000 as the actual max packet size and so to shall we
3367
  if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
3368
+ if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decrypt->name) && !($this->bitmap & NET_SSH2_MASK_LOGIN)) {
3369
+ $this->bad_key_size_fix = true;
3370
+ $this->_reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
3371
+ return false;
3372
+ }
3373
  user_error('Invalid size');
3374
  return false;
3375
  }
3378
  while ($remaining_length > 0) {
3379
  $temp = fread($this->fsock, $remaining_length);
3380
  if ($temp === false || feof($this->fsock)) {
 
3381
  $this->bitmap = 0;
3382
+ user_error('Error reading from socket');
3383
  return false;
3384
  }
3385
  $buffer.= $temp;
3386
  $remaining_length-= strlen($temp);
3387
  }
3388
+
3389
  $stop = strtok(microtime(), ' ') + strtok('');
3390
  if (strlen($buffer)) {
3391
  $raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
3397
  if ($this->hmac_check !== false) {
3398
  $hmac = fread($this->fsock, $this->hmac_size);
3399
  if ($hmac === false || strlen($hmac) != $this->hmac_size) {
 
3400
  $this->bitmap = 0;
3401
+ user_error('Error reading socket');
3402
  return false;
3403
  } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
3404
  user_error('Invalid HMAC');
3421
  $this->last_packet = $current;
3422
  }
3423
 
3424
+ return $this->_filter($payload, $skip_channel_filter);
3425
  }
3426
 
3427
  /**
3433
  * @return string
3434
  * @access private
3435
  */
3436
+ function _filter($payload, $skip_channel_filter)
3437
  {
3438
  switch (ord($payload[0])) {
3439
  case NET_SSH2_MSG_DISCONNECT:
3442
  return false;
3443
  }
3444
  extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
3445
+ $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . $this->_string_shift($payload, $length);
3446
  $this->bitmap = 0;
3447
  return false;
3448
  case NET_SSH2_MSG_IGNORE:
3449
+ $payload = $this->_get_binary_packet($skip_channel_filter);
3450
  break;
3451
  case NET_SSH2_MSG_DEBUG:
3452
  $this->_string_shift($payload, 2);
3454
  return false;
3455
  }
3456
  extract(unpack('Nlength', $this->_string_shift($payload, 4)));
3457
+ $this->errors[] = 'SSH_MSG_DEBUG: ' . $this->_string_shift($payload, $length);
3458
+ $payload = $this->_get_binary_packet($skip_channel_filter);
3459
  break;
3460
  case NET_SSH2_MSG_UNIMPLEMENTED:
3461
  return false;
3462
  case NET_SSH2_MSG_KEXINIT:
3463
  if ($this->session_id !== false) {
3464
+ $this->send_kex_first = false;
3465
  if (!$this->_key_exchange($payload)) {
3466
  $this->bitmap = 0;
3467
  return false;
3468
  }
3469
+ $payload = $this->_get_binary_packet($skip_channel_filter);
3470
  }
3471
  }
3472
 
3477
  return false;
3478
  }
3479
  extract(unpack('Nlength', $this->_string_shift($payload, 4)));
3480
+ $this->banner_message = $this->_string_shift($payload, $length);
3481
  $payload = $this->_get_binary_packet();
3482
  }
3483
 
3484
  // only called when we've already logged in
3485
  if (($this->bitmap & NET_SSH2_MASK_CONNECTED) && $this->isAuthenticated()) {
3486
  switch (ord($payload[0])) {
3487
+ case NET_SSH2_MSG_CHANNEL_DATA:
3488
+ case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
3489
+ case NET_SSH2_MSG_CHANNEL_REQUEST:
3490
+ case NET_SSH2_MSG_CHANNEL_CLOSE:
3491
+ case NET_SSH2_MSG_CHANNEL_EOF:
3492
+ if (!$skip_channel_filter && !empty($this->server_channels)) {
3493
+ $this->binary_packet_buffer = $payload;
3494
+ $this->_get_channel_packet(true);
3495
+ $payload = $this->_get_binary_packet();
3496
+ }
3497
+ break;
3498
  case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
3499
  if (strlen($payload) < 4) {
3500
  return false;
3506
  return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
3507
  }
3508
 
3509
+ $payload = $this->_get_binary_packet($skip_channel_filter);
3510
  break;
3511
  case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
3512
  $this->_string_shift($payload, 1);
3569
  return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
3570
  }
3571
  }
3572
+ $payload = $this->_get_binary_packet($skip_channel_filter);
3573
  break;
3574
  case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
3575
  $this->_string_shift($payload, 1);
3580
  extract(unpack('Nwindow_size', $this->_string_shift($payload, 4)));
3581
  $this->window_size_client_to_server[$channel]+= $window_size;
3582
 
3583
+ $payload = ($this->bitmap & NET_SSH2_MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet($skip_channel_filter);
3584
  }
3585
  }
3586
 
3679
  }
3680
 
3681
  while (true) {
3682
+ if ($this->binary_packet_buffer !== false) {
3683
+ $response = $this->binary_packet_buffer;
3684
+ $this->binary_packet_buffer = false;
3685
+ } else {
 
 
3686
  $read = array($this->fsock);
3687
  $write = $except = null;
3688
 
3689
+ if (!$this->curTimeout) {
3690
+ @stream_select($read, $write, $except, null);
3691
+ } else {
3692
+ if ($this->curTimeout < 0) {
3693
+ $this->is_timeout = true;
3694
+ return true;
3695
+ }
3696
+
3697
+ $read = array($this->fsock);
3698
+ $write = $except = null;
3699
+
3700
+ $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
3701
+ $sec = floor($this->curTimeout);
3702
+ $usec = 1000000 * ($this->curTimeout - $sec);
3703
+ // on windows this returns a "Warning: Invalid CRT parameters detected" error
3704
+ if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
3705
+ $this->is_timeout = true;
3706
+ if ($client_channel == NET_SSH2_CHANNEL_EXEC && !$this->request_pty) {
3707
+ $this->_close_channel($client_channel);
3708
+ }
3709
+ return true;
3710
+ }
3711
+ $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
3712
+ $this->curTimeout-= $elapsed;
3713
  }
 
 
 
3714
 
3715
+ $response = $this->_get_binary_packet(true);
3716
+ if ($response === false) {
3717
+ $this->bitmap = 0;
3718
+ user_error('Connection closed by server');
3719
+ return false;
3720
+ }
3721
  }
3722
+
3723
  if ($client_channel == -1 && $response === true) {
3724
  return true;
3725
  }
 
 
 
 
3726
  if (!strlen($response)) {
3727
  return false;
3728
  }
3743
 
3744
  // resize the window, if appropriate
3745
  if ($this->window_size_server_to_client[$channel] < 0) {
3746
+ // PuTTY does something more analogous to the following:
3747
+ //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) {
3748
+ $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize);
3749
  if (!$this->_send_binary_packet($packet)) {
3750
  return false;
3751
  }
3752
+ $this->window_size_server_to_client[$channel]+= $this->window_resize;
3753
+ }
3754
+
3755
+ switch ($type) {
3756
+ case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
3757
+ /*
3758
+ if ($client_channel == NET_SSH2_CHANNEL_EXEC) {
3759
+ $this->_send_channel_packet($client_channel, chr(0));
3760
+ }
3761
+ */
3762
+ // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
3763
+ if (strlen($response) < 8) {
3764
+ return false;
3765
+ }
3766
+ extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8)));
3767
+ $data = $this->_string_shift($response, $length);
3768
+ $this->stdErrorLog.= $data;
3769
+ if ($skip_extended || $this->quiet_mode) {
3770
+ continue 2;
3771
+ }
3772
+ if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) {
3773
+ return $data;
3774
+ }
3775
+ if (!isset($this->channel_buffers[$channel])) {
3776
+ $this->channel_buffers[$channel] = array();
3777
+ }
3778
+ $this->channel_buffers[$channel][] = $data;
3779
+
3780
+ continue 2;
3781
+ case NET_SSH2_MSG_CHANNEL_REQUEST:
3782
+ if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) {
3783
+ continue 2;
3784
+ }
3785
+ if (strlen($response) < 4) {
3786
+ return false;
3787
+ }
3788
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
3789
+ $value = $this->_string_shift($response, $length);
3790
+ switch ($value) {
3791
+ case 'exit-signal':
3792
+ $this->_string_shift($response, 1);
3793
+ if (strlen($response) < 4) {
3794
+ return false;
3795
+ }
3796
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
3797
+ $this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);
3798
+ $this->_string_shift($response, 1);
3799
+ if (strlen($response) < 4) {
3800
+ return false;
3801
+ }
3802
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
3803
+ if ($length) {
3804
+ $this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);
3805
+ }
3806
+
3807
+ $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel]));
3808
+ $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
3809
+
3810
+ $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF;
3811
+
3812
+ continue 3;
3813
+ case 'exit-status':
3814
+ if (strlen($response) < 5) {
3815
+ return false;
3816
+ }
3817
+ extract(unpack('Cfalse/Nexit_status', $this->_string_shift($response, 5)));
3818
+ $this->exit_status = $exit_status;
3819
+
3820
+ // "The client MAY ignore these messages."
3821
+ // -- http://tools.ietf.org/html/rfc4254#section-6.10
3822
+
3823
+ continue 3;
3824
+ default:
3825
+ // "Some systems may not implement signals, in which case they SHOULD ignore this message."
3826
+ // -- http://tools.ietf.org/html/rfc4254#section-6.9
3827
+ continue 3;
3828
+ }
3829
  }
3830
 
3831
  switch ($this->channel_status[$channel]) {
3910
  }
3911
  $this->channel_buffers[$channel][] = $data;
3912
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3913
  case NET_SSH2_MSG_CHANNEL_CLOSE:
3914
+ $this->curTimeout = 5;
3915
 
3916
  if ($this->bitmap & NET_SSH2_MASK_SHELL) {
3917
  $this->bitmap&= ~NET_SSH2_MASK_SHELL;
3947
  function _send_binary_packet($data, $logged = null)
3948
  {
3949
  if (!is_resource($this->fsock) || feof($this->fsock)) {
 
3950
  $this->bitmap = 0;
3951
+ user_error('Connection closed prematurely');
3952
  return false;
3953
  }
3954
 
4140
 
4141
  $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
4142
 
4143
+ $this->curTimeout = 5;
4144
 
4145
  while (!is_bool($this->_get_channel_packet($client_channel))) {
4146
  }
4147
 
4148
+ if ($this->is_timeout) {
4149
+ $this->disconnect();
4150
+ }
4151
+
4152
  if ($want_reply) {
4153
  $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
4154
  }
4170
  if ($this->bitmap & NET_SSH2_MASK_CONNECTED) {
4171
  $data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, '');
4172
  $this->_send_binary_packet($data);
4173
+ }
4174
+
4175
+ $this->bitmap = 0;
4176
+ if (is_resource($this->fsock) && get_resource_type($this->fsock) == 'stream') {
4177
  fclose($this->fsock);
 
4178
  }
4179
+
4180
+ return false;
4181
  }
4182
 
4183
  /**
4498
  return $this->languages_client_to_server;
4499
  }
4500
 
4501
+ /**
4502
+ * Returns a list of algorithms the server supports
4503
+ *
4504
+ * @return array
4505
+ * @access public
4506
+ */
4507
+ function getServerAlgorithms()
4508
+ {
4509
+ $this->_connect();
4510
+
4511
+ return array(
4512
+ 'kex' => $this->kex_algorithms,
4513
+ 'hostkey' => $this->server_host_key_algorithms,
4514
+ 'client_to_server' => array(
4515
+ 'crypt' => $this->encryption_algorithms_client_to_server,
4516
+ 'mac' => $this->mac_algorithms_client_to_server,
4517
+ 'comp' => $this->compression_algorithms_client_to_server,
4518
+ 'lang' => $this->languages_client_to_server
4519
+ ),
4520
+ 'server_to_client' => array(
4521
+ 'crypt' => $this->encryption_algorithms_server_to_client,
4522
+ 'mac' => $this->mac_algorithms_server_to_client,
4523
+ 'comp' => $this->compression_algorithms_server_to_client,
4524
+ 'lang' => $this->languages_server_to_client
4525
+ )
4526
+ );
4527
+ }
4528
+
4529
+ /**
4530
+ * Returns a list of KEX algorithms that phpseclib supports
4531
+ *
4532
+ * @return array
4533
+ * @access public
4534
+ */
4535
+ function getSupportedKEXAlgorithms()
4536
+ {
4537
+ $kex_algorithms = array(
4538
+ 'diffie-hellman-group-exchange-sha256',// RFC 4419
4539
+ 'diffie-hellman-group-exchange-sha1', // RFC 4419
4540
+
4541
+ // Diffie-Hellman Key Agreement (DH) using integer modulo prime
4542
+ // groups.
4543
+ 'diffie-hellman-group14-sha1', // REQUIRED
4544
+ 'diffie-hellman-group1-sha1', // REQUIRED
4545
+ );
4546
+
4547
+ return $kex_algorithms;
4548
+ }
4549
+
4550
+ /**
4551
+ * Returns a list of host key algorithms that phpseclib supports
4552
+ *
4553
+ * @return array
4554
+ * @access public
4555
+ */
4556
+ function getSupportedHostKeyAlgorithms()
4557
+ {
4558
+ return array(
4559
+ 'rsa-sha2-256', // RFC 8332
4560
+ 'rsa-sha2-512', // RFC 8332
4561
+ 'ssh-rsa', // RECOMMENDED sign Raw RSA Key
4562
+ 'ssh-dss' // REQUIRED sign Raw DSS Key
4563
+ );
4564
+ }
4565
+
4566
+ /**
4567
+ * Returns a list of symmetric key algorithms that phpseclib supports
4568
+ *
4569
+ * @return array
4570
+ * @access public
4571
+ */
4572
+ function getSupportedEncryptionAlgorithms()
4573
+ {
4574
+ $algos = array(
4575
+ // from <http://tools.ietf.org/html/rfc4345#section-4>:
4576
+ 'arcfour256',
4577
+ 'arcfour128',
4578
+
4579
+ //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
4580
+
4581
+ // CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
4582
+ 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
4583
+ 'aes192-ctr', // RECOMMENDED AES with 192-bit key
4584
+ 'aes256-ctr', // RECOMMENDED AES with 256-bit key
4585
+
4586
+ 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key
4587
+ 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key
4588
+ 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key
4589
+
4590
+ 'aes128-cbc', // RECOMMENDED AES with a 128-bit key
4591
+ 'aes192-cbc', // OPTIONAL AES with a 192-bit key
4592
+ 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
4593
+
4594
+ 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key
4595
+ 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key
4596
+ 'twofish256-cbc',
4597
+ 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc"
4598
+ // (this is being retained for historical reasons)
4599
+
4600
+ 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode
4601
+
4602
+ 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode
4603
+
4604
+ '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
4605
+
4606
+ '3des-cbc', // REQUIRED three-key 3DES in CBC mode
4607
+
4608
+ //'none' // OPTIONAL no encryption; NOT RECOMMENDED
4609
+ );
4610
+
4611
+ $engines = array(
4612
+ CRYPT_ENGINE_OPENSSL,
4613
+ CRYPT_ENGINE_MCRYPT,
4614
+ CRYPT_ENGINE_INTERNAL
4615
+ );
4616
+
4617
+ $ciphers = array();
4618
+ foreach ($engines as $engine) {
4619
+ foreach ($algos as $algo) {
4620
+ $obj = $this->_encryption_algorithm_to_crypt_instance($algo);
4621
+ if (strtolower(get_class($obj)) == 'crypt_rijndael') {
4622
+ $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo));
4623
+ }
4624
+ switch ($algo) {
4625
+ case 'arcfour128':
4626
+ case 'arcfour256':
4627
+ if ($engine != CRYPT_ENGINE_INTERNAL) {
4628
+ continue 2;
4629
+ }
4630
+ }
4631
+ if ($obj->isValidEngine($engine)) {
4632
+ $algos = array_diff($algos, array($algo));
4633
+ $ciphers[] = $algo;
4634
+ }
4635
+ }
4636
+ }
4637
+
4638
+ return $ciphers;
4639
+ }
4640
+
4641
+ /**
4642
+ * Returns a list of MAC algorithms that phpseclib supports
4643
+ *
4644
+ * @return array
4645
+ * @access public
4646
+ */
4647
+ function getSupportedMACAlgorithms()
4648
+ {
4649
+ return array(
4650
+ // from <http://www.ietf.org/rfc/rfc6668.txt>:
4651
+ 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32)
4652
+
4653
+ 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20)
4654
+ 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20)
4655
+ 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16)
4656
+ 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16)
4657
+ //'none' // OPTIONAL no MAC; NOT RECOMMENDED
4658
+ );
4659
+ }
4660
+
4661
+ /**
4662
+ * Returns a list of compression algorithms that phpseclib supports
4663
+ *
4664
+ * @return array
4665
+ * @access public
4666
+ */
4667
+ function getSupportedCompressionAlgorithms()
4668
+ {
4669
+ return array(
4670
+ 'none' // REQUIRED no compression
4671
+ //'zlib' // OPTIONAL ZLIB (LZ77) compression
4672
+ );
4673
+ }
4674
+
4675
+ /**
4676
+ * Return list of negotiated algorithms
4677
+ *
4678
+ * Uses the same format as https://www.php.net/ssh2-methods-negotiated
4679
+ *
4680
+ * @return array
4681
+ * @access public
4682
+ */
4683
+ function getAlgorithmsNegotiated()
4684
+ {
4685
+ $this->_connect();
4686
+
4687
+ return array(
4688
+ 'kex' => $this->kex_algorithm,
4689
+ 'hostkey' => $this->signature_format,
4690
+ 'client_to_server' => array(
4691
+ 'crypt' => $this->encrypt->name,
4692
+ 'mac' => $this->hmac_create->name,
4693
+ 'comp' => 'none',
4694
+ ),
4695
+ 'server_to_client' => array(
4696
+ 'crypt' => $this->decrypt->name,
4697
+ 'mac' => $this->hmac_check->name,
4698
+ 'comp' => 'none',
4699
+ )
4700
+ );
4701
+ }
4702
+
4703
+ /**
4704
+ * Accepts an associative array with up to four parameters as described at
4705
+ * <https://www.php.net/manual/en/function.ssh2-connect.php>
4706
+ *
4707
+ * @param array $methods
4708
+ * @access public
4709
+ */
4710
+ function setPreferredAlgorithms($methods)
4711
+ {
4712
+ $preferred = $methods;
4713
+
4714
+ if (isset($preferred['kex'])) {
4715
+ $preferred['kex'] = array_intersect(
4716
+ $preferred['kex'],
4717
+ $this->getSupportedKEXAlgorithms()
4718
+ );
4719
+ }
4720
+
4721
+ if (isset($preferred['hostkey'])) {
4722
+ $preferred['hostkey'] = array_intersect(
4723
+ $preferred['hostkey'],
4724
+ $this->getSupportedHostKeyAlgorithms()
4725
+ );
4726
+ }
4727
+
4728
+ $keys = array('client_to_server', 'server_to_client');
4729
+ foreach ($keys as $key) {
4730
+ if (isset($preferred[$key])) {
4731
+ $a = &$preferred[$key];
4732
+ if (isset($a['crypt'])) {
4733
+ $a['crypt'] = array_intersect(
4734
+ $a['crypt'],
4735
+ $this->getSupportedEncryptionAlgorithms()
4736
+ );
4737
+ }
4738
+ if (isset($a['comp'])) {
4739
+ $a['comp'] = array_intersect(
4740
+ $a['comp'],
4741
+ $this->getSupportedCompressionAlgorithms()
4742
+ );
4743
+ }
4744
+ if (isset($a['mac'])) {
4745
+ $a['mac'] = array_intersect(
4746
+ $a['mac'],
4747
+ $this->getSupportedMACAlgorithms()
4748
+ );
4749
+ }
4750
+ }
4751
+ }
4752
+
4753
+ $keys = array(
4754
+ 'kex',
4755
+ 'hostkey',
4756
+ 'client_to_server/crypt',
4757
+ 'client_to_server/comp',
4758
+ 'client_to_server/mac',
4759
+ 'server_to_client/crypt',
4760
+ 'server_to_client/comp',
4761
+ 'server_to_client/mac',
4762
+ );
4763
+ foreach ($keys as $key) {
4764
+ $p = $preferred;
4765
+ $m = $methods;
4766
+
4767
+ $subkeys = explode('/', $key);
4768
+ foreach ($subkeys as $subkey) {
4769
+ if (!isset($p[$subkey])) {
4770
+ continue 2;
4771
+ }
4772
+ $p = $p[$subkey];
4773
+ $m = $m[$subkey];
4774
+ }
4775
+
4776
+ if (count($p) != count($m)) {
4777
+ $diff = array_diff($m, $p);
4778
+ $msg = count($diff) == 1 ?
4779
+ ' is not a supported algorithm' :
4780
+ ' are not supported algorithms';
4781
+ user_error(implode(', ', $diff) . $msg);
4782
+ return false;
4783
+ }
4784
+ }
4785
+
4786
+ $this->preferred = $preferred;
4787
+ }
4788
+
4789
  /**
4790
  * Returns the banner message.
4791
  *
4905
 
4906
  break;
4907
  case 'ssh-rsa':
4908
+ case 'rsa-sha2-256':
4909
+ case 'rsa-sha2-512':
4910
  if (strlen($server_public_host_key) < 4) {
4911
  return false;
4912
  }
4933
  }
4934
 
4935
  $rsa = new Crypt_RSA();
4936
+ switch ($this->signature_format) {
4937
+ case 'rsa-sha2-512':
4938
+ $hash = 'sha512';
4939
+ break;
4940
+ case 'rsa-sha2-256':
4941
+ $hash = 'sha256';
4942
+ break;
4943
+ //case 'ssh-rsa':
4944
+ default:
4945
+ $hash = 'sha1';
4946
+ }
4947
+ $rsa->setHash($hash);
4948
  $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
4949
  $rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
4950
  if (!$rsa->verify($this->exchange_hash, $signature)) {
4973
  $s = $s->modPow($e, $n);
4974
  $s = $s->toBytes();
4975
 
4976
+ switch ($this->signature_format) {
4977
+ case 'rsa-sha2-512':
4978
+ $hash = 'sha512';
4979
+ break;
4980
+ case 'rsa-sha2-256':
4981
+ $hash = 'sha256';
4982
+ break;
4983
+ //case 'ssh-rsa':
4984
+ default:
4985
+ $hash = 'sha1';
4986
+ }
4987
+ $hashObj = new Crypt_Hash($hash);
4988
+ switch ($this->signature_format) {
4989
+ case 'rsa-sha2-512':
4990
+ $h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash));
4991
+ break;
4992
+ case 'rsa-sha2-256':
4993
+ $h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash));
4994
+ break;
4995
+ //case 'ssh-rsa':
4996
+ default:
4997
+ $hash = 'sha1';
4998
+ $h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash));
4999
+ }
5000
  $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
5001
 
5002
  if ($s != $h) {
5082
  $this->windowColumns = $columns;
5083
  $this->windowRows = $rows;
5084
  }
5085
+
5086
+ /**
5087
+ * Update packet types in log history
5088
+ *
5089
+ * @param string $old
5090
+ * @param string $new
5091
+ * @access private
5092
+ */
5093
+ function _updateLogHistory($old, $new)
5094
+ {
5095
+ if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {
5096
+ $this->message_number_log[count($this->message_number_log) - 1] = str_replace(
5097
+ $old,
5098
+ $new,
5099
+ $this->message_number_log[count($this->message_number_log) - 1]
5100
+ );
5101
+ }
5102
+ }
5103
  }
lib/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php CHANGED
@@ -64,7 +64,7 @@ define('SYSTEM_SSH_AGENT_FAILURE', 5);
64
  define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
65
  // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
66
  define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
67
-
68
 
69
  /**@+
70
  * Agent forwarding status
@@ -77,7 +77,17 @@ define('SYSTEM_SSH_AGENT_FORWARD_NONE', 0);
77
  define('SYSTEM_SSH_AGENT_FORWARD_REQUEST', 1);
78
  // forwarding has been request and is active
79
  define('SYSTEM_SSH_AGENT_FORWARD_ACTIVE', 2);
 
80
 
 
 
 
 
 
 
 
 
 
81
  /**#@-*/
82
 
83
  /**
@@ -123,6 +133,16 @@ class System_SSH_Agent_Identity
123
  */
124
  var $fsock;
125
 
 
 
 
 
 
 
 
 
 
 
126
  /**
127
  * Default Constructor.
128
  *
@@ -202,6 +222,31 @@ class System_SSH_Agent_Identity
202
  {
203
  }
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  /**
206
  * Create a signature
207
  *
@@ -214,22 +259,61 @@ class System_SSH_Agent_Identity
214
  function sign($message)
215
  {
216
  // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
217
- $packet = pack('CNa*Na*N', SYSTEM_SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, 0);
218
  $packet = pack('Na*', strlen($packet), $packet);
219
  if (strlen($packet) != fputs($this->fsock, $packet)) {
220
  user_error('Connection closed during signing');
 
221
  }
222
 
223
- $length = current(unpack('N', fread($this->fsock, 4)));
 
 
 
 
 
224
  $type = ord(fread($this->fsock, 1));
225
  if ($type != SYSTEM_SSH_AGENT_SIGN_RESPONSE) {
226
  user_error('Unable to retreive signature');
 
227
  }
228
 
229
  $signature_blob = fread($this->fsock, $length - 1);
230
- // the only other signature format defined - ssh-dss - is the same length as ssh-rsa
231
- // the + 12 is for the other various SSH added length fields
232
- return substr($signature_blob, strlen('ssh-rsa') + 12);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  }
234
  }
235
 
@@ -240,7 +324,7 @@ class System_SSH_Agent_Identity
240
  *
241
  * @package System_SSH_Agent
242
  * @author Jim Wigginton <terrafrost@php.net>
243
- * @access internal
244
  */
245
  class System_SSH_Agent
246
  {
@@ -281,18 +365,20 @@ class System_SSH_Agent
281
  * @return System_SSH_Agent
282
  * @access public
283
  */
284
- function __construct()
285
  {
286
- switch (true) {
287
- case isset($_SERVER['SSH_AUTH_SOCK']):
288
- $address = $_SERVER['SSH_AUTH_SOCK'];
289
- break;
290
- case isset($_ENV['SSH_AUTH_SOCK']):
291
- $address = $_ENV['SSH_AUTH_SOCK'];
292
- break;
293
- default:
294
- user_error('SSH_AUTH_SOCK not found');
295
- return false;
 
 
296
  }
297
 
298
  $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
@@ -307,9 +393,9 @@ class System_SSH_Agent
307
  * @see self::__construct()
308
  * @access public
309
  */
310
- function System_SSH_Agent()
311
  {
312
- $this->__construct();
313
  }
314
 
315
  /**
@@ -330,23 +416,54 @@ class System_SSH_Agent
330
  $packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
331
  if (strlen($packet) != fputs($this->fsock, $packet)) {
332
  user_error('Connection closed while requesting identities');
 
333
  }
334
 
335
- $length = current(unpack('N', fread($this->fsock, 4)));
 
 
 
 
 
336
  $type = ord(fread($this->fsock, 1));
337
  if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
338
  user_error('Unable to request identities');
 
339
  }
340
 
341
  $identities = array();
342
- $keyCount = current(unpack('N', fread($this->fsock, 4)));
 
 
 
 
 
343
  for ($i = 0; $i < $keyCount; $i++) {
344
- $length = current(unpack('N', fread($this->fsock, 4)));
 
 
 
 
 
345
  $key_blob = fread($this->fsock, $length);
 
 
 
 
346
  $key_str = 'ssh-rsa ' . base64_encode($key_blob);
347
- $length = current(unpack('N', fread($this->fsock, 4)));
 
 
 
 
 
348
  if ($length) {
349
- $key_str.= ' ' . fread($this->fsock, $length);
 
 
 
 
 
350
  }
351
  $length = current(unpack('N', substr($key_blob, 0, 4)));
352
  $key_type = substr($key_blob, 4, $length);
@@ -471,14 +588,24 @@ class System_SSH_Agent
471
 
472
  if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
473
  user_error('Connection closed attempting to forward data to SSH agent');
 
474
  }
475
 
476
  $this->socket_buffer = '';
477
  $this->expected_bytes = 0;
478
 
479
- $agent_reply_bytes = current(unpack('N', fread($this->fsock, 4)));
 
 
 
 
 
480
 
481
  $agent_reply_data = fread($this->fsock, $agent_reply_bytes);
 
 
 
 
482
  $agent_reply_data = current(unpack('a*', $agent_reply_data));
483
 
484
  return pack('Na*', $agent_reply_bytes, $agent_reply_data);
64
  define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
65
  // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
66
  define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
67
+ /**#@-*/
68
 
69
  /**@+
70
  * Agent forwarding status
77
  define('SYSTEM_SSH_AGENT_FORWARD_REQUEST', 1);
78
  // forwarding has been request and is active
79
  define('SYSTEM_SSH_AGENT_FORWARD_ACTIVE', 2);
80
+ /**#@-*/
81
 
82
+ /**@+
83
+ * Signature Flags
84
+ *
85
+ * See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3
86
+ *
87
+ * @access private
88
+ */
89
+ define('SYSTEM_SSH_AGENT_RSA2_256', 2);
90
+ define('SYSTEM_SSH_AGENT_RSA2_512', 4);
91
  /**#@-*/
92
 
93
  /**
133
  */
134
  var $fsock;
135
 
136
+ /**
137
+ * Signature flags
138
+ *
139
+ * @var int
140
+ * @access private
141
+ * @see self::sign()
142
+ * @see self::setHash()
143
+ */
144
+ var $flags = 0;
145
+
146
  /**
147
  * Default Constructor.
148
  *
222
  {
223
  }
224
 
225
+ /**
226
+ * Set Hash
227
+ *
228
+ * ssh-agent doesn't support using hashes for RSA other than SHA1
229
+ *
230
+ * @param string $hash
231
+ * @access public
232
+ */
233
+ function setHash($hash)
234
+ {
235
+ $this->flags = 0;
236
+ switch ($hash) {
237
+ case 'sha1':
238
+ break;
239
+ case 'sha256':
240
+ $this->flags = SYSTEM_SSH_AGENT_RSA2_256;
241
+ break;
242
+ case 'sha512':
243
+ $this->flags = SYSTEM_SSH_AGENT_RSA2_512;
244
+ break;
245
+ default:
246
+ user_error('The only supported hashes for RSA are sha1, sha256 and sha512');
247
+ }
248
+ }
249
+
250
  /**
251
  * Create a signature
252
  *
259
  function sign($message)
260
  {
261
  // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
262
+ $packet = pack('CNa*Na*N', SYSTEM_SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags);
263
  $packet = pack('Na*', strlen($packet), $packet);
264
  if (strlen($packet) != fputs($this->fsock, $packet)) {
265
  user_error('Connection closed during signing');
266
+ return false;
267
  }
268
 
269
+ $temp = fread($this->fsock, 4);
270
+ if (strlen($temp) != 4) {
271
+ user_error('Connection closed during signing');
272
+ return false;
273
+ }
274
+ $length = current(unpack('N', $temp));
275
  $type = ord(fread($this->fsock, 1));
276
  if ($type != SYSTEM_SSH_AGENT_SIGN_RESPONSE) {
277
  user_error('Unable to retreive signature');
278
+ return false;
279
  }
280
 
281
  $signature_blob = fread($this->fsock, $length - 1);
282
+ if (strlen($signature_blob) != $length - 1) {
283
+ user_error('Connection closed during signing');
284
+ return false;
285
+ }
286
+ $length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
287
+ if ($length != strlen($signature_blob)) {
288
+ user_error('Malformed signature blob');
289
+ return false;
290
+ }
291
+ $length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
292
+ if ($length > strlen($signature_blob) + 4) {
293
+ user_error('Malformed signature blob');
294
+ return false;
295
+ }
296
+ $type = $this->_string_shift($signature_blob, $length);
297
+ $this->_string_shift($signature_blob, 4);
298
+
299
+ return $signature_blob;
300
+ }
301
+
302
+ /**
303
+ * String Shift
304
+ *
305
+ * Inspired by array_shift
306
+ *
307
+ * @param string $string
308
+ * @param int $index
309
+ * @return string
310
+ * @access private
311
+ */
312
+ function _string_shift(&$string, $index = 1)
313
+ {
314
+ $substr = substr($string, 0, $index);
315
+ $string = substr($string, $index);
316
+ return $substr;
317
  }
318
  }
319
 
324
  *
325
  * @package System_SSH_Agent
326
  * @author Jim Wigginton <terrafrost@php.net>
327
+ * @access public
328
  */
329
  class System_SSH_Agent
330
  {
365
  * @return System_SSH_Agent
366
  * @access public
367
  */
368
+ function __construct($address = null)
369
  {
370
+ if (!$address) {
371
+ switch (true) {
372
+ case isset($_SERVER['SSH_AUTH_SOCK']):
373
+ $address = $_SERVER['SSH_AUTH_SOCK'];
374
+ break;
375
+ case isset($_ENV['SSH_AUTH_SOCK']):
376
+ $address = $_ENV['SSH_AUTH_SOCK'];
377
+ break;
378
+ default:
379
+ user_error('SSH_AUTH_SOCK not found');
380
+ return false;
381
+ }
382
  }
383
 
384
  $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
393
  * @see self::__construct()
394
  * @access public
395
  */
396
+ function System_SSH_Agent($address = null)
397
  {
398
+ $this->__construct($address);
399
  }
400
 
401
  /**
416
  $packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
417
  if (strlen($packet) != fputs($this->fsock, $packet)) {
418
  user_error('Connection closed while requesting identities');
419
+ return array();
420
  }
421
 
422
+ $temp = fread($this->fsock, 4);
423
+ if (strlen($temp) != 4) {
424
+ user_error('Connection closed while requesting identities');
425
+ return array();
426
+ }
427
+ $length = current(unpack('N', $temp));
428
  $type = ord(fread($this->fsock, 1));
429
  if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
430
  user_error('Unable to request identities');
431
+ return array();
432
  }
433
 
434
  $identities = array();
435
+ $temp = fread($this->fsock, 4);
436
+ if (strlen($temp) != 4) {
437
+ user_error('Connection closed while requesting identities');
438
+ return array();
439
+ }
440
+ $keyCount = current(unpack('N', $temp));
441
  for ($i = 0; $i < $keyCount; $i++) {
442
+ $temp = fread($this->fsock, 4);
443
+ if (strlen($temp) != 4) {
444
+ user_error('Connection closed while requesting identities');
445
+ return array();
446
+ }
447
+ $length = current(unpack('N', $temp));
448
  $key_blob = fread($this->fsock, $length);
449
+ if (strlen($key_blob) != $length) {
450
+ user_error('Connection closed while requesting identities');
451
+ return array();
452
+ }
453
  $key_str = 'ssh-rsa ' . base64_encode($key_blob);
454
+ $temp = fread($this->fsock, 4);
455
+ if (strlen($temp) != 4) {
456
+ user_error('Connection closed while requesting identities');
457
+ return array();
458
+ }
459
+ $length = current(unpack('N', $temp));
460
  if ($length) {
461
+ $temp = fread($this->fsock, $length);
462
+ if (strlen($temp) != $length) {
463
+ user_error('Connection closed while requesting identities');
464
+ return array();
465
+ }
466
+ $key_str.= ' ' . $temp;
467
  }
468
  $length = current(unpack('N', substr($key_blob, 0, 4)));
469
  $key_type = substr($key_blob, 4, $length);
588
 
589
  if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
590
  user_error('Connection closed attempting to forward data to SSH agent');
591
+ return false;
592
  }
593
 
594
  $this->socket_buffer = '';
595
  $this->expected_bytes = 0;
596
 
597
+ $temp = fread($this->fsock, 4);
598
+ if (strlen($temp) != 4) {
599
+ user_error('Connection closed while reading data response');
600
+ return false;
601
+ }
602
+ $agent_reply_bytes = current(unpack('N', $temp));
603
 
604
  $agent_reply_data = fread($this->fsock, $agent_reply_bytes);
605
+ if (strlen($agent_reply_data) != $agent_reply_bytes) {
606
+ user_error('Connection closed while reading data response');
607
+ return false;
608
+ }
609
  $agent_reply_data = current(unpack('a*', $agent_reply_data));
610
 
611
  return pack('Na*', $agent_reply_bytes, $agent_reply_data);
lib/phpseclib/phpseclib/phpseclib/bootstrap.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Bootstrapping File for phpseclib
4
  *
1
  <?php
2
+ return array();
3
  /**
4
  * Bootstrapping File for phpseclib
5
  *
lib/sftp.php CHANGED
@@ -294,7 +294,7 @@ class IWP_MMB_RemoteStorage_sftp extends IWP_MMB_RemoteStorage_Extension {
294
  * @param Boolean $debug - debugging mode: will ask phpseclib to log (which, being controlled by constants, may not be possible if they are already set)
295
  * @return WP_Error|Net_SSH2|Net_SCP
296
  */
297
- public function connect($host, $port = 22, $fingerprint, $user, $pass = '', $key = '', $scp = false, $debug = false) {
298
 
299
  global $iwp_backup_core;
300
  $this->scp = $scp;
294
  * @param Boolean $debug - debugging mode: will ask phpseclib to log (which, being controlled by constants, may not be possible if they are already set)
295
  * @return WP_Error|Net_SSH2|Net_SCP
296
  */
297
+ public function connect($host, $port = 22, $fingerprint='', $user='', $pass = '', $key = '', $scp = false, $debug = false) {
298
 
299
  global $iwp_backup_core;
300
  $this->scp = $scp;
pclzip.class.php CHANGED
@@ -2570,17 +2570,19 @@ endif;
2570
  {
2571
  foreach($exclude_extensions as $ext)
2572
  {
2573
- $this_pos = strrpos($this_base_name, $ext);
2574
- if($this_pos !== false)
2575
- {
2576
- if(substr($this_base_name, $this_pos) == $ext)
2577
- {
2578
- //$files_excluded_by_size[] = substr($value, strlen(ABSPATH));
2579
- $skip_after_ext = true; //to skip the file exclude by size
2580
- break;
2581
- }
2582
- }
2583
- }
 
 
2584
  }
2585
  if($skip_after_ext)
2586
  {
2570
  {
2571
  foreach($exclude_extensions as $ext)
2572
  {
2573
+ if(!empty($ext)){
2574
+ $this_pos = strrpos($this_base_name, $ext);
2575
+ if($this_pos !== false)
2576
+ {
2577
+ if(substr($this_base_name, $this_pos) == $ext)
2578
+ {
2579
+ //$files_excluded_by_size[] = substr($value, strlen(ABSPATH));
2580
+ $skip_after_ext = true; //to skip the file exclude by size
2581
+ break;
2582
+ }
2583
+ }
2584
+ }
2585
+ }
2586
  }
2587
  if($skip_after_ext)
2588
  {
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: infinitewp
3
  Tags: admin, administration, amazon, api, authentication, automatic, dashboard, dropbox, events, integration, manage, multisite, multiple, notification, performance, s3, security, seo, stats, tracking, infinitewp, updates, backup, restore, iwp, infinite
4
  Requires at least: 3.1
5
- Tested up to: 5.6
6
  Stable tag: trunk
7
 
8
  Install this plugin on unlimited sites and manage them all from a central dashboard.
@@ -48,6 +48,22 @@ Credits: [Vladimir Prelovac](http://prelovac.com/vladimir) for his worker plugin
48
 
49
  == Changelog ==
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  = 1.9.4.8.2 - Dec 2nd 2020 =
52
  * Improvement: Improved support for the recent WordPress DB update
53
  * Fix: Percentage ( % ) converted to random string after Restore the single call backup in certain databases
2
  Contributors: infinitewp
3
  Tags: admin, administration, amazon, api, authentication, automatic, dashboard, dropbox, events, integration, manage, multisite, multiple, notification, performance, s3, security, seo, stats, tracking, infinitewp, updates, backup, restore, iwp, infinite
4
  Requires at least: 3.1
5
+ Tested up to: 5.7.2
6
  Stable tag: trunk
7
 
8
  Install this plugin on unlimited sites and manage them all from a central dashboard.
48
 
49
  == Changelog ==
50
 
51
+ = 1.9.4.11 - Jun 16th 2021 =
52
+ * Improvement: Amazon s3 library updated.
53
+ * Improvement: Wordfence data not correctly showing in Client report due to the Wordfence recent release.
54
+ * Improvement: wp_new_user_notification function deprecated arg removed.
55
+ * Improvement: New constant (IWP_PHP_DB_ROWS) introduced on the WordPress site to take more row in the PHP database dump backup method.
56
+ * Improvement: If MySQL Dump fails, the admin panel will automatically retry MySQL Dump with a different 'max_allowed_packet' value.
57
+ * Improvement: Added a few locations for the MySQL dump command.
58
+ * Improvement: Multicall method backup speed enhanced.
59
+ * Improvement: Enabled support for "Exclude file size" in Phoenix method backup.
60
+ * Fix: Multiple Deprecated notices and Warnings when backing up a site (installed on a server with PHP8) using all backup methods.
61
+ * Fix: Fatal errors due to disabled PHP functions on certain hosting providers.
62
+ * Fix: WP Option cache causing issue in Phoenix backup on certain servers.
63
+ * Fix: MySQL Dump using 'passthru()' function not working both single and multicall method.
64
+ * Fix: MySQL Dump not working if 'max_allowed_packet' size has low value.
65
+ * Fix: open_basedir warning fixed.
66
+
67
  = 1.9.4.8.2 - Dec 2nd 2020 =
68
  * Improvement: Improved support for the recent WordPress DB update
69
  * Fix: Percentage ( % ) converted to random string after Restore the single call backup in certain databases
stats.class.php CHANGED
@@ -567,7 +567,9 @@ class IWP_MMB_Stats extends IWP_MMB_Core
567
  $stats = array();
568
 
569
  $current = get_site_transient( 'update_plugins' );
570
- $r = $current->response['iwp-client/init.php'];
 
 
571
  //For BWP
572
  $bwp = get_option("bit51_bwps");
573
  $wp_admin_URL=admin_url();
@@ -589,8 +591,10 @@ class IWP_MMB_Stats extends IWP_MMB_Core
589
  $stats['content_path'] = WP_CONTENT_DIR;
590
  $stats['client_path'] = $iwp_mmb_plugin_dir;
591
  $stats['client_version'] = IWP_MMB_CLIENT_VERSION;
592
- $stats['client_new_version'] = $r->new_version;
593
- $stats['client_new_package'] = $r->package;
 
 
594
  $stats['site_title'] = get_bloginfo('name');
595
  $stats['site_tagline'] = get_bloginfo('description');
596
  $stats['site_home'] = get_option('home');
567
  $stats = array();
568
 
569
  $current = get_site_transient( 'update_plugins' );
570
+ if (isset($current->response['iwp-client/init.php'])) {
571
+ $r = $current->response['iwp-client/init.php'];
572
+ }
573
  //For BWP
574
  $bwp = get_option("bit51_bwps");
575
  $wp_admin_URL=admin_url();
591
  $stats['content_path'] = WP_CONTENT_DIR;
592
  $stats['client_path'] = $iwp_mmb_plugin_dir;
593
  $stats['client_version'] = IWP_MMB_CLIENT_VERSION;
594
+ if (!empty($r)) {
595
+ $stats['client_new_version'] = $r->new_version;
596
+ $stats['client_new_package'] = $r->package;
597
+ }
598
  $stats['site_title'] = get_bloginfo('name');
599
  $stats['site_tagline'] = get_bloginfo('description');
600
  $stats['site_home'] = get_option('home');