SEOPress - Version 5.4.4

Version Description

  • FIX Guzzle conflict
  • FIX AIOSEO import tool
Download this release

Release Info

Developer rainbowgeek
Plugin Icon 128x128 SEOPress
Version 5.4.4
Comparing to
See all releases

Code changes from version 5.4.3 to 5.4.4

Files changed (34) hide show
  1. inc/admin/ajax-migrate/aio.php +0 -216
  2. inc/admin/ajax.php +0 -1
  3. inc/admin/callbacks/InstantIndexing.php +1 -0
  4. inc/functions/options-instant-indexing.php +1 -0
  5. readme.txt +4 -1
  6. seopress-autoload.php +31 -0
  7. seopress.php +4 -3
  8. src/Actions/Admin/Importer/AIO.php +243 -0
  9. src/Thirds/AIO/Tags.php +78 -0
  10. vendor/autoload.php +1 -1
  11. vendor/composer/autoload_real.php +7 -7
  12. vendor/composer/autoload_static.php +4 -4
  13. vendor/composer/installed.json +14 -14
  14. vendor/composer/installed.php +8 -8
  15. vendor/google/apiclient-services/synth.metadata +2 -2
  16. vendor/phpseclib/phpseclib/BACKERS.md +4 -1
  17. vendor/phpseclib/phpseclib/README.md +2 -2
  18. vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php +17 -10
  19. vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php +7 -1
  20. vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php +113 -2
  21. vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php +2 -2
  22. vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php +2 -2
  23. vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php +1 -1
  24. vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php +1 -1
  25. vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php +3 -1
  26. vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php +1 -1
  27. vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php +4 -2
  28. vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php +1 -1
  29. vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php +1 -1
  30. vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php +5 -0
  31. vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php +32 -21
  32. vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php +1 -1
  33. vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php +210 -116
  34. vendor/phpseclib/phpseclib/psalm.xml +29 -0
inc/admin/ajax-migrate/aio.php DELETED
@@ -1,216 +0,0 @@
1
- <?php
2
-
3
- defined('ABSPATH') or exit('Please don&rsquo;t call the plugin directly. Thanks :)');
4
-
5
- ///////////////////////////////////////////////////////////////////////////////////////////////////
6
- //AIO migration
7
- ///////////////////////////////////////////////////////////////////////////////////////////////////
8
- function seopress_aio_migration()
9
- {
10
- check_ajax_referer('seopress_aio_migrate_nonce', $_POST['_ajax_nonce'], true);
11
-
12
- if (current_user_can(seopress_capability('manage_options', 'migration')) && is_admin()) {
13
- if (isset($_POST['offset']) && isset($_POST['offset'])) {
14
- $offset = absint($_POST['offset']);
15
- }
16
-
17
- global $wpdb;
18
- $total_count_posts = (int) $wpdb->get_var("SELECT count(*) FROM {$wpdb->posts}");
19
-
20
- $increment = 200;
21
- global $post;
22
-
23
- if ($offset > $total_count_posts) {
24
- $offset = 'done';
25
- wp_reset_query();
26
- } else {
27
- $args = [
28
- 'posts_per_page' => $increment,
29
- 'post_type' => 'any',
30
- 'post_status' => 'any',
31
- 'offset' => $offset,
32
- ];
33
-
34
- $aio_query = get_posts($args);
35
-
36
- if ($aio_query) {
37
- foreach ($aio_query as $post) {
38
- if ('' != get_post_meta($post->ID, '_aioseo_title', true)) { //Import title tag
39
- update_post_meta($post->ID, '_seopress_titles_title', get_post_meta($post->ID, '_aioseo_title', true));
40
- } elseif ('' != get_post_meta($post->ID, '_aioseop_title', true)) { //Import old title tag
41
- update_post_meta($post->ID, '_seopress_titles_title', get_post_meta($post->ID, '_aioseop_title', true));
42
- }
43
- if ('' != get_post_meta($post->ID, '_aioseo_description', true)) { //Import meta desc
44
- update_post_meta($post->ID, '_seopress_titles_desc', get_post_meta($post->ID, '_aioseo_description', true));
45
- } elseif ('' != get_post_meta($post->ID, '_aioseop_description', true)) { //Import old meta desc
46
- update_post_meta($post->ID, '_seopress_titles_desc', get_post_meta($post->ID, '_aioseop_description', true));
47
- }
48
-
49
- if ('' != get_post_meta($post->ID, '_aioseo_og_title', true)) { //Import Facebook Title
50
- update_post_meta($post->ID, '_seopress_social_fb_title', get_post_meta($post->ID, '_aioseo_og_title', true));
51
- } elseif ('' != get_post_meta($post->ID, '_aioseop_opengraph_settings', true)) { //Import old Facebook
52
- $_aioseop_opengraph_settings = get_post_meta($post->ID, '_aioseop_opengraph_settings', true);
53
- if (isset($_aioseop_opengraph_settings['aioseop_opengraph_settings_title'])) {
54
- update_post_meta($post->ID, '_seopress_social_fb_title', $_aioseop_opengraph_settings['aioseop_opengraph_settings_title']);
55
- }
56
- }
57
-
58
- if ('' != get_post_meta($post->ID, '_aioseo_twitter_title', true)) { //Import Twitter Title
59
- update_post_meta($post->ID, '_seopress_social_twitter_title', get_post_meta($post->ID, '_aioseo_twitter_title', true));
60
- } elseif ('' != get_post_meta($post->ID, '_aioseop_opengraph_settings', true)) { //Import old Twitter Title
61
- $_aioseop_opengraph_settings = get_post_meta($post->ID, '_aioseop_opengraph_settings', true);
62
- if (isset($_aioseop_opengraph_settings['aioseop_opengraph_settings_title'])) {
63
- update_post_meta($post->ID, '_seopress_social_twitter_title', $_aioseop_opengraph_settings['aioseop_opengraph_settings_title']);
64
- }
65
- }
66
-
67
- if ('' != get_post_meta($post->ID, '_aioseo_og_description', true)) { //Import Facebook Desc
68
- update_post_meta($post->ID, '_seopress_social_fb_desc', get_post_meta($post->ID, '_aioseo_og_description', true));
69
- } elseif ('' != get_post_meta($post->ID, '_aioseop_opengraph_settings', true)) { //Import old Facebook Desc
70
- $_aioseop_opengraph_settings = get_post_meta($post->ID, '_aioseop_opengraph_settings', true);
71
- if (isset($_aioseop_opengraph_settings['aioseop_opengraph_settings_title'])) {
72
- update_post_meta($post->ID, '_seopress_social_fb_desc', $_aioseop_opengraph_settings['aioseop_opengraph_settings_title']);
73
- }
74
- }
75
-
76
- if ('' != get_post_meta($post->ID, '_aioseo_twitter_description', true)) { //Import Twitter Desc
77
- update_post_meta($post->ID, '_seopress_social_twitter_desc', get_post_meta($post->ID, '_aioseo_twitter_description', true));
78
- } elseif ('' != get_post_meta($post->ID, '_aioseop_opengraph_settings', true)) { //Import old Twitter Desc
79
- $_aioseop_opengraph_settings = get_post_meta($post->ID, '_aioseop_opengraph_settings', true);
80
- if (isset($_aioseop_opengraph_settings['aioseop_opengraph_settings_title'])) {
81
- update_post_meta($post->ID, '_seopress_social_twitter_desc', $_aioseop_opengraph_settings['aioseop_opengraph_settings_title']);
82
- }
83
- }
84
-
85
- $canonical_url = "SELECT p.canonical_url, p.post_id
86
- FROM {$wpdb->prefix}aioseo_posts p
87
- WHERE p.post_id = $post->ID";
88
-
89
- $canonical_url = $wpdb->get_results($canonical_url, ARRAY_A);
90
-
91
- if (! empty($canonical_url[0]['canonical_url'])) {//Import Canonical URL
92
- update_post_meta($post->ID, '_seopress_robots_canonical', $canonical_url[0]['canonical_url']);
93
- }
94
-
95
- $og_img_url = "SELECT p.og_image_custom_url, p.post_id
96
- FROM {$wpdb->prefix}aioseo_posts p
97
- WHERE p.og_image_type = 'custom_image' AND p.post_id = $post->ID";
98
-
99
- $og_img_url = $wpdb->get_results($og_img_url, ARRAY_A);
100
-
101
- if (! empty($og_img_url[0]['og_image_custom_url'])) {//Import Facebook Image
102
- update_post_meta($post->ID, '_seopress_social_fb_img', $og_img_url[0]['og_image_custom_url']);
103
- } elseif ('' != get_post_meta($post->ID, '_aioseop_opengraph_settings', true)) { //Import old Facebook Image
104
- $_aioseop_opengraph_settings = get_post_meta($post->ID, '_aioseop_opengraph_settings', true);
105
- if (isset($_aioseop_opengraph_settings['aioseop_opengraph_settings_image'])) {
106
- update_post_meta($post->ID, '_seopress_social_fb_img', $_aioseop_opengraph_settings['aioseop_opengraph_settings_customimg']);
107
- }
108
- }
109
-
110
- $tw_img_url = "SELECT p.twitter_image_custom_url, p.post_id
111
- FROM {$wpdb->prefix}aioseo_posts p
112
- WHERE p.twitter_image_type = 'custom_image' AND p.post_id = $post->ID";
113
-
114
- $tw_img_url = $wpdb->get_results($tw_img_url, ARRAY_A);
115
-
116
- if (! empty($tw_img_url[0]['twitter_image_custom_url'])) {//Import Twitter Image
117
- update_post_meta($post->ID, '_seopress_social_twitter_img', $tw_img_url[0]['twitter_image_custom_url']);
118
- } elseif ('' != get_post_meta($post->ID, '_aioseop_opengraph_settings', true)) { //Import old Twitter Image
119
- $_aioseop_opengraph_settings = get_post_meta($post->ID, '_aioseop_opengraph_settings', true);
120
- if (isset($_aioseop_opengraph_settings['aioseop_opengraph_settings_customimg_twitter'])) {
121
- update_post_meta($post->ID, '_seopress_social_twitter_img', $_aioseop_opengraph_settings['aioseop_opengraph_settings_customimg_twitter']);
122
- }
123
- }
124
-
125
- $robots_noindex = "SELECT p.robots_noindex, p.post_id
126
- FROM {$wpdb->prefix}aioseo_posts p
127
- WHERE p.post_id = $post->ID";
128
-
129
- $robots_noindex = $wpdb->get_results($robots_noindex, ARRAY_A);
130
-
131
- if (! empty($robots_noindex[0]['robots_noindex']) && '1' === $robots_noindex[0]['robots_noindex']) {//Import Robots NoIndex
132
- update_post_meta($post->ID, '_seopress_robots_index', 'yes');
133
- } elseif ('on' == get_post_meta($post->ID, '_aioseop_noindex', true)) { //Import old Robots NoIndex
134
- update_post_meta($post->ID, '_seopress_robots_index', 'yes');
135
- }
136
-
137
- $robots_nofollow = "SELECT p.robots_nofollow, p.post_id
138
- FROM {$wpdb->prefix}aioseo_posts p
139
- WHERE p.post_id = $post->ID";
140
-
141
- $robots_nofollow = $wpdb->get_results($robots_nofollow, ARRAY_A);
142
-
143
- if (! empty($robots_nofollow[0]['robots_nofollow']) && '1' === $robots_nofollow[0]['robots_nofollow']) {//Import Robots NoFollow
144
- update_post_meta($post->ID, '_seopress_robots_follow', 'yes');
145
- } elseif ('on' == get_post_meta($post->ID, '_aioseop_nofollow', true)) { //Import old Robots NoFollow
146
- update_post_meta($post->ID, '_seopress_robots_follow', 'yes');
147
- }
148
-
149
- $robots_noimageindex = "SELECT p.robots_noimageindex, p.post_id
150
- FROM {$wpdb->prefix}aioseo_posts p
151
- WHERE p.post_id = $post->ID";
152
-
153
- $robots_noimageindex = $wpdb->get_results($robots_noimageindex, ARRAY_A);
154
-
155
- if (! empty($robots_noimageindex[0]['robots_noimageindex']) && '1' === $robots_noimageindex[0]['robots_noimageindex']) {//Import Robots NoImageIndex
156
- update_post_meta($post->ID, '_seopress_robots_imageindex', 'yes');
157
- }
158
-
159
- $robots_noodp = "SELECT p.robots_noodp, p.post_id
160
- FROM {$wpdb->prefix}aioseo_posts p
161
- WHERE p.post_id = $post->ID";
162
-
163
- $robots_noodp = $wpdb->get_results($robots_noodp, ARRAY_A);
164
-
165
- if (! empty($robots_noodp[0]['robots_noodp']) && '1' === $robots_noodp[0]['robots_noodp']) {//Import Robots NoOdp
166
- update_post_meta($post->ID, '_seopress_robots_odp', 'yes');
167
- }
168
-
169
- $robots_nosnippet = "SELECT p.robots_nosnippet, p.post_id
170
- FROM {$wpdb->prefix}aioseo_posts p
171
- WHERE p.post_id = $post->ID";
172
-
173
- $robots_nosnippet = $wpdb->get_results($robots_nosnippet, ARRAY_A);
174
-
175
- if (! empty($robots_nosnippet[0]['robots_nosnippet']) && '1' === $robots_nosnippet[0]['robots_nosnippet']) {//Import Robots NoSnippet
176
- update_post_meta($post->ID, '_seopress_robots_snippet', 'yes');
177
- }
178
-
179
- $robots_noarchive = "SELECT p.robots_noarchive, p.post_id
180
- FROM {$wpdb->prefix}aioseo_posts p
181
- WHERE p.post_id = $post->ID";
182
-
183
- $robots_noarchive = $wpdb->get_results($robots_noarchive, ARRAY_A);
184
-
185
- if (! empty($robots_noarchive[0]['robots_noarchive']) && '1' === $robots_noarchive[0]['robots_noarchive']) {//Import Robots NoArchive
186
- update_post_meta($post->ID, '_seopress_robots_archive', 'yes');
187
- }
188
-
189
- $keyphrases = "SELECT p.keyphrases, p.post_id
190
- FROM {$wpdb->prefix}aioseo_posts p
191
- WHERE p.post_id = $post->ID";
192
-
193
- $keyphrases = $wpdb->get_results($keyphrases, ARRAY_A);
194
-
195
- if (! empty($keyphrases)) {
196
- $keyphrases = json_decode($keyphrases[0]['keyphrases']);
197
-
198
- if (isset($keyphrases->focus->keyphrase)) {
199
- $keyphrases = $keyphrases->focus->keyphrase;
200
-
201
- if ('' != $keyphrases) { //Import focus kw
202
- update_post_meta($post->ID, '_seopress_analysis_target_kw', $keyphrases);
203
- }
204
- }
205
- }
206
- }
207
- }
208
- $offset += $increment;
209
- }
210
- $data = [];
211
- $data['offset'] = $offset;
212
- wp_send_json_success($data);
213
- exit();
214
- }
215
- }
216
- add_action('wp_ajax_seopress_aio_migration', 'seopress_aio_migration');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/ajax.php CHANGED
@@ -696,5 +696,4 @@ require_once __DIR__ . '/ajax-migrate/wp-meta-seo.php';
696
  require_once __DIR__ . '/ajax-migrate/seo-ultimate.php';
697
  require_once __DIR__ . '/ajax-migrate/squirrly.php';
698
  require_once __DIR__ . '/ajax-migrate/seo-framework.php';
699
- require_once __DIR__ . '/ajax-migrate/aio.php';
700
  require_once __DIR__ . '/ajax-migrate/yoast.php';
696
  require_once __DIR__ . '/ajax-migrate/seo-ultimate.php';
697
  require_once __DIR__ . '/ajax-migrate/squirrly.php';
698
  require_once __DIR__ . '/ajax-migrate/seo-framework.php';
 
699
  require_once __DIR__ . '/ajax-migrate/yoast.php';
inc/admin/callbacks/InstantIndexing.php CHANGED
@@ -73,6 +73,7 @@ function seopress_instant_indexing_google_action_callback() {
73
  }
74
 
75
  function seopress_instant_indexing_manual_batch_callback() {
 
76
  $options = get_option('seopress_instant_indexing_option_name');
77
  $log = get_option('seopress_instant_indexing_log_option_name');
78
  $check = isset($options['seopress_instant_indexing_manual_batch']) ? esc_attr($options['seopress_instant_indexing_manual_batch']) : null;
73
  }
74
 
75
  function seopress_instant_indexing_manual_batch_callback() {
76
+ require_once WP_PLUGIN_DIR . '/wp-seopress/vendor/autoload.php';
77
  $options = get_option('seopress_instant_indexing_option_name');
78
  $log = get_option('seopress_instant_indexing_log_option_name');
79
  $check = isset($options['seopress_instant_indexing_manual_batch']) ? esc_attr($options['seopress_instant_indexing_manual_batch']) : null;
inc/functions/options-instant-indexing.php CHANGED
@@ -174,6 +174,7 @@ function seopress_instant_indexing_fn() {
174
  function seopress_instant_indexing_post()
175
  {
176
  check_ajax_referer('seopress_instant_indexing_post_nonce');
 
177
  if (current_user_can(seopress_capability('manage_options', 'instant-indexing')) && is_admin()) {
178
  seopress_instant_indexing_fn();
179
  }
174
  function seopress_instant_indexing_post()
175
  {
176
  check_ajax_referer('seopress_instant_indexing_post_nonce');
177
+ require_once WP_PLUGIN_DIR . '/wp-seopress/vendor/autoload.php';
178
  if (current_user_can(seopress_capability('manage_options', 'instant-indexing')) && is_admin()) {
179
  seopress_instant_indexing_fn();
180
  }
readme.txt CHANGED
@@ -6,7 +6,7 @@ Tags: SEO, schema, xml sitemap, redirection, meta title, open graph, content ana
6
  Requires at least: 4.7+
7
  Tested up to: 5.9
8
  Requires PHP: 7.2
9
- Stable tag: 5.4.3
10
  License: GPLv2 or later
11
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
12
 
@@ -338,6 +338,9 @@ You're theme is probably using a deprecated function to handle the title. <a hre
338
  12. Schema metabox
339
 
340
  == Changelog ==
 
 
 
341
  = 5.4.3 =
342
  * FIX Warning: use statement with non-compound name
343
  = 5.4.2 =
6
  Requires at least: 4.7+
7
  Tested up to: 5.9
8
  Requires PHP: 7.2
9
+ Stable tag: 5.4.4
10
  License: GPLv2 or later
11
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
12
 
338
  12. Schema metabox
339
 
340
  == Changelog ==
341
+ = 5.4.4 =
342
+ * FIX Guzzle conflict
343
+ * FIX AIOSEO import tool
344
  = 5.4.3 =
345
  * FIX Warning: use statement with non-compound name
346
  = 5.4.2 =
seopress-autoload.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ defined('ABSPATH') or exit('Please don&rsquo;t call the plugin directly. Thanks :)');
4
+
5
+ spl_autoload_register(function ($class) {
6
+ // project-specific namespace prefix
7
+ $prefix = 'SEOPress\\';
8
+
9
+ // base directory for the namespace prefix
10
+ $base_dir = __DIR__ . '/src/';
11
+
12
+ // does the class use the namespace prefix?
13
+ $len = strlen($prefix);
14
+ if (0 !== strncmp($prefix, $class, $len)) {
15
+ // no, move to the next registered autoloader
16
+ return;
17
+ }
18
+
19
+ // get the relative class name
20
+ $relative_class = substr($class, $len);
21
+
22
+ // replace the namespace prefix with the base directory, replace namespace
23
+ // separators with directory separators in the relative class name, append
24
+ // with .php
25
+ $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
26
+
27
+ // if the file exists, require it
28
+ if (file_exists($file)) {
29
+ require $file;
30
+ }
31
+ });
seopress.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: SEOPress
4
  Plugin URI: https://www.seopress.org/
5
  Description: One of the best SEO plugins for WordPress.
6
  Author: SEOPress
7
- Version: 5.4.3
8
  Author URI: https://www.seopress.org/
9
  License: GPLv2
10
  Text Domain: wp-seopress
@@ -70,7 +70,7 @@ register_deactivation_hook(__FILE__, 'seopress_deactivation');
70
  ///////////////////////////////////////////////////////////////////////////////////////////////////
71
  //Define
72
  ///////////////////////////////////////////////////////////////////////////////////////////////////
73
- define('SEOPRESS_VERSION', '5.4.3');
74
  define('SEOPRESS_AUTHOR', 'Benjamin Denis');
75
  define('SEOPRESS_PLUGIN_DIR_PATH', plugin_dir_path(__FILE__));
76
  define('SEOPRESS_PLUGIN_DIR_URL', plugin_dir_url(__FILE__));
@@ -86,8 +86,9 @@ define('SEOPRESS_DIR_LANGUAGES', dirname(plugin_basename(__FILE__)) . '/language
86
 
87
  use SEOPress\Core\Kernel;
88
 
 
 
89
  if (file_exists(__DIR__ . '/vendor/autoload.php')) {
90
- require_once __DIR__ . '/vendor/autoload.php';
91
  require_once __DIR__ . '/seopress-functions.php';
92
  require_once __DIR__ . '/inc/admin/cron.php';
93
 
4
  Plugin URI: https://www.seopress.org/
5
  Description: One of the best SEO plugins for WordPress.
6
  Author: SEOPress
7
+ Version: 5.4.4
8
  Author URI: https://www.seopress.org/
9
  License: GPLv2
10
  Text Domain: wp-seopress
70
  ///////////////////////////////////////////////////////////////////////////////////////////////////
71
  //Define
72
  ///////////////////////////////////////////////////////////////////////////////////////////////////
73
+ define('SEOPRESS_VERSION', '5.4.4');
74
  define('SEOPRESS_AUTHOR', 'Benjamin Denis');
75
  define('SEOPRESS_PLUGIN_DIR_PATH', plugin_dir_path(__FILE__));
76
  define('SEOPRESS_PLUGIN_DIR_URL', plugin_dir_url(__FILE__));
86
 
87
  use SEOPress\Core\Kernel;
88
 
89
+ require_once __DIR__ . '/seopress-autoload.php';
90
+
91
  if (file_exists(__DIR__ . '/vendor/autoload.php')) {
 
92
  require_once __DIR__ . '/seopress-functions.php';
93
  require_once __DIR__ . '/inc/admin/cron.php';
94
 
src/Actions/Admin/Importer/AIO.php ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace SEOPress\Actions\Admin\Importer;
4
+
5
+ defined('ABSPATH') or exit('Cheatin&#8217; uh?');
6
+
7
+ use SEOPress\Core\Hooks\ExecuteHooksBackend;
8
+ use SEOPress\Thirds\AIO\Tags;
9
+
10
+ class AIO implements ExecuteHooksBackend {
11
+ public function __construct() {
12
+ $this->tagsAIO = new Tags();
13
+ }
14
+
15
+ /**
16
+ * @since 4.3.0
17
+ *
18
+ * @return void
19
+ */
20
+ public function hooks() {
21
+ add_action('wp_ajax_seopress_aio_migration', [$this, 'process']);
22
+ }
23
+
24
+ /**
25
+ * @since 4.3.0
26
+ *
27
+ * @param int $offset
28
+ * @param int $increment
29
+ */
30
+ protected function migratePostQuery($offset, $increment) {
31
+ global $wpdb;
32
+ $args = [
33
+ 'posts_per_page' => $increment,
34
+ 'post_type' => 'testimonials',
35
+ 'post_status' => 'any',
36
+ 'offset' => $offset,
37
+ ];
38
+
39
+ $aio_query = get_posts($args);
40
+
41
+ if ( ! $aio_query) {
42
+ $offset += $increment;
43
+
44
+ return $offset;
45
+ }
46
+
47
+ $getPostMetas = [
48
+ '_seopress_titles_title' => '_aioseo_title',
49
+ '_seopress_titles_desc' => '_aioseo_description',
50
+ '_seopress_social_fb_title' => '_aioseo_og_title',
51
+ '_seopress_social_fb_desc' => '_aioseo_og_description',
52
+ '_seopress_social_twitter_title' => '_aioseo_twitter_title',
53
+ '_seopress_social_twitter_desc' => '_aioseo_twitter_description',
54
+ ];
55
+
56
+ foreach ($aio_query as $post) {
57
+ foreach ($getPostMetas as $key => $value) {
58
+ $metaAIO = get_post_meta($post->ID, $value, true);
59
+ if ( ! empty($metaAIO)) {
60
+ update_post_meta($post->ID, $key, $this->tagsAIO->replaceTags($metaAIO));
61
+ }
62
+ }
63
+
64
+ //Canonical URL
65
+ $canonical_url = "SELECT p.canonical_url, p.post_id
66
+ FROM {$wpdb->prefix}aioseo_posts p
67
+ WHERE p.post_id = $post->ID";
68
+
69
+ $canonical_url = $wpdb->get_results($canonical_url, ARRAY_A);
70
+
71
+ if (! empty($canonical_url[0]['canonical_url'])) {//Import Canonical URL
72
+ update_post_meta($post->ID, '_seopress_robots_canonical', $canonical_url[0]['canonical_url']);
73
+ }
74
+
75
+ //OG Image
76
+ $og_img_url = "SELECT p.og_image_custom_url, p.post_id
77
+ FROM {$wpdb->prefix}aioseo_posts p
78
+ WHERE p.og_image_type = 'custom_image' AND p.post_id = $post->ID";
79
+
80
+ $og_img_url = $wpdb->get_results($og_img_url, ARRAY_A);
81
+
82
+ if (! empty($og_img_url[0]['og_image_custom_url'])) {//Import Facebook Image
83
+ update_post_meta($post->ID, '_seopress_social_fb_img', $og_img_url[0]['og_image_custom_url']);
84
+ } elseif ('' != get_post_meta($post->ID, '_aioseop_opengraph_settings', true)) { //Import old Facebook Image
85
+ $_aioseop_opengraph_settings = get_post_meta($post->ID, '_aioseop_opengraph_settings', true);
86
+ if (isset($_aioseop_opengraph_settings['aioseop_opengraph_settings_image'])) {
87
+ update_post_meta($post->ID, '_seopress_social_fb_img', $_aioseop_opengraph_settings['aioseop_opengraph_settings_customimg']);
88
+ }
89
+ }
90
+
91
+ //Twitter Image
92
+ $tw_img_url = "SELECT p.twitter_image_custom_url, p.post_id
93
+ FROM {$wpdb->prefix}aioseo_posts p
94
+ WHERE p.twitter_image_type = 'custom_image' AND p.post_id = $post->ID";
95
+
96
+ $tw_img_url = $wpdb->get_results($tw_img_url, ARRAY_A);
97
+
98
+ if (! empty($tw_img_url[0]['twitter_image_custom_url'])) {//Import Twitter Image
99
+ update_post_meta($post->ID, '_seopress_social_twitter_img', $tw_img_url[0]['twitter_image_custom_url']);
100
+ } elseif ('' != get_post_meta($post->ID, '_aioseop_opengraph_settings', true)) { //Import old Twitter Image
101
+ $_aioseop_opengraph_settings = get_post_meta($post->ID, '_aioseop_opengraph_settings', true);
102
+ if (isset($_aioseop_opengraph_settings['aioseop_opengraph_settings_customimg_twitter'])) {
103
+ update_post_meta($post->ID, '_seopress_social_twitter_img', $_aioseop_opengraph_settings['aioseop_opengraph_settings_customimg_twitter']);
104
+ }
105
+ }
106
+
107
+ //Meta robots "noindex"
108
+ $robots_noindex = "SELECT p.robots_noindex, p.post_id
109
+ FROM {$wpdb->prefix}aioseo_posts p
110
+ WHERE p.post_id = $post->ID";
111
+
112
+ $robots_noindex = $wpdb->get_results($robots_noindex, ARRAY_A);
113
+
114
+ if (! empty($robots_noindex[0]['robots_noindex']) && '1' === $robots_noindex[0]['robots_noindex']) {//Import Robots NoIndex
115
+ update_post_meta($post->ID, '_seopress_robots_index', 'yes');
116
+ } elseif ('on' == get_post_meta($post->ID, '_aioseop_noindex', true)) { //Import old Robots NoIndex
117
+ update_post_meta($post->ID, '_seopress_robots_index', 'yes');
118
+ }
119
+
120
+ //Meta robots "nofollow"
121
+ $robots_nofollow = "SELECT p.robots_nofollow, p.post_id
122
+ FROM {$wpdb->prefix}aioseo_posts p
123
+ WHERE p.post_id = $post->ID";
124
+
125
+ $robots_nofollow = $wpdb->get_results($robots_nofollow, ARRAY_A);
126
+
127
+ if (! empty($robots_nofollow[0]['robots_nofollow']) && '1' === $robots_nofollow[0]['robots_nofollow']) {//Import Robots NoFollow
128
+ update_post_meta($post->ID, '_seopress_robots_follow', 'yes');
129
+ } elseif ('on' == get_post_meta($post->ID, '_aioseop_nofollow', true)) { //Import old Robots NoFollow
130
+ update_post_meta($post->ID, '_seopress_robots_follow', 'yes');
131
+ }
132
+
133
+ //Meta robots "noimageindex"
134
+ $robots_noimageindex = "SELECT p.robots_noimageindex, p.post_id
135
+ FROM {$wpdb->prefix}aioseo_posts p
136
+ WHERE p.post_id = $post->ID";
137
+
138
+ $robots_noimageindex = $wpdb->get_results($robots_noimageindex, ARRAY_A);
139
+
140
+ if (! empty($robots_noimageindex[0]['robots_noimageindex']) && '1' === $robots_noimageindex[0]['robots_noimageindex']) {//Import Robots NoImageIndex
141
+ update_post_meta($post->ID, '_seopress_robots_imageindex', 'yes');
142
+ }
143
+
144
+ //Meta robots "noodp"
145
+ $robots_noodp = "SELECT p.robots_noodp, p.post_id
146
+ FROM {$wpdb->prefix}aioseo_posts p
147
+ WHERE p.post_id = $post->ID";
148
+
149
+ $robots_noodp = $wpdb->get_results($robots_noodp, ARRAY_A);
150
+
151
+ if (! empty($robots_noodp[0]['robots_noodp']) && '1' === $robots_noodp[0]['robots_noodp']) {//Import Robots NoOdp
152
+ update_post_meta($post->ID, '_seopress_robots_odp', 'yes');
153
+ }
154
+
155
+ //Meta robots "nosnippet"
156
+ $robots_nosnippet = "SELECT p.robots_nosnippet, p.post_id
157
+ FROM {$wpdb->prefix}aioseo_posts p
158
+ WHERE p.post_id = $post->ID";
159
+
160
+ $robots_nosnippet = $wpdb->get_results($robots_nosnippet, ARRAY_A);
161
+
162
+ if (! empty($robots_nosnippet[0]['robots_nosnippet']) && '1' === $robots_nosnippet[0]['robots_nosnippet']) {//Import Robots NoSnippet
163
+ update_post_meta($post->ID, '_seopress_robots_snippet', 'yes');
164
+ }
165
+
166
+ //Meta robots "noarchive"
167
+ $robots_noarchive = "SELECT p.robots_noarchive, p.post_id
168
+ FROM {$wpdb->prefix}aioseo_posts p
169
+ WHERE p.post_id = $post->ID";
170
+
171
+ $robots_noarchive = $wpdb->get_results($robots_noarchive, ARRAY_A);
172
+
173
+ if (! empty($robots_noarchive[0]['robots_noarchive']) && '1' === $robots_noarchive[0]['robots_noarchive']) {//Import Robots NoArchive
174
+ update_post_meta($post->ID, '_seopress_robots_archive', 'yes');
175
+ }
176
+
177
+ //Target keywords
178
+ $keyphrases = "SELECT p.keyphrases, p.post_id
179
+ FROM {$wpdb->prefix}aioseo_posts p
180
+ WHERE p.post_id = $post->ID";
181
+
182
+ $keyphrases = $wpdb->get_results($keyphrases, ARRAY_A);
183
+
184
+ if (! empty($keyphrases)) {
185
+ $keyphrases = json_decode($keyphrases[0]['keyphrases']);
186
+
187
+ if (isset($keyphrases->focus->keyphrase)) {
188
+ $keyphrases = $keyphrases->focus->keyphrase;
189
+
190
+ if ('' != $keyphrases) { //Import focus kw
191
+ update_post_meta($post->ID, '_seopress_analysis_target_kw', $keyphrases);
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ $offset += $increment;
198
+
199
+ return $offset;
200
+ }
201
+
202
+ /**
203
+ * @since 4.3.0
204
+ */
205
+ public function process() {
206
+ check_ajax_referer('seopress_aio_migrate_nonce', $_POST['_ajax_nonce'], true);
207
+ if ( ! is_admin()) {
208
+ wp_send_json_error();
209
+
210
+ return;
211
+ }
212
+
213
+ if ( ! current_user_can(seopress_capability('manage_options', 'migration'))) {
214
+ wp_send_json_error();
215
+
216
+ return;
217
+ }
218
+
219
+ if (isset($_POST['offset'])) {
220
+ $offset = absint($_POST['offset']);
221
+ }
222
+
223
+ global $wpdb;
224
+ $total_count_posts = (int) $wpdb->get_var("SELECT count(*) FROM {$wpdb->posts}");
225
+
226
+ $increment = 200;
227
+ global $post;
228
+
229
+ if ($offset > $total_count_posts) {
230
+ $offset = 'done';
231
+ } else {
232
+ $offset = $this->migratePostQuery($offset, $increment);
233
+ }
234
+
235
+ $data = [];
236
+ $data['offset'] = $offset;
237
+
238
+ do_action('seopress_third_importer_aio', $offset, $increment);
239
+
240
+ wp_send_json_success($data);
241
+ exit();
242
+ }
243
+ }
src/Thirds/AIO/Tags.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace SEOPress\Thirds\AIO;
4
+
5
+ defined('ABSPATH') or exit('Cheatin&#8217; uh?');
6
+
7
+ use SEOPress\Helpers\TagCompose;
8
+
9
+ class Tags {
10
+ protected $variables = [
11
+ '#separator_sa' => 'sep',
12
+ '#site_title' => 'sitetitle',
13
+ '#tagline' => 'tagline',
14
+ '#post_title' => 'post_title',
15
+ '#author_first_name' => 'author_first_name',
16
+ '#author_last_name' => 'author_last_name',
17
+ '#author_last_name' => 'author_last_name',
18
+ '#author_name' => 'post_author',
19
+ '#taxonomy_title' => 'term_title',
20
+ '#current_date' => 'currentdate',
21
+ '#current_month' => 'currentmonth',
22
+ '#current_day' => 'currentday',
23
+ '#current_year' => 'currentyear',
24
+ '#permalink' => 'post_url',
25
+ '#post_content' => 'post_content',
26
+ '#post_excerpt_only' => 'post_excerpt',
27
+ '#post_excerpt' => 'post_excerpt',
28
+ '#post_date' => 'post_date',
29
+ '#post_day' => '',
30
+ '#post_month' => '',
31
+ '#post_year' => '',
32
+ '#custom_field-' => '_cf_',
33
+ '#tax_name-' => '_ct_',
34
+ ];
35
+
36
+ /**
37
+ * @since 5.5.0
38
+ *
39
+ * @param string $input
40
+ *
41
+ * @return string
42
+ */
43
+ public function replaceTags($input) {
44
+ foreach ($this->variables as $key => $value) {
45
+ if ( ! empty($value)) {
46
+
47
+ if ( $key === '#custom_field-') {
48
+ preg_match_all('/#custom_field-[^\s]*/', $input, $matches);
49
+
50
+ if ( ! empty($matches[0])) {
51
+ foreach($matches[0] as $_key => $_value) {
52
+ $new_tag = str_replace('#custom_field-', '_cf_', $_value);
53
+ $new_tag = TagCompose::getValueWithTag($new_tag);
54
+ $input = str_replace($_value, $new_tag, $input);
55
+ }
56
+ }
57
+ } elseif ( $key === '#tax_name-') {
58
+ preg_match_all('/#tax_name-[^\s]*/', $input, $matches);
59
+
60
+ if ( ! empty($matches[0])) {
61
+ foreach($matches[0] as $_key => $_value) {
62
+ $new_tag = str_replace('#tax_name-', '_ct_', $_value);
63
+ $new_tag = TagCompose::getValueWithTag($new_tag);
64
+ $input = str_replace($_value, $new_tag, $input);
65
+ }
66
+ }
67
+ } else {
68
+ $value = TagCompose::getValueWithTag($value);
69
+ }
70
+ }
71
+ if ( $key !== '#custom_field-' || $key !=='#tax_name-') {
72
+ $input = str_replace($key, $value, $input);
73
+ }
74
+ }
75
+
76
+ return $input;
77
+ }
78
+ }
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit7c78591f24079299fccb099544a5f8f7::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit339939d335e3d7b1bcc9634cec27f261::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit7c78591f24079299fccb099544a5f8f7
6
  {
7
  private static $loader;
8
 
@@ -24,15 +24,15 @@ class ComposerAutoloaderInit7c78591f24079299fccb099544a5f8f7
24
 
25
  require __DIR__ . '/platform_check.php';
26
 
27
- spl_autoload_register(array('ComposerAutoloaderInit7c78591f24079299fccb099544a5f8f7', 'loadClassLoader'), true, true);
28
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
29
- spl_autoload_unregister(array('ComposerAutoloaderInit7c78591f24079299fccb099544a5f8f7', '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\ComposerStaticInit7c78591f24079299fccb099544a5f8f7::getInitializer($loader));
36
  } else {
37
  $map = require __DIR__ . '/autoload_namespaces.php';
38
  foreach ($map as $namespace => $path) {
@@ -53,19 +53,19 @@ class ComposerAutoloaderInit7c78591f24079299fccb099544a5f8f7
53
  $loader->register(true);
54
 
55
  if ($useStaticLoader) {
56
- $includeFiles = Composer\Autoload\ComposerStaticInit7c78591f24079299fccb099544a5f8f7::$files;
57
  } else {
58
  $includeFiles = require __DIR__ . '/autoload_files.php';
59
  }
60
  foreach ($includeFiles as $fileIdentifier => $file) {
61
- composerRequire7c78591f24079299fccb099544a5f8f7($fileIdentifier, $file);
62
  }
63
 
64
  return $loader;
65
  }
66
  }
67
 
68
- function composerRequire7c78591f24079299fccb099544a5f8f7($fileIdentifier, $file)
69
  {
70
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
71
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit339939d335e3d7b1bcc9634cec27f261
6
  {
7
  private static $loader;
8
 
24
 
25
  require __DIR__ . '/platform_check.php';
26
 
27
+ spl_autoload_register(array('ComposerAutoloaderInit339939d335e3d7b1bcc9634cec27f261', 'loadClassLoader'), true, true);
28
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
29
+ spl_autoload_unregister(array('ComposerAutoloaderInit339939d335e3d7b1bcc9634cec27f261', '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\ComposerStaticInit339939d335e3d7b1bcc9634cec27f261::getInitializer($loader));
36
  } else {
37
  $map = require __DIR__ . '/autoload_namespaces.php';
38
  foreach ($map as $namespace => $path) {
53
  $loader->register(true);
54
 
55
  if ($useStaticLoader) {
56
+ $includeFiles = Composer\Autoload\ComposerStaticInit339939d335e3d7b1bcc9634cec27f261::$files;
57
  } else {
58
  $includeFiles = require __DIR__ . '/autoload_files.php';
59
  }
60
  foreach ($includeFiles as $fileIdentifier => $file) {
61
+ composerRequire339939d335e3d7b1bcc9634cec27f261($fileIdentifier, $file);
62
  }
63
 
64
  return $loader;
65
  }
66
  }
67
 
68
+ function composerRequire339939d335e3d7b1bcc9634cec27f261($fileIdentifier, $file)
69
  {
70
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
71
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit7c78591f24079299fccb099544a5f8f7
8
  {
9
  public static $files = array (
10
  '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
@@ -144,9 +144,9 @@ class ComposerStaticInit7c78591f24079299fccb099544a5f8f7
144
  public static function getInitializer(ClassLoader $loader)
145
  {
146
  return \Closure::bind(function () use ($loader) {
147
- $loader->prefixLengthsPsr4 = ComposerStaticInit7c78591f24079299fccb099544a5f8f7::$prefixLengthsPsr4;
148
- $loader->prefixDirsPsr4 = ComposerStaticInit7c78591f24079299fccb099544a5f8f7::$prefixDirsPsr4;
149
- $loader->classMap = ComposerStaticInit7c78591f24079299fccb099544a5f8f7::$classMap;
150
 
151
  }, null, ClassLoader::class);
152
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit339939d335e3d7b1bcc9634cec27f261
8
  {
9
  public static $files = array (
10
  '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
144
  public static function getInitializer(ClassLoader $loader)
145
  {
146
  return \Closure::bind(function () use ($loader) {
147
+ $loader->prefixLengthsPsr4 = ComposerStaticInit339939d335e3d7b1bcc9634cec27f261::$prefixLengthsPsr4;
148
+ $loader->prefixDirsPsr4 = ComposerStaticInit339939d335e3d7b1bcc9634cec27f261::$prefixDirsPsr4;
149
+ $loader->classMap = ComposerStaticInit339939d335e3d7b1bcc9634cec27f261::$classMap;
150
 
151
  }, null, ClassLoader::class);
152
  }
vendor/composer/installed.json CHANGED
@@ -136,17 +136,17 @@
136
  },
137
  {
138
  "name": "google/apiclient-services",
139
- "version": "v0.231.1",
140
- "version_normalized": "0.231.1.0",
141
  "source": {
142
  "type": "git",
143
  "url": "https://github.com/googleapis/google-api-php-client-services.git",
144
- "reference": "d6bf7109fc77d1c67110103a42e2a7d480b217a0"
145
  },
146
  "dist": {
147
  "type": "zip",
148
- "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/d6bf7109fc77d1c67110103a42e2a7d480b217a0",
149
- "reference": "d6bf7109fc77d1c67110103a42e2a7d480b217a0",
150
  "shasum": ""
151
  },
152
  "require": {
@@ -155,7 +155,7 @@
155
  "require-dev": {
156
  "phpunit/phpunit": "^5.7||^8.5.13"
157
  },
158
- "time": "2022-01-26T23:24:19+00:00",
159
  "type": "library",
160
  "installation-source": "dist",
161
  "autoload": {
@@ -177,7 +177,7 @@
177
  ],
178
  "support": {
179
  "issues": "https://github.com/googleapis/google-api-php-client-services/issues",
180
- "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.231.1"
181
  },
182
  "install-path": "../google/apiclient-services"
183
  },
@@ -799,17 +799,17 @@
799
  },
800
  {
801
  "name": "phpseclib/phpseclib",
802
- "version": "3.0.12",
803
- "version_normalized": "3.0.12.0",
804
  "source": {
805
  "type": "git",
806
  "url": "https://github.com/phpseclib/phpseclib.git",
807
- "reference": "89bfb45bd8b1abc3b37e910d57f5dbd3174f40fb"
808
  },
809
  "dist": {
810
  "type": "zip",
811
- "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/89bfb45bd8b1abc3b37e910d57f5dbd3174f40fb",
812
- "reference": "89bfb45bd8b1abc3b37e910d57f5dbd3174f40fb",
813
  "shasum": ""
814
  },
815
  "require": {
@@ -828,7 +828,7 @@
828
  "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
829
  "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
830
  },
831
- "time": "2021-11-28T23:46:03+00:00",
832
  "type": "library",
833
  "installation-source": "dist",
834
  "autoload": {
@@ -893,7 +893,7 @@
893
  ],
894
  "support": {
895
  "issues": "https://github.com/phpseclib/phpseclib/issues",
896
- "source": "https://github.com/phpseclib/phpseclib/tree/3.0.12"
897
  },
898
  "funding": [
899
  {
136
  },
137
  {
138
  "name": "google/apiclient-services",
139
+ "version": "v0.233.0",
140
+ "version_normalized": "0.233.0.0",
141
  "source": {
142
  "type": "git",
143
  "url": "https://github.com/googleapis/google-api-php-client-services.git",
144
+ "reference": "c3632d433742f1e0660460c1d9c220adf4e83885"
145
  },
146
  "dist": {
147
  "type": "zip",
148
+ "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/c3632d433742f1e0660460c1d9c220adf4e83885",
149
+ "reference": "c3632d433742f1e0660460c1d9c220adf4e83885",
150
  "shasum": ""
151
  },
152
  "require": {
155
  "require-dev": {
156
  "phpunit/phpunit": "^5.7||^8.5.13"
157
  },
158
+ "time": "2022-01-30T12:26:38+00:00",
159
  "type": "library",
160
  "installation-source": "dist",
161
  "autoload": {
177
  ],
178
  "support": {
179
  "issues": "https://github.com/googleapis/google-api-php-client-services/issues",
180
+ "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.233.0"
181
  },
182
  "install-path": "../google/apiclient-services"
183
  },
799
  },
800
  {
801
  "name": "phpseclib/phpseclib",
802
+ "version": "3.0.13",
803
+ "version_normalized": "3.0.13.0",
804
  "source": {
805
  "type": "git",
806
  "url": "https://github.com/phpseclib/phpseclib.git",
807
+ "reference": "1443ab79364eea48665fa8c09ac67f37d1025f7e"
808
  },
809
  "dist": {
810
  "type": "zip",
811
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/1443ab79364eea48665fa8c09ac67f37d1025f7e",
812
+ "reference": "1443ab79364eea48665fa8c09ac67f37d1025f7e",
813
  "shasum": ""
814
  },
815
  "require": {
828
  "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
829
  "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
830
  },
831
+ "time": "2022-01-30T08:50:05+00:00",
832
  "type": "library",
833
  "installation-source": "dist",
834
  "autoload": {
893
  ],
894
  "support": {
895
  "issues": "https://github.com/phpseclib/phpseclib/issues",
896
+ "source": "https://github.com/phpseclib/phpseclib/tree/3.0.13"
897
  },
898
  "funding": [
899
  {
vendor/composer/installed.php CHANGED
@@ -5,7 +5,7 @@
5
  'type' => 'wordpress-plugin',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
- 'reference' => 'b1bf613c4a673b3f3916225dd0727766558a245c',
9
  'name' => 'wp-seopress/wp-seopress',
10
  'dev' => false,
11
  ),
@@ -29,12 +29,12 @@
29
  'dev_requirement' => false,
30
  ),
31
  'google/apiclient-services' => array(
32
- 'pretty_version' => 'v0.231.1',
33
- 'version' => '0.231.1.0',
34
  'type' => 'library',
35
  'install_path' => __DIR__ . '/../google/apiclient-services',
36
  'aliases' => array(),
37
- 'reference' => 'd6bf7109fc77d1c67110103a42e2a7d480b217a0',
38
  'dev_requirement' => false,
39
  ),
40
  'google/auth' => array(
@@ -101,12 +101,12 @@
101
  'dev_requirement' => false,
102
  ),
103
  'phpseclib/phpseclib' => array(
104
- 'pretty_version' => '3.0.12',
105
- 'version' => '3.0.12.0',
106
  'type' => 'library',
107
  'install_path' => __DIR__ . '/../phpseclib/phpseclib',
108
  'aliases' => array(),
109
- 'reference' => '89bfb45bd8b1abc3b37e910d57f5dbd3174f40fb',
110
  'dev_requirement' => false,
111
  ),
112
  'psr/cache' => array(
@@ -202,7 +202,7 @@
202
  'type' => 'wordpress-plugin',
203
  'install_path' => __DIR__ . '/../../',
204
  'aliases' => array(),
205
- 'reference' => 'b1bf613c4a673b3f3916225dd0727766558a245c',
206
  'dev_requirement' => false,
207
  ),
208
  ),
5
  'type' => 'wordpress-plugin',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
+ 'reference' => '480a87c6d38b74e5c7d24b3ef1a0565711ea9016',
9
  'name' => 'wp-seopress/wp-seopress',
10
  'dev' => false,
11
  ),
29
  'dev_requirement' => false,
30
  ),
31
  'google/apiclient-services' => array(
32
+ 'pretty_version' => 'v0.233.0',
33
+ 'version' => '0.233.0.0',
34
  'type' => 'library',
35
  'install_path' => __DIR__ . '/../google/apiclient-services',
36
  'aliases' => array(),
37
+ 'reference' => 'c3632d433742f1e0660460c1d9c220adf4e83885',
38
  'dev_requirement' => false,
39
  ),
40
  'google/auth' => array(
101
  'dev_requirement' => false,
102
  ),
103
  'phpseclib/phpseclib' => array(
104
+ 'pretty_version' => '3.0.13',
105
+ 'version' => '3.0.13.0',
106
  'type' => 'library',
107
  'install_path' => __DIR__ . '/../phpseclib/phpseclib',
108
  'aliases' => array(),
109
+ 'reference' => '1443ab79364eea48665fa8c09ac67f37d1025f7e',
110
  'dev_requirement' => false,
111
  ),
112
  'psr/cache' => array(
202
  'type' => 'wordpress-plugin',
203
  'install_path' => __DIR__ . '/../../',
204
  'aliases' => array(),
205
+ 'reference' => '480a87c6d38b74e5c7d24b3ef1a0565711ea9016',
206
  'dev_requirement' => false,
207
  ),
208
  ),
vendor/google/apiclient-services/synth.metadata CHANGED
@@ -4,14 +4,14 @@
4
  "git": {
5
  "name": ".",
6
  "remote": "https://github.com/googleapis/google-api-php-client-services.git",
7
- "sha": "c7e41ff04793cdac1c7e72b148da37b09dcc5bfe"
8
  }
9
  },
10
  {
11
  "git": {
12
  "name": "discovery-artifact-manager",
13
  "remote": "https://github.com/googleapis/discovery-artifact-manager.git",
14
- "sha": "f37da7e0496a79c44db6fbcae47a3780b1ea177f"
15
  }
16
  }
17
  ]
4
  "git": {
5
  "name": ".",
6
  "remote": "https://github.com/googleapis/google-api-php-client-services.git",
7
+ "sha": "3b37d2bf260bb5206cce9fda3d79b9d4e51d082b"
8
  }
9
  },
10
  {
11
  "git": {
12
  "name": "discovery-artifact-manager",
13
  "remote": "https://github.com/googleapis/discovery-artifact-manager.git",
14
+ "sha": "b6fdb84be9e1411e1b5233dcc5baf7aa04191cb8"
15
  }
16
  }
17
  ]
vendor/phpseclib/phpseclib/BACKERS.md CHANGED
@@ -4,6 +4,9 @@ phpseclib ongoing development is made possible by [Tidelift](https://tidelift.co
4
 
5
  ## Backers
6
 
 
 
7
  - Zane Hooper
8
  - [Setasign](https://www.setasign.com/)
9
- - Allan Simon
 
4
 
5
  ## Backers
6
 
7
+ - Allan Simon
8
+ - Raghu Veer Dendukuri
9
  - Zane Hooper
10
  - [Setasign](https://www.setasign.com/)
11
+ - [Charles Severance](https://github.com/csev)
12
+ - [Rachel Fish](https://github.com/itsrachelfish)
vendor/phpseclib/phpseclib/README.md CHANGED
@@ -1,6 +1,6 @@
1
  # phpseclib - PHP Secure Communications Library
2
 
3
- [![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=3.0)](https://travis-ci.com/phpseclib/phpseclib)
4
 
5
  ## Supporting phpseclib
6
 
@@ -52,7 +52,7 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 /
52
  * Composer compatible (PSR-0 autoloading)
53
  * Install using Composer: `composer require phpseclib/phpseclib:~1.0`
54
  * Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm)
55
- * [Download 1.0.19 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.19.zip/download)
56
 
57
  ## Security contact information
58
 
1
  # phpseclib - PHP Secure Communications Library
2
 
3
+ [![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=3.0)](https://travis-ci.com/github/phpseclib/phpseclib)
4
 
5
  ## Supporting phpseclib
6
 
52
  * Composer compatible (PSR-0 autoloading)
53
  * Install using Composer: `composer require phpseclib/phpseclib:~1.0`
54
  * Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm)
55
+ * [Download 1.0.20 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.20.zip/download)
56
 
57
  ## Security contact information
58
 
vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php CHANGED
@@ -158,9 +158,9 @@ abstract class Strings
158
  /**
159
  * Create SSH2-style string
160
  *
161
- * @param string[] ...$elements
162
  * @access public
163
- * @return mixed
164
  */
165
  public static function packSSH2(...$elements)
166
  {
@@ -308,7 +308,7 @@ abstract class Strings
308
  * @param string $x
309
  * @return string
310
  */
311
- public static function bin2bits($x)
312
  {
313
  /*
314
  // the pure-PHP approach is slower than the GMP approach BUT
@@ -337,7 +337,7 @@ abstract class Strings
337
  }
338
  }
339
 
340
- return ltrim($bits, '0');
341
  }
342
 
343
  /**
@@ -350,14 +350,21 @@ abstract class Strings
350
  public static function switchEndianness($x)
351
  {
352
  $r = '';
353
- // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits
354
  for ($i = strlen($x) - 1; $i >= 0; $i--) {
355
  $b = ord($x[$i]);
356
- $p1 = ($b * 0x0802) & 0x22110;
357
- $p2 = ($b * 0x8020) & 0x88440;
358
- $r.= chr(
359
- (($p1 | $p2) * 0x10101) >> 16
360
- );
 
 
 
 
 
 
 
 
361
  }
362
  return $r;
363
  }
158
  /**
159
  * Create SSH2-style string
160
  *
161
+ * @param string|int|float|array|bool ...$elements
162
  * @access public
163
+ * @return string
164
  */
165
  public static function packSSH2(...$elements)
166
  {
308
  * @param string $x
309
  * @return string
310
  */
311
+ public static function bin2bits($x, $trim = true)
312
  {
313
  /*
314
  // the pure-PHP approach is slower than the GMP approach BUT
337
  }
338
  }
339
 
340
+ return $trim ? ltrim($bits, '0') : $bits;
341
  }
342
 
343
  /**
350
  public static function switchEndianness($x)
351
  {
352
  $r = '';
 
353
  for ($i = strlen($x) - 1; $i >= 0; $i--) {
354
  $b = ord($x[$i]);
355
+ if (PHP_INT_SIZE === 8) {
356
+ // 3 operations
357
+ // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv
358
+ $r.= chr((($b * 0x0202020202) & 0x010884422010) % 1023);
359
+ } else {
360
+ // 7 operations
361
+ // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits
362
+ $p1 = ($b * 0x0802) & 0x22110;
363
+ $p2 = ($b * 0x8020) & 0x88440;
364
+ $r.= chr(
365
+ (($p1 | $p2) * 0x10101) >> 16
366
+ );
367
+ }
368
  }
369
  return $r;
370
  }
vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php CHANGED
@@ -123,6 +123,12 @@ abstract class AsymmetricKey
123
  */
124
  private $comment;
125
 
 
 
 
 
 
 
126
  /**
127
  * The constructor
128
  */
@@ -245,7 +251,7 @@ abstract class AsymmetricKey
245
  * @param string $type
246
  * @param string $key
247
  * @param string $password optional
248
- * @return AsymmetricKey
249
  */
250
  public static function loadFormat($type, $key, $password = false)
251
  {
123
  */
124
  private $comment;
125
 
126
+ /**
127
+ * @param string $type
128
+ * @return string
129
+ */
130
+ abstract public function toString($type, array $options = []);
131
+
132
  /**
133
  * The constructor
134
  */
251
  * @param string $type
252
  * @param string $key
253
  * @param string $password optional
254
+ * @return static
255
  */
256
  public static function loadFormat($type, $key, $password = false)
257
  {
vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php CHANGED
@@ -101,7 +101,15 @@ abstract class SymmetricKey
101
  * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt()
102
  * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt()
103
  */
104
- const MODE_CFB8 = 38;
 
 
 
 
 
 
 
 
105
  /**
106
  * Encrypt / decrypt using the Output Feedback mode.
107
  *
@@ -142,6 +150,7 @@ abstract class SymmetricKey
142
  'cfb' => self::MODE_CFB,
143
  'cfb8' => self::MODE_CFB8,
144
  'ofb' => self::MODE_OFB,
 
145
  'gcm' => self::MODE_GCM,
146
  'stream' => self::MODE_STREAM
147
  ];
@@ -642,6 +651,8 @@ abstract class SymmetricKey
642
  *
643
  * - ofb
644
  *
 
 
645
  * - gcm
646
  *
647
  * @param string $mode
@@ -669,6 +680,7 @@ abstract class SymmetricKey
669
  case self::MODE_CFB:
670
  case self::MODE_CFB8:
671
  case self::MODE_OFB:
 
672
  case self::MODE_STREAM:
673
  $this->paddable = false;
674
  break;
@@ -1237,6 +1249,21 @@ abstract class SymmetricKey
1237
  }
1238
  }
1239
  return $ciphertext;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1240
  case self::MODE_OFB:
1241
  return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
1242
  }
@@ -1431,6 +1458,21 @@ abstract class SymmetricKey
1431
  }
1432
  }
1433
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1434
  case self::MODE_OFB:
1435
  $xor = $this->encryptIV;
1436
  if (strlen($buffer['xor'])) {
@@ -1595,6 +1637,21 @@ abstract class SymmetricKey
1595
  }
1596
  }
1597
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1598
  case self::MODE_OFB:
1599
  $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
1600
  }
@@ -1773,6 +1830,21 @@ abstract class SymmetricKey
1773
  }
1774
  }
1775
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1776
  case self::MODE_OFB:
1777
  $xor = $this->decryptIV;
1778
  if (strlen($buffer['xor'])) {
@@ -2446,6 +2518,7 @@ abstract class SymmetricKey
2446
  self::MODE_CFB => 'ncfb',
2447
  self::MODE_CFB8 => MCRYPT_MODE_CFB,
2448
  self::MODE_OFB => MCRYPT_MODE_NOFB,
 
2449
  self::MODE_STREAM => MCRYPT_MODE_STREAM,
2450
  ];
2451
 
@@ -2974,6 +3047,44 @@ abstract class SymmetricKey
2974
  }
2975
  }
2976
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2977
  return $_plaintext;
2978
  ';
2979
  break;
@@ -3301,4 +3412,4 @@ abstract class SymmetricKey
3301
  {
3302
  return array_flip(self::MODE_MAP)[$this->mode];
3303
  }
3304
- }
101
  * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt()
102
  * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt()
103
  */
104
+ const MODE_CFB8 = 7;
105
+ /**
106
+ * Encrypt / decrypt using the Output Feedback mode (8bit)
107
+ *
108
+ * @access public
109
+ * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt()
110
+ * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt()
111
+ */
112
+ const MODE_OFB8 = 8;
113
  /**
114
  * Encrypt / decrypt using the Output Feedback mode.
115
  *
150
  'cfb' => self::MODE_CFB,
151
  'cfb8' => self::MODE_CFB8,
152
  'ofb' => self::MODE_OFB,
153
+ 'ofb8' => self::MODE_OFB8,
154
  'gcm' => self::MODE_GCM,
155
  'stream' => self::MODE_STREAM
156
  ];
651
  *
652
  * - ofb
653
  *
654
+ * - ofb8
655
+ *
656
  * - gcm
657
  *
658
  * @param string $mode
680
  case self::MODE_CFB:
681
  case self::MODE_CFB8:
682
  case self::MODE_OFB:
683
+ case self::MODE_OFB8:
684
  case self::MODE_STREAM:
685
  $this->paddable = false;
686
  break;
1249
  }
1250
  }
1251
  return $ciphertext;
1252
+ case self::MODE_OFB8:
1253
+ $ciphertext = '';
1254
+ $len = strlen($plaintext);
1255
+ $iv = $this->encryptIV;
1256
+
1257
+ for ($i = 0; $i < $len; ++$i) {
1258
+ $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV);
1259
+ $ciphertext.= $plaintext[$i] ^ $xor;
1260
+ $iv = substr($iv, 1) . $xor[0];
1261
+ }
1262
+
1263
+ if ($this->continuousBuffer) {
1264
+ $this->encryptIV = $iv;
1265
+ }
1266
+ break;
1267
  case self::MODE_OFB:
1268
  return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
1269
  }
1458
  }
1459
  }
1460
  break;
1461
+ case self::MODE_OFB8:
1462
+ $ciphertext = '';
1463
+ $len = strlen($plaintext);
1464
+ $iv = $this->encryptIV;
1465
+
1466
+ for ($i = 0; $i < $len; ++$i) {
1467
+ $xor = $this->encryptBlock($iv);
1468
+ $ciphertext.= $plaintext[$i] ^ $xor;
1469
+ $iv = substr($iv, 1) . $xor[0];
1470
+ }
1471
+
1472
+ if ($this->continuousBuffer) {
1473
+ $this->encryptIV = $iv;
1474
+ }
1475
+ break;
1476
  case self::MODE_OFB:
1477
  $xor = $this->encryptIV;
1478
  if (strlen($buffer['xor'])) {
1637
  }
1638
  }
1639
  break;
1640
+ case self::MODE_OFB8:
1641
+ $plaintext = '';
1642
+ $len = strlen($ciphertext);
1643
+ $iv = $this->decryptIV;
1644
+
1645
+ for ($i = 0; $i < $len; ++$i) {
1646
+ $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV);
1647
+ $plaintext.= $ciphertext[$i] ^ $xor;
1648
+ $iv = substr($iv, 1) . $xor[0];
1649
+ }
1650
+
1651
+ if ($this->continuousBuffer) {
1652
+ $this->decryptIV = $iv;
1653
+ }
1654
+ break;
1655
  case self::MODE_OFB:
1656
  $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
1657
  }
1830
  }
1831
  }
1832
  break;
1833
+ case self::MODE_OFB8:
1834
+ $plaintext = '';
1835
+ $len = strlen($ciphertext);
1836
+ $iv = $this->decryptIV;
1837
+
1838
+ for ($i = 0; $i < $len; ++$i) {
1839
+ $xor = $this->encryptBlock($iv);
1840
+ $plaintext.= $ciphertext[$i] ^ $xor;
1841
+ $iv = substr($iv, 1) . $xor[0];
1842
+ }
1843
+
1844
+ if ($this->continuousBuffer) {
1845
+ $this->decryptIV = $iv;
1846
+ }
1847
+ break;
1848
  case self::MODE_OFB:
1849
  $xor = $this->decryptIV;
1850
  if (strlen($buffer['xor'])) {
2518
  self::MODE_CFB => 'ncfb',
2519
  self::MODE_CFB8 => MCRYPT_MODE_CFB,
2520
  self::MODE_OFB => MCRYPT_MODE_NOFB,
2521
+ self::MODE_OFB8 => MCRYPT_MODE_OFB,
2522
  self::MODE_STREAM => MCRYPT_MODE_STREAM,
2523
  ];
2524
 
3047
  }
3048
  }
3049
 
3050
+ return $_plaintext;
3051
+ ';
3052
+ break;
3053
+ case self::MODE_OFB8:
3054
+ $encrypt = $init_encrypt . '
3055
+ $_ciphertext = "";
3056
+ $_len = strlen($_text);
3057
+ $_iv = $this->encryptIV;
3058
+
3059
+ for ($_i = 0; $_i < $_len; ++$_i) {
3060
+ $in = $_iv;
3061
+ '.$encrypt_block.'
3062
+ $_ciphertext.= $_text[$_i] ^ $in;
3063
+ $_iv = substr($_iv, 1) . $in[0];
3064
+ }
3065
+
3066
+ if ($this->continuousBuffer) {
3067
+ $this->encryptIV = $_iv;
3068
+ }
3069
+
3070
+ return $_ciphertext;
3071
+ ';
3072
+ $decrypt = $init_encrypt . '
3073
+ $_plaintext = "";
3074
+ $_len = strlen($_text);
3075
+ $_iv = $this->decryptIV;
3076
+
3077
+ for ($_i = 0; $_i < $_len; ++$_i) {
3078
+ $in = $_iv;
3079
+ '.$encrypt_block.'
3080
+ $_plaintext.= $_text[$_i] ^ $in;
3081
+ $_iv = substr($_iv, 1) . $in[0];
3082
+ }
3083
+
3084
+ if ($this->continuousBuffer) {
3085
+ $this->decryptIV = $_iv;
3086
+ }
3087
+
3088
  return $_plaintext;
3089
  ';
3090
  break;
3412
  {
3413
  return array_flip(self::MODE_MAP)[$this->mode];
3414
  }
3415
+ }
vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php CHANGED
@@ -78,7 +78,7 @@ abstract class DH extends AsymmetricKey
78
  * - a string (eg. diffie-hellman-group14-sha1)
79
  *
80
  * @access public
81
- * @return \phpseclib3\Crypt\DH|bool
82
  */
83
  public static function createParameters(...$args)
84
  {
@@ -397,4 +397,4 @@ abstract class DH extends AsymmetricKey
397
  $key = $type::saveParameters($this->prime, $this->base);
398
  return self::load($key, 'PKCS1');
399
  }
400
- }
78
  * - a string (eg. diffie-hellman-group14-sha1)
79
  *
80
  * @access public
81
+ * @return Parameters
82
  */
83
  public static function createParameters(...$args)
84
  {
397
  $key = $type::saveParameters($this->prime, $this->base);
398
  return self::load($key, 'PKCS1');
399
  }
400
+ }
vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php CHANGED
@@ -129,7 +129,7 @@ abstract class DSA extends AsymmetricKey
129
  SSH DSA implementations only support keys with an N of 160.
130
  puttygen let's you set the size of L (but not the size of N) and uses 2048 as the
131
  default L value. that's not really compliant with any of the FIPS standards, however,
132
- for the purposes of maintaining compatibility with puttygen, we'll support it
133
  */
134
  //case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160:
135
  // FIPS 186-3 changed this as follows:
@@ -341,4 +341,4 @@ abstract class DSA extends AsymmetricKey
341
  {
342
  return $this->shortFormat;
343
  }
344
- }
129
  SSH DSA implementations only support keys with an N of 160.
130
  puttygen let's you set the size of L (but not the size of N) and uses 2048 as the
131
  default L value. that's not really compliant with any of the FIPS standards, however,
132
+ for the purposes of maintaining compatibility with puttygen, we'll support it
133
  */
134
  //case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160:
135
  // FIPS 186-3 changed this as follows:
341
  {
342
  return $this->shortFormat;
343
  }
344
+ }
vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php CHANGED
@@ -233,4 +233,4 @@ abstract class Base
233
  $r = $this->addPoint($p1, $p2);
234
  return $this->convertToAffine($r);
235
  }
236
- }
233
  $r = $this->addPoint($p1, $p2);
234
  return $this->convertToAffine($r);
235
  }
236
+ }
vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php CHANGED
@@ -375,4 +375,4 @@ class Binary extends Base
375
  $p['fresh'] = true;
376
  return $p;
377
  }
378
- }
375
  $p['fresh'] = true;
376
  return $p;
377
  }
378
+ }
vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php CHANGED
@@ -152,7 +152,9 @@ abstract class XML
152
  }
153
  $node = $nodes->item(0);
154
  $ns_name = $node->lookupPrefix($ns);
155
- $node->removeAttributeNS($ns, $ns_name);
 
 
156
  return $dom->saveXML($node);
157
  }
158
 
152
  }
153
  $node = $nodes->item(0);
154
  $ns_name = $node->lookupPrefix($ns);
155
+ if ($ns_name) {
156
+ $node->removeAttributeNS($ns, $ns_name);
157
+ }
158
  return $dom->saveXML($node);
159
  }
160
 
vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php CHANGED
@@ -51,7 +51,7 @@ abstract class Random
51
  }
52
 
53
  try {
54
- return \random_bytes($length);
55
  } catch (\Exception $e) {
56
  // random_compat will throw an Exception, which in PHP 5 does not implement Throwable
57
  } catch (\Throwable $e) {
51
  }
52
 
53
  try {
54
+ return random_bytes($length);
55
  } catch (\Exception $e) {
56
  // random_compat will throw an Exception, which in PHP 5 does not implement Throwable
57
  } catch (\Throwable $e) {
vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php CHANGED
@@ -341,7 +341,9 @@ class Salsa20 extends StreamCipher
341
  } else {
342
  $buffer = &$this->debuffer;
343
  }
344
- if (strlen($buffer['ciphertext'])) {
 
 
345
  $ciphertext = $text ^ Strings::shift($buffer['ciphertext'], strlen($text));
346
  $text = substr($text, strlen($ciphertext));
347
  if (!strlen($text)) {
@@ -478,7 +480,7 @@ class Salsa20 extends StreamCipher
478
  {
479
  $z = $x = unpack('V*', $x);
480
  for ($i = 0; $i < 10; $i++) {
481
- static::doubleRound(...$z);
482
  }
483
 
484
  for ($i = 1; $i <= 16; $i++) {
341
  } else {
342
  $buffer = &$this->debuffer;
343
  }
344
+ if (!strlen($buffer['ciphertext'])) {
345
+ $ciphertext = '';
346
+ } else {
347
  $ciphertext = $text ^ Strings::shift($buffer['ciphertext'], strlen($text));
348
  $text = substr($text, strlen($ciphertext));
349
  if (!strlen($text)) {
480
  {
481
  $z = $x = unpack('V*', $x);
482
  for ($i = 0; $i < 10; $i++) {
483
+ static::doubleRound($z[1], $z[2], $z[3], $z[4], $z[5], $z[6], $z[7], $z[8], $z[9], $z[10], $z[11], $z[12], $z[13], $z[14], $z[15], $z[16]);
484
  }
485
 
486
  for ($i = 1; $i <= 16; $i++) {
vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php CHANGED
@@ -737,4 +737,4 @@ class BCMath extends Engine
737
 
738
  return $temp;
739
  }
740
- }
737
 
738
  return $temp;
739
  }
740
+ }
vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php CHANGED
@@ -190,4 +190,4 @@ abstract class Barrett extends Base
190
 
191
  return $result;
192
  }
193
- }
190
 
191
  return $result;
192
  }
193
+ }
vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php CHANGED
@@ -578,6 +578,11 @@ abstract class PHP extends Engine
578
  $lhs = new static();
579
  $rhs = new static();
580
  }
 
 
 
 
 
581
  $temp_value = &$temp->value;
582
  $rhs_value = &$rhs->value;
583
 
578
  $lhs = new static();
579
  $rhs = new static();
580
  }
581
+ if (static::class != get_class($temp)) {
582
+ $temp = new static();
583
+ $lhs = new static();
584
+ $rhs = new static();
585
+ }
586
  $temp_value = &$temp->value;
587
  $rhs_value = &$rhs->value;
588
 
vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php CHANGED
@@ -116,6 +116,18 @@ class SFTP extends SSH2
116
  */
117
  private $status_codes = [];
118
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  /**
120
  * The Request ID
121
  *
@@ -188,7 +200,7 @@ class SFTP extends SSH2
188
  /**
189
  * Current working directory
190
  *
191
- * @var string
192
  * @see self::realpath()
193
  * @see self::chdir()
194
  * @access private
@@ -242,7 +254,7 @@ class SFTP extends SSH2
242
  *
243
  * @see self::__construct()
244
  * @see self::get()
245
- * @var array
246
  * @access private
247
  */
248
  private $max_sftp_packet;
@@ -341,7 +353,6 @@ class SFTP extends SSH2
341
  * @param string $host
342
  * @param int $port
343
  * @param int $timeout
344
- * @return \phpseclib3\Net\SFTP
345
  * @access public
346
  */
347
  public function __construct($host, $port = 22, $timeout = 10)
@@ -782,7 +793,7 @@ class SFTP extends SSH2
782
  /**
783
  * Returns the current directory name
784
  *
785
- * @return mixed
786
  * @access public
787
  */
788
  public function pwd()
@@ -952,7 +963,7 @@ class SFTP extends SSH2
952
  *
953
  * @param string $dir
954
  * @param bool $recursive
955
- * @return mixed
956
  * @access public
957
  */
958
  public function nlist($dir = '.', $recursive = false)
@@ -966,7 +977,7 @@ class SFTP extends SSH2
966
  * @param string $dir
967
  * @param bool $recursive
968
  * @param string $relativeDir
969
- * @return mixed
970
  * @access private
971
  */
972
  private function nlist_helper($dir, $recursive, $relativeDir)
@@ -1000,7 +1011,7 @@ class SFTP extends SSH2
1000
  *
1001
  * @param string $dir
1002
  * @param bool $recursive
1003
- * @return mixed
1004
  * @access public
1005
  */
1006
  public function rawlist($dir = '.', $recursive = false)
@@ -1044,7 +1055,7 @@ class SFTP extends SSH2
1044
  *
1045
  * @param string $dir
1046
  * @param bool $raw
1047
- * @return mixed
1048
  * @throws \UnexpectedValueException on receipt of unexpected packets
1049
  * @access private
1050
  */
@@ -1227,7 +1238,7 @@ class SFTP extends SSH2
1227
  * $sftp->setListOrder();
1228
  * Don't do any sort of sorting
1229
  *
1230
- * @param string[] ...$args
1231
  * @access public
1232
  */
1233
  public function setListOrder(...$args)
@@ -1349,7 +1360,7 @@ class SFTP extends SSH2
1349
  * Returns an array on success and false otherwise.
1350
  *
1351
  * @param string $filename
1352
- * @return mixed
1353
  * @access public
1354
  */
1355
  public function stat($filename)
@@ -1406,7 +1417,7 @@ class SFTP extends SSH2
1406
  * Returns an array on success and false otherwise.
1407
  *
1408
  * @param string $filename
1409
- * @return mixed
1410
  * @access public
1411
  */
1412
  public function lstat($filename)
@@ -1474,7 +1485,7 @@ class SFTP extends SSH2
1474
  * @param string $filename
1475
  * @param int $type
1476
  * @throws \UnexpectedValueException on receipt of unexpected packets
1477
- * @return mixed
1478
  * @access private
1479
  */
1480
  private function stat_helper($filename, $type)
@@ -1635,7 +1646,7 @@ class SFTP extends SSH2
1635
  public function chgrp($filename, $gid, $recursive = false)
1636
  {
1637
  $attr = $this->version < 4 ?
1638
- pack('N3', NET_SFTP_ATTR_UIDGID, $gid, -1) :
1639
  Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, '', $gid);
1640
 
1641
  return $this->setstat($filename, $attr, $recursive);
@@ -1810,7 +1821,7 @@ class SFTP extends SSH2
1810
  $packet = Strings::packSSH2('s', $path);
1811
  $packet.= $this->version >= 4 ?
1812
  pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) :
1813
- $atr;
1814
  $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet);
1815
 
1816
  $i++;
@@ -2344,7 +2355,7 @@ class SFTP extends SSH2
2344
  * @param int $length
2345
  * @param callable|null $progressCallback
2346
  * @throws \UnexpectedValueException on receipt of unexpected packets
2347
- * @return mixed
2348
  * @access public
2349
  */
2350
  public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null)
@@ -2846,7 +2857,7 @@ class SFTP extends SSH2
2846
  * Gets file type
2847
  *
2848
  * @param string $path
2849
- * @return mixed
2850
  * @access public
2851
  */
2852
  public function filetype($path)
@@ -3132,7 +3143,7 @@ class SFTP extends SSH2
3132
  // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4
3133
  // represents the number of bytes that the file consumes on the disk. will
3134
  // usually be larger than the 'size' field
3135
- list($attr['allocation-size']) = Strings::unpack('Q', $response);
3136
  break;
3137
  case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800
3138
  // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10
@@ -3147,7 +3158,7 @@ class SFTP extends SSH2
3147
  break;
3148
  case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000
3149
  // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12
3150
- list($attr['link-count']) = Strings::unpackSS2('N', $response);
3151
  break;
3152
  case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000
3153
  // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13
@@ -3500,7 +3511,7 @@ class SFTP extends SSH2
3500
  /**
3501
  * Get supported SFTP versions
3502
  *
3503
- * @return array
3504
  * @access public
3505
  */
3506
  public function getNegotiatedVersion()
@@ -3531,13 +3542,13 @@ class SFTP extends SSH2
3531
  * Disconnect
3532
  *
3533
  * @param int $reason
3534
- * @return bool
3535
  * @access protected
3536
  */
3537
  protected function disconnect_helper($reason)
3538
  {
3539
  $this->pwd = false;
3540
- parent::disconnect_helper($reason);
3541
  }
3542
 
3543
  /**
116
  */
117
  private $status_codes = [];
118
 
119
+ /** @var array<int, string> */
120
+ private $attributes;
121
+
122
+ /** @var array<int, string> */
123
+ private $open_flags;
124
+
125
+ /** @var array<int, string> */
126
+ private $open_flags5;
127
+
128
+ /** @var array<int, string> */
129
+ private $file_types;
130
+
131
  /**
132
  * The Request ID
133
  *
200
  /**
201
  * Current working directory
202
  *
203
+ * @var string|bool
204
  * @see self::realpath()
205
  * @see self::chdir()
206
  * @access private
254
  *
255
  * @see self::__construct()
256
  * @see self::get()
257
+ * @var int
258
  * @access private
259
  */
260
  private $max_sftp_packet;
353
  * @param string $host
354
  * @param int $port
355
  * @param int $timeout
 
356
  * @access public
357
  */
358
  public function __construct($host, $port = 22, $timeout = 10)
793
  /**
794
  * Returns the current directory name
795
  *
796
+ * @return string|bool
797
  * @access public
798
  */
799
  public function pwd()
963
  *
964
  * @param string $dir
965
  * @param bool $recursive
966
+ * @return array|false
967
  * @access public
968
  */
969
  public function nlist($dir = '.', $recursive = false)
977
  * @param string $dir
978
  * @param bool $recursive
979
  * @param string $relativeDir
980
+ * @return array|false
981
  * @access private
982
  */
983
  private function nlist_helper($dir, $recursive, $relativeDir)
1011
  *
1012
  * @param string $dir
1013
  * @param bool $recursive
1014
+ * @return array|false
1015
  * @access public
1016
  */
1017
  public function rawlist($dir = '.', $recursive = false)
1055
  *
1056
  * @param string $dir
1057
  * @param bool $raw
1058
+ * @return array|false
1059
  * @throws \UnexpectedValueException on receipt of unexpected packets
1060
  * @access private
1061
  */
1238
  * $sftp->setListOrder();
1239
  * Don't do any sort of sorting
1240
  *
1241
+ * @param string ...$args
1242
  * @access public
1243
  */
1244
  public function setListOrder(...$args)
1360
  * Returns an array on success and false otherwise.
1361
  *
1362
  * @param string $filename
1363
+ * @return array|false
1364
  * @access public
1365
  */
1366
  public function stat($filename)
1417
  * Returns an array on success and false otherwise.
1418
  *
1419
  * @param string $filename
1420
+ * @return array|false
1421
  * @access public
1422
  */
1423
  public function lstat($filename)
1485
  * @param string $filename
1486
  * @param int $type
1487
  * @throws \UnexpectedValueException on receipt of unexpected packets
1488
+ * @return array|false
1489
  * @access private
1490
  */
1491
  private function stat_helper($filename, $type)
1646
  public function chgrp($filename, $gid, $recursive = false)
1647
  {
1648
  $attr = $this->version < 4 ?
1649
+ pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid) :
1650
  Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, '', $gid);
1651
 
1652
  return $this->setstat($filename, $attr, $recursive);
1821
  $packet = Strings::packSSH2('s', $path);
1822
  $packet.= $this->version >= 4 ?
1823
  pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) :
1824
+ $attr;
1825
  $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet);
1826
 
1827
  $i++;
2355
  * @param int $length
2356
  * @param callable|null $progressCallback
2357
  * @throws \UnexpectedValueException on receipt of unexpected packets
2358
+ * @return string|false
2359
  * @access public
2360
  */
2361
  public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null)
2857
  * Gets file type
2858
  *
2859
  * @param string $path
2860
+ * @return string|false
2861
  * @access public
2862
  */
2863
  public function filetype($path)
3143
  // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4
3144
  // represents the number of bytes that the file consumes on the disk. will
3145
  // usually be larger than the 'size' field
3146
+ list($attr['allocation-size']) = Strings::unpackSSH2('Q', $response);
3147
  break;
3148
  case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800
3149
  // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10
3158
  break;
3159
  case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000
3160
  // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12
3161
+ list($attr['link-count']) = Strings::unpackSSH2('N', $response);
3162
  break;
3163
  case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000
3164
  // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13
3511
  /**
3512
  * Get supported SFTP versions
3513
  *
3514
+ * @return int|false
3515
  * @access public
3516
  */
3517
  public function getNegotiatedVersion()
3542
  * Disconnect
3543
  *
3544
  * @param int $reason
3545
+ * @return false
3546
  * @access protected
3547
  */
3548
  protected function disconnect_helper($reason)
3549
  {
3550
  $this->pwd = false;
3551
+ return parent::disconnect_helper($reason);
3552
  }
3553
 
3554
  /**
vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php CHANGED
@@ -338,7 +338,7 @@ class Stream
338
  * Write to stream
339
  *
340
  * @param string $data
341
- * @return mixed
342
  * @access public
343
  */
344
  private function _stream_write($data)
338
  * Write to stream
339
  *
340
  * @param string $data
341
+ * @return int|false
342
  * @access public
343
  */
344
  private function _stream_write($data)
vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php CHANGED
@@ -48,10 +48,12 @@
48
  namespace phpseclib3\Net;
49
 
50
  use phpseclib3\Crypt\Blowfish;
 
51
  use phpseclib3\Crypt\Hash;
52
  use phpseclib3\Crypt\Random;
53
  use phpseclib3\Crypt\RC4;
54
  use phpseclib3\Crypt\Rijndael;
 
55
  use phpseclib3\Crypt\Common\PrivateKey;
56
  use phpseclib3\Crypt\RSA;
57
  use phpseclib3\Crypt\DSA;
@@ -72,23 +74,6 @@ use phpseclib3\Exception\InsufficientSetupException;
72
  use phpseclib3\Common\Functions\Strings;
73
  use phpseclib3\Crypt\Common\AsymmetricKey;
74
 
75
- /**#@+
76
- * @access private
77
- */
78
- /**
79
- * No compression
80
- */
81
- define('NET_SSH2_COMPRESSION_NONE', 1);
82
- /**
83
- * zlib compression
84
- */
85
- define('NET_SSH2_COMPRESSION_ZLIB', 2);
86
- /**
87
- * zlib@openssh.com
88
- */
89
- define('NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH', 3);
90
- /**#@-*/
91
-
92
  /**
93
  * Pure-PHP implementation of SSHv2.
94
  *
@@ -98,6 +83,25 @@ define('NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH', 3);
98
  */
99
  class SSH2
100
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  // Execution Bitmap Masks
102
  const MASK_CONSTRUCTOR = 0x00000001;
103
  const MASK_CONNECTED = 0x00000002;
@@ -200,7 +204,7 @@ class SSH2
200
  /**
201
  * The Socket Object
202
  *
203
- * @var object
204
  * @access private
205
  */
206
  public $fsock;
@@ -230,7 +234,7 @@ class SSH2
230
  * Server Identifier
231
  *
232
  * @see self::getServerIdentification()
233
- * @var array|false
234
  * @access private
235
  */
236
  protected $server_identifier = false;
@@ -406,6 +410,24 @@ class SSH2
406
  */
407
  private $decrypt = false;
408
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  /**
410
  * Server to Client Length Encryption Object
411
  *
@@ -424,6 +446,24 @@ class SSH2
424
  */
425
  private $encrypt = false;
426
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  /**
428
  * Client to Server Length Encryption Object
429
  *
@@ -442,6 +482,22 @@ class SSH2
442
  */
443
  private $hmac_create = false;
444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  /**
446
  * Server to Client HMAC Object
447
  *
@@ -451,6 +507,22 @@ class SSH2
451
  */
452
  private $hmac_check = false;
453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  /**
455
  * Size of server to client HMAC
456
  *
@@ -707,7 +779,7 @@ class SSH2
707
  * Interactive Buffer
708
  *
709
  * @see self::read()
710
- * @var array
711
  * @access private
712
  */
713
  private $interactiveBuffer = '';
@@ -752,7 +824,7 @@ class SSH2
752
  * Real-time log file pointer
753
  *
754
  * @see self::_append_log()
755
- * @var resource
756
  * @access private
757
  */
758
  private $realtime_log_file;
@@ -794,7 +866,7 @@ class SSH2
794
  /**
795
  * Time of first network activity
796
  *
797
- * @var int
798
  * @access private
799
  */
800
  private $last_packet;
@@ -962,7 +1034,7 @@ class SSH2
962
  /**
963
  * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
964
  *
965
- * @var \phpseclib3\System\Ssh\Agent
966
  * @access private
967
  */
968
  private $agent;
@@ -971,7 +1043,7 @@ class SSH2
971
  * Connection storage to replicates ssh2 extension functionality:
972
  * {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
973
  *
974
- * @var SSH2[]
975
  */
976
  private static $connections;
977
 
@@ -1041,7 +1113,7 @@ class SSH2
1041
 
1042
  /**
1043
  * The authentication methods that may productively continue authentication.
1044
- *
1045
  * @see https://tools.ietf.org/html/rfc4252#section-5.1
1046
  * @var array|null
1047
  * @access private
@@ -1054,20 +1126,20 @@ class SSH2
1054
  * @var int
1055
  * @access private
1056
  */
1057
- private $compress = NET_SSH2_COMPRESSION_NONE;
1058
 
1059
  /**
1060
  * Decompression method
1061
  *
1062
- * @var resource|object
1063
  * @access private
1064
  */
1065
- private $decompress = NET_SSH2_COMPRESSION_NONE;
1066
 
1067
  /**
1068
  * Compression context
1069
  *
1070
- * @var int
1071
  * @access private
1072
  */
1073
  private $compress_context;
@@ -1113,7 +1185,6 @@ class SSH2
1113
  * @param int $port
1114
  * @param int $timeout
1115
  * @see self::login()
1116
- * @return SSH2|void
1117
  * @access public
1118
  */
1119
  public function __construct($host, $port = 22, $timeout = 10)
@@ -1197,14 +1268,20 @@ class SSH2
1197
  31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY']
1198
  );
1199
 
1200
- self::$connections[$this->getResourceId()] = class_exists('WeakReference') ? \WeakReference::create($this) : $this;
 
 
 
 
 
 
1201
 
1202
  if (is_resource($host)) {
1203
  $this->fsock = $host;
1204
  return;
1205
  }
1206
 
1207
- if (is_string($host)) {
1208
  $this->host = $host;
1209
  $this->port = $port;
1210
  $this->timeout = $timeout;
@@ -1344,8 +1421,8 @@ class SSH2
1344
  $read = [$this->fsock];
1345
  $write = $except = null;
1346
  $start = microtime(true);
1347
- $sec = floor($this->curTimeout);
1348
- $usec = 1000000 * ($this->curTimeout - $sec);
1349
  if (@stream_select($read, $write, $except, $sec, $usec) === false) {
1350
  throw new \RuntimeException('Connection timed out whilst receiving server identification string');
1351
  }
@@ -1408,7 +1485,7 @@ class SSH2
1408
  if (!$this->send_kex_first) {
1409
  $response = $this->get_binary_packet();
1410
 
1411
- if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
1412
  $this->bitmap = 0;
1413
  throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
1414
  }
@@ -1543,7 +1620,11 @@ class SSH2
1543
 
1544
  $kexinit_payload_server = $this->get_binary_packet();
1545
 
1546
- if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) {
 
 
 
 
1547
  $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR);
1548
  throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
1549
  }
@@ -1617,9 +1698,9 @@ class SSH2
1617
  }
1618
 
1619
  $compression_map = [
1620
- 'none' => NET_SSH2_COMPRESSION_NONE,
1621
- 'zlib' => NET_SSH2_COMPRESSION_ZLIB,
1622
- 'zlib@openssh.com' => NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH
1623
  ];
1624
 
1625
  $compression_algorithm_in = self::array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client);
@@ -1847,7 +1928,7 @@ class SSH2
1847
  case 'aes256-gcm@openssh.com':
1848
  $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
1849
  $this->encrypt->fixed = substr($nonce, 0, 4);
1850
- $this->encrypt->invocation_counter = substr($nonce, 4, 8);
1851
  case 'chacha20-poly1305@openssh.com':
1852
  break;
1853
  default:
@@ -1865,7 +1946,7 @@ class SSH2
1865
  $this->lengthEncrypt->setKey(substr($key, 32, 32));
1866
  }
1867
  $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
1868
- $this->encrypt->name = $encrypt;
1869
  }
1870
 
1871
  $this->decrypt = self::encryption_algorithm_to_crypt_instance($decrypt);
@@ -1892,7 +1973,7 @@ class SSH2
1892
  // see https://tools.ietf.org/html/rfc5647#section-7.1
1893
  $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
1894
  $this->decrypt->fixed = substr($nonce, 0, 4);
1895
- $this->decrypt->invocation_counter = substr($nonce, 4, 8);
1896
  case 'chacha20-poly1305@openssh.com':
1897
  break;
1898
  default:
@@ -1910,7 +1991,7 @@ class SSH2
1910
  $this->lengthDecrypt->setKey(substr($key, 32, 32));
1911
  }
1912
  $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
1913
- $this->decrypt->name = $decrypt;
1914
  }
1915
 
1916
  /* The "arcfour128" algorithm is the RC4 cipher, as described in
@@ -1931,7 +2012,7 @@ class SSH2
1931
  list($this->hmac_create, $createKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_out);
1932
  } else {
1933
  $this->hmac_create = new \stdClass;
1934
- $this->hmac_create->name = $mac_algorithm_out;
1935
  //$mac_algorithm_out = 'none';
1936
  $createKeyLength = 0;
1937
  }
@@ -1942,8 +2023,8 @@ class SSH2
1942
  $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
1943
  }
1944
  $this->hmac_create->setKey(substr($key, 0, $createKeyLength));
1945
- $this->hmac_create->name = $mac_algorithm_out;
1946
- $this->hmac_create->etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_out);
1947
  }
1948
 
1949
  if (!$this->decrypt->usesNonce()) {
@@ -1951,7 +2032,7 @@ class SSH2
1951
  $this->hmac_size = $this->hmac_check->getLengthInBytes();
1952
  } else {
1953
  $this->hmac_check = new \stdClass;
1954
- $this->hmac_check->name = $mac_algorithm_in;
1955
  //$mac_algorithm_in = 'none';
1956
  $checkKeyLength = 0;
1957
  $this->hmac_size = 0;
@@ -1963,8 +2044,8 @@ class SSH2
1963
  $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
1964
  }
1965
  $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
1966
- $this->hmac_check->name = $mac_algorithm_in;
1967
- $this->hmac_check->etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_in);
1968
  }
1969
 
1970
  $this->regenerate_compression_context = $this->regenerate_decompression_context = true;
@@ -2024,7 +2105,7 @@ class SSH2
2024
  * \phpseclib3\Crypt\Common\SymmetricKey.
2025
  *
2026
  * @param string $algorithm Name of the encryption algorithm
2027
- * @return mixed Instance of \phpseclib3\Crypt\Common\SymmetricKey or null for unknown
2028
  * @access private
2029
  */
2030
  private static function encryption_algorithm_to_crypt_instance($algorithm)
@@ -2073,7 +2154,7 @@ class SSH2
2073
  * \phpseclib3\Crypt\Hash.
2074
  *
2075
  * @param string $algorithm Name of the encryption algorithm
2076
- * @return mixed Instance of \phpseclib3\Crypt\Hash or null for unknown
2077
  * @access private
2078
  */
2079
  private static function mac_algorithm_to_hash_instance($algorithm)
@@ -2156,7 +2237,7 @@ class SSH2
2156
  * Login Helper
2157
  *
2158
  * @param string $username
2159
- * @param string[] ...$args
2160
  * @return bool
2161
  * @see self::_login_helper()
2162
  * @access private
@@ -2171,6 +2252,20 @@ class SSH2
2171
  return $this->login_helper($username);
2172
  }
2173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2174
  while (count($args)) {
2175
  if (!$this->auth_methods_to_continue || !$this->smartMFA) {
2176
  $newargs = $args;
@@ -2195,7 +2290,7 @@ class SSH2
2195
  $hasArray = true;
2196
  break;
2197
  }
2198
- if ($hasString || is_string($arg)) {
2199
  $hasString = true;
2200
  break;
2201
  }
@@ -2218,6 +2313,10 @@ class SSH2
2218
  }
2219
  }
2220
 
 
 
 
 
2221
  foreach ($newargs as $arg) {
2222
  if ($this->login_helper($username, $arg)) {
2223
  return true;
@@ -2271,7 +2370,7 @@ class SSH2
2271
  }
2272
 
2273
  if (strlen($this->last_interactive_response)) {
2274
- return !is_string($password) && !is_array($password) ? false : $this->keyboard_interactive_process($password);
2275
  }
2276
 
2277
  if ($password instanceof PrivateKey) {
@@ -2316,10 +2415,6 @@ class SSH2
2316
  }
2317
  }
2318
 
2319
- if (!is_string($password)) {
2320
- throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string');
2321
- }
2322
-
2323
  $packet = Strings::packSSH2(
2324
  'Cs3bs',
2325
  NET_SSH2_MSG_USERAUTH_REQUEST,
@@ -2385,7 +2480,7 @@ class SSH2
2385
  * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator.
2386
  *
2387
  * @param string $username
2388
- * @param string $password
2389
  * @return bool
2390
  * @access private
2391
  */
@@ -2408,7 +2503,7 @@ class SSH2
2408
  /**
2409
  * Handle the keyboard-interactive requests / responses.
2410
  *
2411
- * @param mixed[] ...$responses
2412
  * @return bool
2413
  * @throws \RuntimeException on connection error
2414
  * @access private
@@ -2702,12 +2797,12 @@ class SSH2
2702
  * In all likelihood, this is not a feature you want to be taking advantage of.
2703
  *
2704
  * @param string $command
2705
- * @param callback $callback
2706
- * @return string
2707
  * @throws \RuntimeException on connection error
2708
  * @access public
2709
  */
2710
- public function exec($command, $callback = null)
2711
  {
2712
  $this->curTimeout = $this->timeout;
2713
  $this->is_timeout = false;
@@ -3273,12 +3368,15 @@ class SSH2
3273
  *
3274
  * @see self::_send_binary_packet()
3275
  * @param bool $skip_channel_filter
3276
- * @return string
3277
  * @access private
3278
  */
3279
  private function get_binary_packet($skip_channel_filter = false)
3280
  {
3281
  if ($skip_channel_filter) {
 
 
 
3282
  $read = [$this->fsock];
3283
  $write = $except = null;
3284
 
@@ -3297,9 +3395,6 @@ class SSH2
3297
  return true;
3298
  }
3299
 
3300
- $read = [$this->fsock];
3301
- $write = $except = null;
3302
-
3303
  $start = microtime(true);
3304
 
3305
  if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) {
@@ -3313,8 +3408,8 @@ class SSH2
3313
  $this->curTimeout-= $elapsed;
3314
  }
3315
 
3316
- $sec = floor($this->curTimeout);
3317
- $usec = 1000000 * ($this->curTimeout - $sec);
3318
 
3319
  // this can return a "stream_select(): unable to select [4]: Interrupted system call" error
3320
  if (!@stream_select($read, $write, $except, $sec, $usec)) {
@@ -3340,14 +3435,14 @@ class SSH2
3340
  }
3341
 
3342
  if ($this->decrypt) {
3343
- switch ($this->decrypt->name) {
3344
  case 'aes128-gcm@openssh.com':
3345
  case 'aes256-gcm@openssh.com':
3346
  $this->decrypt->setNonce(
3347
  $this->decrypt->fixed .
3348
- $this->decrypt->invocation_counter
3349
  );
3350
- Strings::increment_str($this->decrypt->invocation_counter);
3351
  $this->decrypt->setAAD($temp = Strings::shift($raw, 4));
3352
  extract(unpack('Npacket_length', $temp));
3353
  /**
@@ -3392,7 +3487,7 @@ class SSH2
3392
  $remaining_length = 0;
3393
  break;
3394
  default:
3395
- if (!$this->hmac_check instanceof Hash || !$this->hmac_check->etm) {
3396
  $raw = $this->decrypt->decrypt($raw);
3397
  break;
3398
  }
@@ -3441,7 +3536,7 @@ class SSH2
3441
  throw new \RuntimeException('Error reading socket');
3442
  }
3443
 
3444
- $reconstructed = !$this->hmac_check->etm ?
3445
  pack('NCa*', $packet_length, $padding_length, $payload . $padding) :
3446
  $encrypted;
3447
  if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') {
@@ -3459,11 +3554,11 @@ class SSH2
3459
  }
3460
 
3461
  switch ($this->decompress) {
3462
- case NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH:
3463
  if (!$this->isAuthenticated()) {
3464
  break;
3465
  }
3466
- case NET_SSH2_COMPRESSION_ZLIB:
3467
  if ($this->regenerate_decompression_context) {
3468
  $this->regenerate_decompression_context = false;
3469
 
@@ -3525,10 +3620,10 @@ class SSH2
3525
  $adjustLength = false;
3526
  if ($this->decrypt) {
3527
  switch (true) {
3528
- case $this->decrypt->name == 'aes128-gcm@openssh.com':
3529
- case $this->decrypt->name == 'aes256-gcm@openssh.com':
3530
- case $this->decrypt->name == 'chacha20-poly1305@openssh.com':
3531
- case $this->hmac_check instanceof Hash && $this->hmac_check->etm:
3532
  $remaining_length+= $this->decrypt_block_size - 4;
3533
  $adjustLength = true;
3534
  }
@@ -3539,7 +3634,7 @@ class SSH2
3539
  // PuTTY uses 0x9000 as the actual max packet size and so to shall we
3540
  // don't do this when GCM mode is used since GCM mode doesn't encrypt the length
3541
  if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
3542
- if (!$this->bad_key_size_fix && self::bad_algorithm_candidate($this->decrypt ? $this->decrypt->name : '') && !($this->bitmap & SSH2::MASK_LOGIN)) {
3543
  $this->bad_key_size_fix = true;
3544
  $this->reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
3545
  return false;
@@ -3573,7 +3668,7 @@ class SSH2
3573
  * @see self::_get_binary_packet()
3574
  * @param string $payload
3575
  * @param bool $skip_channel_filter
3576
- * @return string
3577
  * @access private
3578
  */
3579
  private function filter($payload, $skip_channel_filter)
@@ -3607,7 +3702,7 @@ class SSH2
3607
  }
3608
 
3609
  // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
3610
- if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
3611
  Strings::shift($payload, 1);
3612
  list($this->banner_message) = Strings::unpackSSH2('s', $payload);
3613
  $payload = $this->get_binary_packet();
@@ -3615,8 +3710,8 @@ class SSH2
3615
 
3616
  // only called when we've already logged in
3617
  if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
3618
- if ($payload === true) {
3619
- return true;
3620
  }
3621
 
3622
  switch (ord($payload[0])) {
@@ -4034,7 +4129,7 @@ class SSH2
4034
  * @param string $data
4035
  * @param string $logged
4036
  * @see self::_get_binary_packet()
4037
- * @return bool
4038
  * @access private
4039
  */
4040
  protected function send_binary_packet($data, $logged = null)
@@ -4049,11 +4144,11 @@ class SSH2
4049
  }
4050
 
4051
  switch ($this->compress) {
4052
- case NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH:
4053
  if (!$this->isAuthenticated()) {
4054
  break;
4055
  }
4056
- case NET_SSH2_COMPRESSION_ZLIB:
4057
  if (!$this->regenerate_compression_context) {
4058
  $header = '';
4059
  } else {
@@ -4077,7 +4172,7 @@ class SSH2
4077
  $padding_length = $packet_length - strlen($data) - 5;
4078
  switch (true) {
4079
  case $this->encrypt && $this->encrypt->usesNonce():
4080
- case $this->hmac_create instanceof Hash && $this->hmac_create->etm:
4081
  $padding_length+= 4;
4082
  $packet_length+= 4;
4083
  }
@@ -4088,7 +4183,7 @@ class SSH2
4088
  $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding);
4089
 
4090
  $hmac = '';
4091
- if ($this->hmac_create instanceof Hash && !$this->hmac_create->etm) {
4092
  if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') {
4093
  $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no));
4094
  $hmac = $this->hmac_create->hash($packet);
@@ -4098,14 +4193,14 @@ class SSH2
4098
  }
4099
 
4100
  if ($this->encrypt) {
4101
- switch ($this->encrypt->name) {
4102
  case 'aes128-gcm@openssh.com':
4103
  case 'aes256-gcm@openssh.com':
4104
  $this->encrypt->setNonce(
4105
  $this->encrypt->fixed .
4106
- $this->encrypt->invocation_counter
4107
  );
4108
- Strings::increment_str($this->encrypt->invocation_counter);
4109
  $this->encrypt->setAAD($temp = ($packet & "\xFF\xFF\xFF\xFF"));
4110
  $packet = $temp . $this->encrypt->encrypt(substr($packet, 4));
4111
  break;
@@ -4129,13 +4224,13 @@ class SSH2
4129
  $packet = $length . $this->encrypt->encrypt(substr($packet, 4));
4130
  break;
4131
  default:
4132
- $packet = $this->hmac_create instanceof Hash && $this->hmac_create->etm ?
4133
  ($packet & "\xFF\xFF\xFF\xFF") . $this->encrypt->encrypt(substr($packet, 4)) :
4134
  $this->encrypt->encrypt($packet);
4135
  }
4136
  }
4137
 
4138
- if ($this->hmac_create instanceof Hash && $this->hmac_create->etm) {
4139
  if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') {
4140
  $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no));
4141
  $hmac = $this->hmac_create->hash($packet);
@@ -4296,7 +4391,7 @@ class SSH2
4296
  *
4297
  * @param int $client_channel
4298
  * @param bool $want_reply
4299
- * @return bool
4300
  * @access private
4301
  */
4302
  private function close_channel($client_channel, $want_reply = false)
@@ -4333,7 +4428,7 @@ class SSH2
4333
  * Disconnect
4334
  *
4335
  * @param int $reason
4336
- * @return bool
4337
  * @access protected
4338
  */
4339
  protected function disconnect_helper($reason)
@@ -4347,7 +4442,7 @@ class SSH2
4347
  }
4348
 
4349
  $this->bitmap = 0;
4350
- if (is_resource($this->fsock) && get_resource_type($this->fsock) == 'stream') {
4351
  fclose($this->fsock);
4352
  }
4353
 
@@ -4502,7 +4597,7 @@ class SSH2
4502
  /**
4503
  * Return the server identification.
4504
  *
4505
- * @return string
4506
  * @access public
4507
  */
4508
  public function getServerIdentification()
@@ -4666,7 +4761,7 @@ class SSH2
4666
  'mcrypt',
4667
  'Eval',
4668
  'PHP'
4669
- ];
4670
  }
4671
 
4672
  $ciphers = [];
@@ -4762,22 +4857,22 @@ class SSH2
4762
  $this->connect();
4763
 
4764
  $compression_map = [
4765
- NET_SSH2_COMPRESSION_NONE => 'none',
4766
- NET_SSH2_COMPRESSION_ZLIB => 'zlib',
4767
- NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH => 'zlib@openssh.com'
4768
  ];
4769
 
4770
  return [
4771
  'kex' => $this->kex_algorithm,
4772
  'hostkey' => $this->signature_format,
4773
  'client_to_server' => [
4774
- 'crypt' => $this->encrypt->name,
4775
- 'mac' => $this->hmac_create->name,
4776
  'comp' => $compression_map[$this->compress],
4777
  ],
4778
  'server_to_client' => [
4779
- 'crypt' => $this->decrypt->name,
4780
- 'mac' => $this->hmac_check->name,
4781
  'comp' => $compression_map[$this->decompress],
4782
  ]
4783
  ];
@@ -4899,7 +4994,7 @@ class SSH2
4899
  * Caching this the first time you connect to a server and checking the result on subsequent connections
4900
  * is recommended. Returns false if the server signature is not signed correctly with the public host key.
4901
  *
4902
- * @return mixed
4903
  * @throws \RuntimeException on badly formatted keys
4904
  * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format
4905
  * @access public
@@ -4951,12 +5046,10 @@ class SSH2
4951
  case 'ssh-rsa':
4952
  case 'rsa-sha2-256':
4953
  case 'rsa-sha2-512':
4954
- if (strlen($signature) < 15) {
4955
- return false;
4956
- }
4957
- Strings::shift($signature, 11);
4958
- $temp = unpack('Nlength', Strings::shift($signature, 4));
4959
- $signature = Strings::shift($signature, $temp['length']);
4960
 
4961
  $key = RSA::loadFormat('OpenSSH', $server_public_host_key)
4962
  ->withPadding(RSA::SIGNATURE_PKCS1);
@@ -5100,11 +5193,12 @@ class SSH2
5100
  /**
5101
  * Return all excising connections
5102
  *
5103
- * @return SSH2[]
5104
  */
5105
  public static function getConnections()
5106
  {
5107
  if (!class_exists('WeakReference')) {
 
5108
  return self::$connections;
5109
  }
5110
  $temp = [];
@@ -5134,7 +5228,7 @@ class SSH2
5134
 
5135
  /**
5136
  * Return the list of authentication methods that may productively continue authentication.
5137
- *
5138
  * @see https://tools.ietf.org/html/rfc4252#section-5.1
5139
  * @return array|null
5140
  */
48
  namespace phpseclib3\Net;
49
 
50
  use phpseclib3\Crypt\Blowfish;
51
+ use phpseclib3\Crypt\Common\SymmetricKey;
52
  use phpseclib3\Crypt\Hash;
53
  use phpseclib3\Crypt\Random;
54
  use phpseclib3\Crypt\RC4;
55
  use phpseclib3\Crypt\Rijndael;
56
+ use phpseclib3\Crypt\Common\PublicKey;
57
  use phpseclib3\Crypt\Common\PrivateKey;
58
  use phpseclib3\Crypt\RSA;
59
  use phpseclib3\Crypt\DSA;
74
  use phpseclib3\Common\Functions\Strings;
75
  use phpseclib3\Crypt\Common\AsymmetricKey;
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  /**
78
  * Pure-PHP implementation of SSHv2.
79
  *
83
  */
84
  class SSH2
85
  {
86
+ /**#@+
87
+ * Compression Types
88
+ *
89
+ * @access private
90
+ */
91
+ /**
92
+ * No compression
93
+ */
94
+ const NET_SSH2_COMPRESSION_NONE = 1;
95
+ /**
96
+ * zlib compression
97
+ */
98
+ const NET_SSH2_COMPRESSION_ZLIB = 2;
99
+ /**
100
+ * zlib@openssh.com
101
+ */
102
+ const NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH = 3;
103
+ /**#@-*/
104
+
105
  // Execution Bitmap Masks
106
  const MASK_CONSTRUCTOR = 0x00000001;
107
  const MASK_CONNECTED = 0x00000002;
204
  /**
205
  * The Socket Object
206
  *
207
+ * @var resource|closed-resource|null
208
  * @access private
209
  */
210
  public $fsock;
234
  * Server Identifier
235
  *
236
  * @see self::getServerIdentification()
237
+ * @var string|false
238
  * @access private
239
  */
240
  protected $server_identifier = false;
410
  */
411
  private $decrypt = false;
412
 
413
+ /**
414
+ * Decryption Algorithm Name
415
+ *
416
+ * @var string|null
417
+ * @access private
418
+ */
419
+ private $decryptName;
420
+
421
+ /**
422
+ * Decryption Invocation Counter
423
+ *
424
+ * Used by GCM
425
+ *
426
+ * @var string|null
427
+ * @access private
428
+ */
429
+ private $decryptInvocationCounter;
430
+
431
  /**
432
  * Server to Client Length Encryption Object
433
  *
446
  */
447
  private $encrypt = false;
448
 
449
+ /**
450
+ * Encryption Algorithm Name
451
+ *
452
+ * @var string|null
453
+ * @access private
454
+ */
455
+ private $encryptName;
456
+
457
+ /**
458
+ * Encryption Invocation Counter
459
+ *
460
+ * Used by GCM
461
+ *
462
+ * @var string|null
463
+ * @access private
464
+ */
465
+ private $encryptInvocationCounter;
466
+
467
  /**
468
  * Client to Server Length Encryption Object
469
  *
482
  */
483
  private $hmac_create = false;
484
 
485
+ /**
486
+ * Client to Server HMAC Name
487
+ *
488
+ * @var string|false
489
+ * @access private
490
+ */
491
+ private $hmac_create_name;
492
+
493
+ /**
494
+ * Client to Server ETM
495
+ *
496
+ * @var int|false
497
+ * @access private
498
+ */
499
+ private $hmac_create_etm;
500
+
501
  /**
502
  * Server to Client HMAC Object
503
  *
507
  */
508
  private $hmac_check = false;
509
 
510
+ /**
511
+ * Server to Client HMAC Name
512
+ *
513
+ * @var string|false
514
+ * @access private
515
+ */
516
+ private $hmac_check_name;
517
+
518
+ /**
519
+ * Server to Client ETM
520
+ *
521
+ * @var int|false
522
+ * @access private
523
+ */
524
+ private $hmac_check_etm;
525
+
526
  /**
527
  * Size of server to client HMAC
528
  *
779
  * Interactive Buffer
780
  *
781
  * @see self::read()
782
+ * @var string
783
  * @access private
784
  */
785
  private $interactiveBuffer = '';
824
  * Real-time log file pointer
825
  *
826
  * @see self::_append_log()
827
+ * @var resource|closed-resource
828
  * @access private
829
  */
830
  private $realtime_log_file;
866
  /**
867
  * Time of first network activity
868
  *
869
+ * @var float
870
  * @access private
871
  */
872
  private $last_packet;
1034
  /**
1035
  * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
1036
  *
1037
+ * @var Agent
1038
  * @access private
1039
  */
1040
  private $agent;
1043
  * Connection storage to replicates ssh2 extension functionality:
1044
  * {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
1045
  *
1046
+ * @var array<string, SSH2|\WeakReference<SSH2>>
1047
  */
1048
  private static $connections;
1049
 
1113
 
1114
  /**
1115
  * The authentication methods that may productively continue authentication.
1116
+ *
1117
  * @see https://tools.ietf.org/html/rfc4252#section-5.1
1118
  * @var array|null
1119
  * @access private
1126
  * @var int
1127
  * @access private
1128
  */
1129
+ private $compress = self::NET_SSH2_COMPRESSION_NONE;
1130
 
1131
  /**
1132
  * Decompression method
1133
  *
1134
+ * @var int
1135
  * @access private
1136
  */
1137
+ private $decompress = self::NET_SSH2_COMPRESSION_NONE;
1138
 
1139
  /**
1140
  * Compression context
1141
  *
1142
+ * @var resource|false|null
1143
  * @access private
1144
  */
1145
  private $compress_context;
1185
  * @param int $port
1186
  * @param int $timeout
1187
  * @see self::login()
 
1188
  * @access public
1189
  */
1190
  public function __construct($host, $port = 22, $timeout = 10)
1268
  31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY']
1269
  );
1270
 
1271
+ /**
1272
+ * Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508
1273
+ * @var \WeakReference<SSH2>|SSH2
1274
+ */
1275
+ self::$connections[$this->getResourceId()] = class_exists('WeakReference')
1276
+ ? \WeakReference::create($this)
1277
+ : $this;
1278
 
1279
  if (is_resource($host)) {
1280
  $this->fsock = $host;
1281
  return;
1282
  }
1283
 
1284
+ if (Strings::is_stringable($host)) {
1285
  $this->host = $host;
1286
  $this->port = $port;
1287
  $this->timeout = $timeout;
1421
  $read = [$this->fsock];
1422
  $write = $except = null;
1423
  $start = microtime(true);
1424
+ $sec = (int) floor($this->curTimeout);
1425
+ $usec = (int) (1000000 * ($this->curTimeout - $sec));
1426
  if (@stream_select($read, $write, $except, $sec, $usec) === false) {
1427
  throw new \RuntimeException('Connection timed out whilst receiving server identification string');
1428
  }
1485
  if (!$this->send_kex_first) {
1486
  $response = $this->get_binary_packet();
1487
 
1488
+ if (is_bool($response) || !strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
1489
  $this->bitmap = 0;
1490
  throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
1491
  }
1620
 
1621
  $kexinit_payload_server = $this->get_binary_packet();
1622
 
1623
+ if (
1624
+ is_bool($kexinit_payload_server)
1625
+ || !strlen($kexinit_payload_server)
1626
+ || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT
1627
+ ) {
1628
  $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR);
1629
  throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
1630
  }
1698
  }
1699
 
1700
  $compression_map = [
1701
+ 'none' => self::NET_SSH2_COMPRESSION_NONE,
1702
+ 'zlib' => self::NET_SSH2_COMPRESSION_ZLIB,
1703
+ 'zlib@openssh.com' => self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH
1704
  ];
1705
 
1706
  $compression_algorithm_in = self::array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client);
1928
  case 'aes256-gcm@openssh.com':
1929
  $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
1930
  $this->encrypt->fixed = substr($nonce, 0, 4);
1931
+ $this->encryptInvocationCounter = substr($nonce, 4, 8);
1932
  case 'chacha20-poly1305@openssh.com':
1933
  break;
1934
  default:
1946
  $this->lengthEncrypt->setKey(substr($key, 32, 32));
1947
  }
1948
  $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
1949
+ $this->encryptName = $encrypt;
1950
  }
1951
 
1952
  $this->decrypt = self::encryption_algorithm_to_crypt_instance($decrypt);
1973
  // see https://tools.ietf.org/html/rfc5647#section-7.1
1974
  $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
1975
  $this->decrypt->fixed = substr($nonce, 0, 4);
1976
+ $this->decryptInvocationCounter = substr($nonce, 4, 8);
1977
  case 'chacha20-poly1305@openssh.com':
1978
  break;
1979
  default:
1991
  $this->lengthDecrypt->setKey(substr($key, 32, 32));
1992
  }
1993
  $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
1994
+ $this->decryptName = $decrypt;
1995
  }
1996
 
1997
  /* The "arcfour128" algorithm is the RC4 cipher, as described in
2012
  list($this->hmac_create, $createKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_out);
2013
  } else {
2014
  $this->hmac_create = new \stdClass;
2015
+ $this->hmac_create_name = $mac_algorithm_out;
2016
  //$mac_algorithm_out = 'none';
2017
  $createKeyLength = 0;
2018
  }
2023
  $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
2024
  }
2025
  $this->hmac_create->setKey(substr($key, 0, $createKeyLength));
2026
+ $this->hmac_create_name = $mac_algorithm_out;
2027
+ $this->hmac_create_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_out);
2028
  }
2029
 
2030
  if (!$this->decrypt->usesNonce()) {
2032
  $this->hmac_size = $this->hmac_check->getLengthInBytes();
2033
  } else {
2034
  $this->hmac_check = new \stdClass;
2035
+ $this->hmac_check_name = $mac_algorithm_in;
2036
  //$mac_algorithm_in = 'none';
2037
  $checkKeyLength = 0;
2038
  $this->hmac_size = 0;
2044
  $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
2045
  }
2046
  $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
2047
+ $this->hmac_check_name = $mac_algorithm_in;
2048
+ $this->hmac_check_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_in);
2049
  }
2050
 
2051
  $this->regenerate_compression_context = $this->regenerate_decompression_context = true;
2105
  * \phpseclib3\Crypt\Common\SymmetricKey.
2106
  *
2107
  * @param string $algorithm Name of the encryption algorithm
2108
+ * @return SymmetricKey|null
2109
  * @access private
2110
  */
2111
  private static function encryption_algorithm_to_crypt_instance($algorithm)
2154
  * \phpseclib3\Crypt\Hash.
2155
  *
2156
  * @param string $algorithm Name of the encryption algorithm
2157
+ * @return array{Hash, int}|null
2158
  * @access private
2159
  */
2160
  private static function mac_algorithm_to_hash_instance($algorithm)
2237
  * Login Helper
2238
  *
2239
  * @param string $username
2240
+ * @param string ...$args
2241
  * @return bool
2242
  * @see self::_login_helper()
2243
  * @access private
2252
  return $this->login_helper($username);
2253
  }
2254
 
2255
+ foreach ($args as $arg) {
2256
+ switch (true) {
2257
+ case $arg instanceof PublicKey:
2258
+ throw new \UnexpectedValueException('A PublicKey object was passed to the login method instead of a PrivateKey object');
2259
+ case $arg instanceof PrivateKey:
2260
+ case $arg instanceof Agent:
2261
+ case is_array($arg):
2262
+ case Strings::is_stringable($arg):
2263
+ break;
2264
+ default:
2265
+ throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string');
2266
+ }
2267
+ }
2268
+
2269
  while (count($args)) {
2270
  if (!$this->auth_methods_to_continue || !$this->smartMFA) {
2271
  $newargs = $args;
2290
  $hasArray = true;
2291
  break;
2292
  }
2293
+ if ($hasString || Strings::is_stringable($arg)) {
2294
  $hasString = true;
2295
  break;
2296
  }
2313
  }
2314
  }
2315
 
2316
+ if (!count($newargs)) {
2317
+ return false;
2318
+ }
2319
+
2320
  foreach ($newargs as $arg) {
2321
  if ($this->login_helper($username, $arg)) {
2322
  return true;
2370
  }
2371
 
2372
  if (strlen($this->last_interactive_response)) {
2373
+ return !Strings::is_stringable($password) && !is_array($password) ? false : $this->keyboard_interactive_process($password);
2374
  }
2375
 
2376
  if ($password instanceof PrivateKey) {
2415
  }
2416
  }
2417
 
 
 
 
 
2418
  $packet = Strings::packSSH2(
2419
  'Cs3bs',
2420
  NET_SSH2_MSG_USERAUTH_REQUEST,
2480
  * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator.
2481
  *
2482
  * @param string $username
2483
+ * @param string|array $password
2484
  * @return bool
2485
  * @access private
2486
  */
2503
  /**
2504
  * Handle the keyboard-interactive requests / responses.
2505
  *
2506
+ * @param string|array ...$responses
2507
  * @return bool
2508
  * @throws \RuntimeException on connection error
2509
  * @access private
2797
  * In all likelihood, this is not a feature you want to be taking advantage of.
2798
  *
2799
  * @param string $command
2800
+ * @return string|bool
2801
+ * @psalm-return ($callback is callable ? bool : string|bool)
2802
  * @throws \RuntimeException on connection error
2803
  * @access public
2804
  */
2805
+ public function exec($command, callable $callback = null)
2806
  {
2807
  $this->curTimeout = $this->timeout;
2808
  $this->is_timeout = false;
3368
  *
3369
  * @see self::_send_binary_packet()
3370
  * @param bool $skip_channel_filter
3371
+ * @return bool|string
3372
  * @access private
3373
  */
3374
  private function get_binary_packet($skip_channel_filter = false)
3375
  {
3376
  if ($skip_channel_filter) {
3377
+ if (!is_resource($this->fsock)) {
3378
+ throw new \InvalidArgumentException('fsock is not a resource.');
3379
+ }
3380
  $read = [$this->fsock];
3381
  $write = $except = null;
3382
 
3395
  return true;
3396
  }
3397
 
 
 
 
3398
  $start = microtime(true);
3399
 
3400
  if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) {
3408
  $this->curTimeout-= $elapsed;
3409
  }
3410
 
3411
+ $sec = (int) floor($this->curTimeout);
3412
+ $usec = (int) (1000000 * ($this->curTimeout - $sec));
3413
 
3414
  // this can return a "stream_select(): unable to select [4]: Interrupted system call" error
3415
  if (!@stream_select($read, $write, $except, $sec, $usec)) {
3435
  }
3436
 
3437
  if ($this->decrypt) {
3438
+ switch ($this->decryptName) {
3439
  case 'aes128-gcm@openssh.com':
3440
  case 'aes256-gcm@openssh.com':
3441
  $this->decrypt->setNonce(
3442
  $this->decrypt->fixed .
3443
+ $this->decryptInvocationCounter
3444
  );
3445
+ Strings::increment_str($this->decryptInvocationCounter);
3446
  $this->decrypt->setAAD($temp = Strings::shift($raw, 4));
3447
  extract(unpack('Npacket_length', $temp));
3448
  /**
3487
  $remaining_length = 0;
3488
  break;
3489
  default:
3490
+ if (!$this->hmac_check instanceof Hash || !$this->hmac_check_etm) {
3491
  $raw = $this->decrypt->decrypt($raw);
3492
  break;
3493
  }
3536
  throw new \RuntimeException('Error reading socket');
3537
  }
3538
 
3539
+ $reconstructed = !$this->hmac_check_etm ?
3540
  pack('NCa*', $packet_length, $padding_length, $payload . $padding) :
3541
  $encrypted;
3542
  if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') {
3554
  }
3555
 
3556
  switch ($this->decompress) {
3557
+ case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH:
3558
  if (!$this->isAuthenticated()) {
3559
  break;
3560
  }
3561
+ case self::NET_SSH2_COMPRESSION_ZLIB:
3562
  if ($this->regenerate_decompression_context) {
3563
  $this->regenerate_decompression_context = false;
3564
 
3620
  $adjustLength = false;
3621
  if ($this->decrypt) {
3622
  switch (true) {
3623
+ case $this->decryptName == 'aes128-gcm@openssh.com':
3624
+ case $this->decryptName == 'aes256-gcm@openssh.com':
3625
+ case $this->decryptName == 'chacha20-poly1305@openssh.com':
3626
+ case $this->hmac_check instanceof Hash && $this->hmac_check_etm:
3627
  $remaining_length+= $this->decrypt_block_size - 4;
3628
  $adjustLength = true;
3629
  }
3634
  // PuTTY uses 0x9000 as the actual max packet size and so to shall we
3635
  // don't do this when GCM mode is used since GCM mode doesn't encrypt the length
3636
  if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
3637
+ if (!$this->bad_key_size_fix && self::bad_algorithm_candidate($this->decrypt ? $this->decryptName : '') && !($this->bitmap & SSH2::MASK_LOGIN)) {
3638
  $this->bad_key_size_fix = true;
3639
  $this->reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
3640
  return false;
3668
  * @see self::_get_binary_packet()
3669
  * @param string $payload
3670
  * @param bool $skip_channel_filter
3671
+ * @return string|bool
3672
  * @access private
3673
  */
3674
  private function filter($payload, $skip_channel_filter)
3702
  }
3703
 
3704
  // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
3705
+ if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && !is_bool($payload) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
3706
  Strings::shift($payload, 1);
3707
  list($this->banner_message) = Strings::unpackSSH2('s', $payload);
3708
  $payload = $this->get_binary_packet();
3710
 
3711
  // only called when we've already logged in
3712
  if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
3713
+ if (is_bool($payload)) {
3714
+ return $payload;
3715
  }
3716
 
3717
  switch (ord($payload[0])) {
4129
  * @param string $data
4130
  * @param string $logged
4131
  * @see self::_get_binary_packet()
4132
+ * @return void
4133
  * @access private
4134
  */
4135
  protected function send_binary_packet($data, $logged = null)
4144
  }
4145
 
4146
  switch ($this->compress) {
4147
+ case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH:
4148
  if (!$this->isAuthenticated()) {
4149
  break;
4150
  }
4151
+ case self::NET_SSH2_COMPRESSION_ZLIB:
4152
  if (!$this->regenerate_compression_context) {
4153
  $header = '';
4154
  } else {
4172
  $padding_length = $packet_length - strlen($data) - 5;
4173
  switch (true) {
4174
  case $this->encrypt && $this->encrypt->usesNonce():
4175
+ case $this->hmac_create instanceof Hash && $this->hmac_create_etm:
4176
  $padding_length+= 4;
4177
  $packet_length+= 4;
4178
  }
4183
  $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding);
4184
 
4185
  $hmac = '';
4186
+ if ($this->hmac_create instanceof Hash && !$this->hmac_create_etm) {
4187
  if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') {
4188
  $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no));
4189
  $hmac = $this->hmac_create->hash($packet);
4193
  }
4194
 
4195
  if ($this->encrypt) {
4196
+ switch ($this->encryptName) {
4197
  case 'aes128-gcm@openssh.com':
4198
  case 'aes256-gcm@openssh.com':
4199
  $this->encrypt->setNonce(
4200
  $this->encrypt->fixed .
4201
+ $this->encryptInvocationCounter
4202
  );
4203
+ Strings::increment_str($this->encryptInvocationCounter);
4204
  $this->encrypt->setAAD($temp = ($packet & "\xFF\xFF\xFF\xFF"));
4205
  $packet = $temp . $this->encrypt->encrypt(substr($packet, 4));
4206
  break;
4224
  $packet = $length . $this->encrypt->encrypt(substr($packet, 4));
4225
  break;
4226
  default:
4227
+ $packet = $this->hmac_create instanceof Hash && $this->hmac_create_etm ?
4228
  ($packet & "\xFF\xFF\xFF\xFF") . $this->encrypt->encrypt(substr($packet, 4)) :
4229
  $this->encrypt->encrypt($packet);
4230
  }
4231
  }
4232
 
4233
+ if ($this->hmac_create instanceof Hash && $this->hmac_create_etm) {
4234
  if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') {
4235
  $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no));
4236
  $hmac = $this->hmac_create->hash($packet);
4391
  *
4392
  * @param int $client_channel
4393
  * @param bool $want_reply
4394
+ * @return void
4395
  * @access private
4396
  */
4397
  private function close_channel($client_channel, $want_reply = false)
4428
  * Disconnect
4429
  *
4430
  * @param int $reason
4431
+ * @return false
4432
  * @access protected
4433
  */
4434
  protected function disconnect_helper($reason)
4442
  }
4443
 
4444
  $this->bitmap = 0;
4445
+ if (is_resource($this->fsock) && get_resource_type($this->fsock) === 'stream') {
4446
  fclose($this->fsock);
4447
  }
4448
 
4597
  /**
4598
  * Return the server identification.
4599
  *
4600
+ * @return string|false
4601
  * @access public
4602
  */
4603
  public function getServerIdentification()
4761
  'mcrypt',
4762
  'Eval',
4763
  'PHP'
4764
+ ];
4765
  }
4766
 
4767
  $ciphers = [];
4857
  $this->connect();
4858
 
4859
  $compression_map = [
4860
+ self::NET_SSH2_COMPRESSION_NONE => 'none',
4861
+ self::NET_SSH2_COMPRESSION_ZLIB => 'zlib',
4862
+ self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH => 'zlib@openssh.com'
4863
  ];
4864
 
4865
  return [
4866
  'kex' => $this->kex_algorithm,
4867
  'hostkey' => $this->signature_format,
4868
  'client_to_server' => [
4869
+ 'crypt' => $this->encryptName,
4870
+ 'mac' => $this->hmac_create_name,
4871
  'comp' => $compression_map[$this->compress],
4872
  ],
4873
  'server_to_client' => [
4874
+ 'crypt' => $this->decryptName,
4875
+ 'mac' => $this->hmac_check_name,
4876
  'comp' => $compression_map[$this->decompress],
4877
  ]
4878
  ];
4994
  * Caching this the first time you connect to a server and checking the result on subsequent connections
4995
  * is recommended. Returns false if the server signature is not signed correctly with the public host key.
4996
  *
4997
+ * @return string|false
4998
  * @throws \RuntimeException on badly formatted keys
4999
  * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format
5000
  * @access public
5046
  case 'ssh-rsa':
5047
  case 'rsa-sha2-256':
5048
  case 'rsa-sha2-512':
5049
+ // could be ssh-rsa, rsa-sha2-256, rsa-sha2-512
5050
+ // we don't check here because we already checked in key_exchange
5051
+ // some signatures have the type embedded within the message and some don't
5052
+ list(, $signature) = Strings::unpackSSH2('ss', $signature);
 
 
5053
 
5054
  $key = RSA::loadFormat('OpenSSH', $server_public_host_key)
5055
  ->withPadding(RSA::SIGNATURE_PKCS1);
5193
  /**
5194
  * Return all excising connections
5195
  *
5196
+ * @return array<string, SSH2>
5197
  */
5198
  public static function getConnections()
5199
  {
5200
  if (!class_exists('WeakReference')) {
5201
+ /** @var array<string, SSH2> */
5202
  return self::$connections;
5203
  }
5204
  $temp = [];
5228
 
5229
  /**
5230
  * Return the list of authentication methods that may productively continue authentication.
5231
+ *
5232
  * @see https://tools.ietf.org/html/rfc4252#section-5.1
5233
  * @return array|null
5234
  */
vendor/phpseclib/phpseclib/psalm.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <psalm
3
+ errorLevel="6"
4
+ resolveFromConfigFile="true"
5
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
+ xmlns="https://getpsalm.org/schema/config"
7
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
8
+ findUnusedPsalmSuppress="true"
9
+ sealAllMethods="true"
10
+ >
11
+ <projectFiles>
12
+ <directory name="phpseclib/Net"/>
13
+ </projectFiles>
14
+ <fileExtensions>
15
+ <extension name=".php"/>
16
+ </fileExtensions>
17
+ <issueHandlers>
18
+ <Trace>
19
+ <errorLevel type="error">
20
+ <directory name="."/>
21
+ </errorLevel>
22
+ </Trace>
23
+ <UndefinedConstant>
24
+ <errorLevel type="suppress">
25
+ <directory name="phpseclib/Net"/>
26
+ </errorLevel>
27
+ </UndefinedConstant>
28
+ </issueHandlers>
29
+ </psalm>