SSH SFTP Updater Support - Version 0.8.0

Version Description

  • 2018/Dec/14 =

  • TWEAK: Replaced the deprecated 'var' visibility indicator

  • TWEAK: Add various sanity checks to return error codes instead of causing fatal errors if another component calls the WP_Filesystem API incorrectly

  • TWEAK: Add an extra sanity check that should prevent a fatal error if a component directly requests the 'direct' filesystem method but WP won't let it have it

Download this release

Release Info

Developer DavidAnderson
Plugin Icon wp plugin SSH SFTP Updater Support
Version 0.8.0
Comparing to
See all releases

Code changes from version 0.7.6 to 0.8.0

class-wp-filesystem-ssh2.php CHANGED
@@ -1,350 +1,376 @@
1
- <?php
2
- /**
3
- * WordPress SSH2 Filesystem.
4
- *
5
- * @package WordPress
6
- * @subpackage Filesystem
7
- */
8
-
9
- set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/phpseclib/');
10
-
11
- require_once('Net/SFTP.php');
12
- require_once('Crypt/RSA.php');
13
-
14
- /**
15
- * WordPress Filesystem Class for implementing SSH2.
16
- *
17
- * @since 2.7
18
- * @package WordPress
19
- * @subpackage Filesystem
20
- * @uses WP_Filesystem_Base Extends class
21
- */
22
-
23
- class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
24
-
25
- var $link = false;
26
- var $sftp_link = false;
27
- var $keys = false;
28
- var $password = false;
29
- var $errors = array();
30
- var $options = array();
31
-
32
- public function __construct($opt='') {
33
- $this->method = 'ssh2';
34
- $this->errors = new WP_Error();
35
-
36
- if ( !function_exists('stream_get_contents') ) {
37
- $this->errors->add('ssh2_php_requirement', __('We require the PHP5 function <code>stream_get_contents()</code>'));
38
- return false;
39
- }
40
-
41
- // Set defaults:
42
- if ( empty($opt['port']) )
43
- $this->options['port'] = 22;
44
- else
45
- $this->options['port'] = $opt['port'];
46
-
47
- if ( empty($opt['hostname']) )
48
- $this->errors->add('empty_hostname', __('SSH2 hostname is required'));
49
- else
50
- $this->options['hostname'] = $opt['hostname'];
51
-
52
- if ( ! empty($opt['base']) )
53
- $this->wp_base = $opt['base'];
54
-
55
- if ( !empty ($opt['private_key']) ) {
56
- $this->options['private_key'] = $opt['private_key'];
57
-
58
- $this->keys = true;
59
- } elseif ( empty ($opt['username']) ) {
60
- $this->errors->add('empty_username', __('SSH2 username is required'));
61
- }
62
-
63
- if ( !empty($opt['username']) )
64
- $this->options['username'] = $opt['username'];
65
-
66
- if ( empty ($opt['password']) ) {
67
- if ( !$this->keys ) //password can be blank if we are using keys
68
- $this->errors->add('empty_password', __('SSH2 password is required'));
69
- } else {
70
- $this->options['password'] = $opt['password'];
71
-
72
- $this->password = true;
73
- }
74
- }
75
-
76
- public function connect() {
77
- $this->link = new Net_SFTP($this->options['hostname'], $this->options['port']);
78
-
79
- if ( !$this->keys ) {
80
- if ( ! $this->link->login($this->options['username'], $this->options['password']) ) {
81
- if ( $this->handle_connect_error() )
82
- return false;
83
- $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
84
- return false;
85
- }
86
- } else {
87
- $rsa = new Crypt_RSA();
88
- if ( $this->password ) {
89
- $rsa->setPassword($this->options['password']);
90
- }
91
- $rsa->loadKey($this->options['private_key']);
92
- if ( ! $this->link->login($this->options['username'], $rsa ) ) {
93
- if ( $this->handle_connect_error() )
94
- return false;
95
- $this->errors->add('auth', sprintf(__('Private key incorrect for %s'), $this->options['username']));
96
- $this->errors->add('auth', __('Make sure that the key you are using is an RSA key and not a DSA key'));
97
- return false;
98
- }
99
- }
100
-
101
- return true;
102
- }
103
-
104
- public function handle_connect_error() {
105
- if ( ! $this->link->isConnected() ) {
106
- $this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
107
- $this->errors->add('connect2', __('If SELinux is installed check to make sure that <code>httpd_can_network_connect</code> is set to 1'));
108
- return true;
109
- }
110
-
111
- return false;
112
- }
113
-
114
- public function run_command( $command, $returnbool = false) {
115
-
116
- if ( ! $this->link )
117
- return false;
118
-
119
- $data = $this->link->exec($command);
120
-
121
- if ( $returnbool )
122
- return ( $data === false ) ? false : '' != trim($data);
123
- else
124
- return $data;
125
- }
126
-
127
- public function get_contents($file, $type = '', $resumepos = 0 ) {
128
- return $this->link->get($file);
129
- }
130
-
131
- public function get_contents_array($file) {
132
- $lines = preg_split('#(\r\n|\r|\n)#', $this->link->get($file), -1, PREG_SPLIT_DELIM_CAPTURE);
133
- $newLines = array();
134
- for ($i = 0; $i < count($lines); $i+= 2)
135
- $newLines[] = $lines[$i] . $lines[$i + 1];
136
- return $newLines;
137
- }
138
-
139
- public function put_contents($file, $contents, $mode = false ) {
140
- $ret = $this->link->put($file, $contents);
141
-
142
- $this->chmod($file, $mode);
143
-
144
- return false !== $ret;
145
- }
146
-
147
- public function cwd() {
148
- $cwd = $this->run_command('pwd');
149
- if ( $cwd )
150
- $cwd = trailingslashit($cwd);
151
- return $cwd;
152
- }
153
-
154
- public function chdir($dir) {
155
- $this->list->chdir($dir);
156
- return $this->run_command('cd ' . $dir, true);
157
- }
158
-
159
- public function chgrp($file, $group, $recursive = false ) {
160
- if ( ! $this->exists($file) )
161
- return false;
162
- if ( ! $recursive || ! $this->is_dir($file) )
163
- return $this->run_command(sprintf('chgrp %o %s', $mode, escapeshellarg($file)), true);
164
- return $this->run_command(sprintf('chgrp -R %o %s', $mode, escapeshellarg($file)), true);
165
- }
166
-
167
- public function chmod($file, $mode = false, $recursive = false) {
168
- return $mode === false ? false : $this->link->chmod($mode, $file, $recursive);
169
- }
170
-
171
- public function chown($file, $owner, $recursive = false ) {
172
- if ( ! $this->exists($file) )
173
- return false;
174
- if ( ! $recursive || ! $this->is_dir($file) )
175
- return $this->run_command(sprintf('chown %o %s', $mode, escapeshellarg($file)), true);
176
- return $this->run_command(sprintf('chown -R %o %s', $mode, escapeshellarg($file)), true);
177
- }
178
-
179
- public function owner($file, $owneruid = false) {
180
- if ($owneruid === false) {
181
- $result = $this->link->stat($file);
182
- $owneruid = $result['uid'];
183
- }
184
-
185
- if ( ! $owneruid )
186
- return false;
187
- if ( ! function_exists('posix_getpwuid') )
188
- return $owneruid;
189
- $ownerarray = posix_getpwuid($owneruid);
190
- return $ownerarray['name'];
191
- }
192
-
193
- public function getchmod($file) {
194
- $result = $this->link->stat($file);
195
-
196
- return substr(decoct($result['permissions']),3);
197
- }
198
-
199
- public function group($file, $gid = false) {
200
- if ($gid === false) {
201
- $result = $this->link->stat($file);
202
- $gid = $result['gid'];
203
- }
204
-
205
- if ( ! $gid )
206
- return false;
207
- if ( ! function_exists('posix_getgrgid') )
208
- return $gid;
209
- $grouparray = posix_getgrgid($gid);
210
- return $grouparray['name'];
211
- }
212
-
213
- public function copy($source, $destination, $overwrite = false, $mode = false) {
214
- if ( ! $overwrite && $this->exists($destination) )
215
- return false;
216
- $content = $this->get_contents($source);
217
- if ( false === $content)
218
- return false;
219
- return $this->put_contents($destination, $content, $mode);
220
- }
221
-
222
- public function move($source, $destination, $overwrite = false) {
223
- return $this->link->rename($source, $destination);
224
- }
225
-
226
- public function delete($file, $recursive = false, $type = false) {
227
- if ( 'f' == $type || $this->is_file($file) )
228
- return $this->link->delete($file);
229
- if ( ! $recursive )
230
- return $this->link->rmdir($file);
231
- return $this->link->delete($file, $recursive);
232
- }
233
-
234
- public function exists($file) {
235
- return $this->link->stat($file) !== false;
236
- }
237
-
238
- public function is_file($file) {
239
- $result = $this->link->stat($file);
240
- return $result['type'] == NET_SFTP_TYPE_REGULAR;
241
- }
242
-
243
- public function is_dir($path) {
244
- $result = $this->link->stat($path);
245
- return $result['type'] == NET_SFTP_TYPE_DIRECTORY;
246
- }
247
-
248
- public function is_readable($file) {
249
- return true;
250
-
251
- return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
252
- }
253
-
254
- public function is_writable($file) {
255
- return true;
256
-
257
- return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
258
- }
259
-
260
- public function atime($file) {
261
- $result = $this->link->stat($file);
262
- return $result['atime'];
263
- }
264
-
265
- public function mtime($file) {
266
- $result = $this->link->stat($file);
267
- return $result['mtime'];
268
- }
269
-
270
- public function size($file) {
271
- $result = $this->link->stat($file);
272
- return $result['size'];
273
- }
274
-
275
- public function touch($file, $time = 0, $atime = 0) {
276
- //Not implmented.
277
- }
278
-
279
- public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
280
- $path = untrailingslashit($path);
281
- if ( ! $chmod )
282
- $chmod = FS_CHMOD_DIR;
283
- //if ( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) )
284
- // return false;
285
- if ( ! $this->link->mkdir($path) && $this->link->chmod($chmod, $path) )
286
- return false;
287
- if ( $chown )
288
- $this->chown($path, $chown);
289
- if ( $chgrp )
290
- $this->chgrp($path, $chgrp);
291
- return true;
292
- }
293
-
294
- public function rmdir($path, $recursive = false) {
295
- return $this->delete($path, $recursive);
296
- }
297
-
298
- public function dirlist($path, $include_hidden = true, $recursive = false) {
299
- if ( $this->is_file($path) ) {
300
- $limit_file = basename($path);
301
- $path = dirname($path);
302
- } else {
303
- $limit_file = false;
304
- }
305
-
306
- if ( ! $this->is_dir($path) )
307
- return false;
308
-
309
- $ret = array();
310
- $entries = $this->link->rawlist($path);
311
-
312
- if ( $entries === false )
313
- return false;
314
-
315
- foreach ($entries as $name => $entry) {
316
- $struc = array();
317
- $struc['name'] = $name;
318
-
319
- if ( '.' == $struc['name'] || '..' == $struc['name'] )
320
- continue; //Do not care about these folders.
321
-
322
- if ( ! $include_hidden && '.' == $struc['name'][0] )
323
- continue;
324
-
325
- if ( $limit_file && $struc['name'] != $limit_file )
326
- continue;
327
-
328
- $struc['perms'] = $entry['permissions'];
329
- $struc['permsn'] = $this->getnumchmodfromh($struc['perms']);
330
- $struc['number'] = false;
331
- $struc['owner'] = $this->owner($path.'/'.$name, $entry['uid']);
332
- $struc['group'] = $this->group($path.'/'.$name, $entry['gid']);
333
- $struc['size'] = $entry['size'];//$this->size($path.'/'.$entry);
334
- $struc['lastmodunix']= $entry['mtime'];//$this->mtime($path.'/'.$entry);
335
- $struc['lastmod'] = date('M j',$struc['lastmodunix']);
336
- $struc['time'] = date('h:i:s',$struc['lastmodunix']);
337
- $struc['type'] = $entry['type'] == NET_SFTP_TYPE_DIRECTORY ? 'd' : 'f';
338
-
339
- if ( 'd' == $struc['type'] ) {
340
- if ( $recursive )
341
- $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
342
- else
343
- $struc['files'] = array();
344
- }
345
-
346
- $ret[ $struc['name'] ] = $struc;
347
- }
348
- return $ret;
349
- }
350
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WordPress SSH2 Filesystem.
4
+ *
5
+ * @package WordPress
6
+ * @subpackage Filesystem
7
+ */
8
+
9
+ set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/phpseclib/');
10
+
11
+ require_once('Net/SFTP.php');
12
+ require_once('Crypt/RSA.php');
13
+
14
+ /**
15
+ * WordPress Filesystem Class for implementing SSH2.
16
+ *
17
+ * @since 2.7
18
+ * @package WordPress
19
+ * @subpackage Filesystem
20
+ * @uses WP_Filesystem_Base Extends class
21
+ */
22
+
23
+ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
24
+
25
+ public $link = false;
26
+ public $sftp_link = false;
27
+ public $keys = false;
28
+ public $password = false;
29
+ public $errors = array();
30
+ public $options = array();
31
+
32
+ public function __construct($opt='') {
33
+ $this->method = 'ssh2';
34
+ $this->errors = new WP_Error();
35
+
36
+ if ( !function_exists('stream_get_contents') ) {
37
+ $this->errors->add('ssh2_php_requirement', __('We require the PHP5 function <code>stream_get_contents()</code>'));
38
+ return false;
39
+ }
40
+
41
+ // Set defaults:
42
+ if ( empty($opt['port']) )
43
+ $this->options['port'] = 22;
44
+ else
45
+ $this->options['port'] = $opt['port'];
46
+
47
+ if ( empty($opt['hostname']) )
48
+ $this->errors->add('empty_hostname', __('SSH2 hostname is required'));
49
+ else
50
+ $this->options['hostname'] = $opt['hostname'];
51
+
52
+ if ( ! empty($opt['base']) )
53
+ $this->wp_base = $opt['base'];
54
+
55
+ if ( !empty ($opt['private_key']) ) {
56
+ $this->options['private_key'] = $opt['private_key'];
57
+
58
+ $this->keys = true;
59
+ } elseif ( empty ($opt['username']) ) {
60
+ $this->errors->add('empty_username', __('SSH2 username is required'));
61
+ }
62
+
63
+ if ( !empty($opt['username']) )
64
+ $this->options['username'] = $opt['username'];
65
+
66
+ if ( empty ($opt['password']) ) {
67
+ if ( !$this->keys ) //password can be blank if we are using keys
68
+ $this->errors->add('empty_password', __('SSH2 password is required'));
69
+ } else {
70
+ $this->options['password'] = $opt['password'];
71
+
72
+ $this->password = true;
73
+ }
74
+ }
75
+
76
+ public function connect() {
77
+
78
+ if (empty($this->options['hostname']) || empty($this->options['username'])) {
79
+ $this->errors->add('auth', sprintf(__('No connection credentials available'), $this->options));
80
+ return false;
81
+ }
82
+
83
+ $this->link = new Net_SFTP($this->options['hostname'], $this->options['port']);
84
+
85
+ if ( !$this->keys ) {
86
+ if ( ! $this->link->login($this->options['username'], $this->options['password']) ) {
87
+ if ( $this->handle_connect_error() )
88
+ return false;
89
+ $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
90
+ return false;
91
+ }
92
+ } else {
93
+ $rsa = new Crypt_RSA();
94
+ if ( $this->password ) {
95
+ $rsa->setPassword($this->options['password']);
96
+ }
97
+ $rsa->loadKey($this->options['private_key']);
98
+ if ( ! $this->link->login($this->options['username'], $rsa ) ) {
99
+ if ( $this->handle_connect_error() )
100
+ return false;
101
+ $this->errors->add('auth', sprintf(__('Private key incorrect for %s'), $this->options['username']));
102
+ $this->errors->add('auth', __('Make sure that the key you are using is an RSA key and not a DSA key'));
103
+ return false;
104
+ }
105
+ }
106
+
107
+ return true;
108
+ }
109
+
110
+ public function handle_connect_error() {
111
+ if ( ! $this->link->isConnected() ) {
112
+ $this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
113
+ $this->errors->add('connect2', __('If SELinux is installed check to make sure that <code>httpd_can_network_connect</code> is set to 1'));
114
+ return true;
115
+ }
116
+
117
+ return false;
118
+ }
119
+
120
+ public function run_command( $command, $returnbool = false) {
121
+
122
+ if ( ! $this->link )
123
+ return false;
124
+
125
+ $data = $this->link->exec($command);
126
+
127
+ if ( $returnbool )
128
+ return ( $data === false ) ? false : '' != trim($data);
129
+ else
130
+ return $data;
131
+ }
132
+
133
+ public function get_contents($file, $type = '', $resumepos = 0 ) {
134
+ if (!is_a($this->link, 'Net_SFTP')) return false;
135
+ return $this->link->get($file);
136
+ }
137
+
138
+ public function get_contents_array($file) {
139
+ if (!is_a($this->link, 'Net_SFTP')) return false;
140
+ $lines = preg_split('#(\r\n|\r|\n)#', $this->link->get($file), -1, PREG_SPLIT_DELIM_CAPTURE);
141
+ $newLines = array();
142
+ for ($i = 0; $i < count($lines); $i+= 2)
143
+ $newLines[] = $lines[$i] . $lines[$i + 1];
144
+ return $newLines;
145
+ }
146
+
147
+ public function put_contents($file, $contents, $mode = false ) {
148
+ if (!is_a($this->link, 'Net_SFTP')) return false;
149
+ $ret = $this->link->put($file, $contents);
150
+
151
+ $this->chmod($file, $mode);
152
+
153
+ return false !== $ret;
154
+ }
155
+
156
+ public function cwd() {
157
+ if (!is_a($this->link, 'Net_SFTP')) return false;
158
+ $cwd = $this->run_command('pwd');
159
+ if ( $cwd )
160
+ $cwd = trailingslashit($cwd);
161
+ return $cwd;
162
+ }
163
+
164
+ public function chdir($dir) {
165
+ if (!is_a($this->link, 'Net_SFTP')) return false;
166
+ $this->list->chdir($dir);
167
+ return $this->run_command('cd ' . $dir, true);
168
+ }
169
+
170
+ public function chgrp($file, $group, $recursive = false ) {
171
+ if ( ! $this->exists($file) )
172
+ return false;
173
+ if ( ! $recursive || ! $this->is_dir($file) )
174
+ return $this->run_command(sprintf('chgrp %o %s', $mode, escapeshellarg($file)), true);
175
+ return $this->run_command(sprintf('chgrp -R %o %s', $mode, escapeshellarg($file)), true);
176
+ }
177
+
178
+ public function chmod($file, $mode = false, $recursive = false) {
179
+ if (!is_a($this->link, 'Net_SFTP')) return false;
180
+ return $mode === false ? false : $this->link->chmod($mode, $file, $recursive);
181
+ }
182
+
183
+ public function chown($file, $owner, $recursive = false ) {
184
+ if (!is_a($this->link, 'Net_SFTP')) return false;
185
+ if ( ! $this->exists($file) )
186
+ return false;
187
+ if ( ! $recursive || ! $this->is_dir($file) )
188
+ return $this->run_command(sprintf('chown %o %s', $mode, escapeshellarg($file)), true);
189
+ return $this->run_command(sprintf('chown -R %o %s', $mode, escapeshellarg($file)), true);
190
+ }
191
+
192
+ public function owner($file, $owneruid = false) {
193
+ if (!is_a($this->link, 'Net_SFTP')) return false;
194
+ if ($owneruid === false) {
195
+ $result = $this->link->stat($file);
196
+ $owneruid = $result['uid'];
197
+ }
198
+
199
+ if ( ! $owneruid )
200
+ return false;
201
+ if ( ! function_exists('posix_getpwuid') )
202
+ return $owneruid;
203
+ $ownerarray = posix_getpwuid($owneruid);
204
+ return $ownerarray['name'];
205
+ }
206
+
207
+ public function getchmod($file) {
208
+ $result = $this->link->stat($file);
209
+
210
+ return substr(decoct($result['permissions']),3);
211
+ }
212
+
213
+ public function group($file, $gid = false) {
214
+ if (!is_a($this->link, 'Net_SFTP')) return false;
215
+ if ($gid === false) {
216
+ $result = $this->link->stat($file);
217
+ $gid = $result['gid'];
218
+ }
219
+
220
+ if ( ! $gid )
221
+ return false;
222
+ if ( ! function_exists('posix_getgrgid') )
223
+ return $gid;
224
+ $grouparray = posix_getgrgid($gid);
225
+ return $grouparray['name'];
226
+ }
227
+
228
+ public function copy($source, $destination, $overwrite = false, $mode = false) {
229
+ if (!is_a($this->link, 'Net_SFTP')) return false;
230
+ if ( ! $overwrite && $this->exists($destination) )
231
+ return false;
232
+ $content = $this->get_contents($source);
233
+ if ( false === $content)
234
+ return false;
235
+ return $this->put_contents($destination, $content, $mode);
236
+ }
237
+
238
+ public function move($source, $destination, $overwrite = false) {
239
+ if (!is_a($this->link, 'Net_SFTP')) return false;
240
+ return $this->link->rename($source, $destination);
241
+ }
242
+
243
+ public function delete($file, $recursive = false, $type = false) {
244
+ if (!is_a($this->link, 'Net_SFTP')) return false;
245
+ if ( 'f' == $type || $this->is_file($file) )
246
+ return $this->link->delete($file);
247
+ if ( ! $recursive )
248
+ return $this->link->rmdir($file);
249
+ return $this->link->delete($file, $recursive);
250
+ }
251
+
252
+ public function exists($file) {
253
+ return $this->link->stat($file) !== false;
254
+ }
255
+
256
+ public function is_file($file) {
257
+ $result = $this->link->stat($file);
258
+ return $result['type'] == NET_SFTP_TYPE_REGULAR;
259
+ }
260
+
261
+ public function is_dir($path) {
262
+ $result = $this->link->stat($path);
263
+ return $result['type'] == NET_SFTP_TYPE_DIRECTORY;
264
+ }
265
+
266
+ public function is_readable($file) {
267
+ if (!is_a($this->link, 'Net_SFTP')) return false;
268
+ return true;
269
+
270
+ return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
271
+ }
272
+
273
+ public function is_writable($file) {
274
+ if (!is_a($this->link, 'Net_SFTP')) return false;
275
+ return true;
276
+
277
+ return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
278
+ }
279
+
280
+ public function atime($file) {
281
+ if (!is_a($this->link, 'Net_SFTP')) return false;
282
+ $result = $this->link->stat($file);
283
+ return $result['atime'];
284
+ }
285
+
286
+ public function mtime($file) {
287
+ if (!is_a($this->link, 'Net_SFTP')) return false;
288
+ $result = $this->link->stat($file);
289
+ return $result['mtime'];
290
+ }
291
+
292
+ public function size($file) {
293
+ if (!is_a($this->link, 'Net_SFTP')) return false;
294
+ $result = $this->link->stat($file);
295
+ return $result['size'];
296
+ }
297
+
298
+ public function touch($file, $time = 0, $atime = 0) {
299
+ //Not implmented.
300
+ }
301
+
302
+ public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
303
+ if (!is_a($this->link, 'Net_SFTP')) return false;
304
+ $path = untrailingslashit($path);
305
+ if ( ! $chmod )
306
+ $chmod = FS_CHMOD_DIR;
307
+ //if ( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) )
308
+ // return false;
309
+ if ( ! $this->link->mkdir($path) && $this->link->chmod($chmod, $path) )
310
+ return false;
311
+ if ( $chown )
312
+ $this->chown($path, $chown);
313
+ if ( $chgrp )
314
+ $this->chgrp($path, $chgrp);
315
+ return true;
316
+ }
317
+
318
+ public function rmdir($path, $recursive = false) {
319
+ if (!is_a($this->link, 'Net_SFTP')) return false;
320
+ return $this->delete($path, $recursive);
321
+ }
322
+
323
+ public function dirlist($path, $include_hidden = true, $recursive = false) {
324
+ if (!is_a($this->link, 'Net_SFTP')) return false;
325
+ if ( $this->is_file($path) ) {
326
+ $limit_file = basename($path);
327
+ $path = dirname($path);
328
+ } else {
329
+ $limit_file = false;
330
+ }
331
+
332
+ if ( ! $this->is_dir($path) )
333
+ return false;
334
+
335
+ $ret = array();
336
+ $entries = $this->link->rawlist($path);
337
+
338
+ if ( $entries === false )
339
+ return false;
340
+
341
+ foreach ($entries as $name => $entry) {
342
+ $struc = array();
343
+ $struc['name'] = $name;
344
+
345
+ if ( '.' == $struc['name'] || '..' == $struc['name'] )
346
+ continue; //Do not care about these folders.
347
+
348
+ if ( ! $include_hidden && '.' == $struc['name'][0] )
349
+ continue;
350
+
351
+ if ( $limit_file && $struc['name'] != $limit_file )
352
+ continue;
353
+
354
+ $struc['perms'] = $entry['permissions'];
355
+ $struc['permsn'] = $this->getnumchmodfromh($struc['perms']);
356
+ $struc['number'] = false;
357
+ $struc['owner'] = $this->owner($path.'/'.$name, $entry['uid']);
358
+ $struc['group'] = $this->group($path.'/'.$name, $entry['gid']);
359
+ $struc['size'] = $entry['size'];//$this->size($path.'/'.$entry);
360
+ $struc['lastmodunix']= $entry['mtime'];//$this->mtime($path.'/'.$entry);
361
+ $struc['lastmod'] = date('M j',$struc['lastmodunix']);
362
+ $struc['time'] = date('h:i:s',$struc['lastmodunix']);
363
+ $struc['type'] = $entry['type'] == NET_SFTP_TYPE_DIRECTORY ? 'd' : 'f';
364
+
365
+ if ( 'd' == $struc['type'] ) {
366
+ if ( $recursive )
367
+ $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
368
+ else
369
+ $struc['files'] = array();
370
+ }
371
+
372
+ $ret[ $struc['name'] ] = $struc;
373
+ }
374
+ return $ret;
375
+ }
376
+ }
phpseclib/Crypt/Base.php CHANGED
@@ -661,7 +661,7 @@ class Crypt_Base
661
  $count = isset($func_args[4]) ? $func_args[4] : 1000;
662
 
663
  // Keylength
664
- if (isset($func_args[5]) && $func_args[5] > 0) {
665
  $dkLen = $func_args[5];
666
  } else {
667
  $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
@@ -696,10 +696,10 @@ class Crypt_Base
696
  include_once 'Crypt/Hash.php';
697
  }
698
  $i = 1;
699
- $hmac = new Crypt_Hash();
700
- $hmac->setHash($hash);
701
- $hmac->setKey($password);
702
  while (strlen($key) < $dkLen) {
 
 
 
703
  $f = $u = $hmac->hash($salt . pack('N', $i++));
704
  for ($j = 2; $j <= $count; ++$j) {
705
  $u = $hmac->hash($u);
661
  $count = isset($func_args[4]) ? $func_args[4] : 1000;
662
 
663
  // Keylength
664
+ if (isset($func_args[5])) {
665
  $dkLen = $func_args[5];
666
  } else {
667
  $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
696
  include_once 'Crypt/Hash.php';
697
  }
698
  $i = 1;
 
 
 
699
  while (strlen($key) < $dkLen) {
700
+ $hmac = new Crypt_Hash();
701
+ $hmac->setHash($hash);
702
+ $hmac->setKey($password);
703
  $f = $u = $hmac->hash($salt . pack('N', $i++));
704
  for ($j = 2; $j <= $count; ++$j) {
705
  $u = $hmac->hash($u);
phpseclib/Crypt/Hash.php CHANGED
@@ -126,15 +126,6 @@ class Crypt_Hash
126
  */
127
  var $key = false;
128
 
129
- /**
130
- * Computed Key
131
- *
132
- * @see self::_computeKey()
133
- * @var string
134
- * @access private
135
- */
136
- var $computedKey = false;
137
-
138
  /**
139
  * Outer XOR (Internal HMAC)
140
  *
@@ -201,43 +192,6 @@ class Crypt_Hash
201
  function setKey($key = false)
202
  {
203
  $this->key = $key;
204
- $this->_computeKey();
205
- }
206
-
207
- /**
208
- * Pre-compute the key used by the HMAC
209
- *
210
- * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
211
- * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
212
- *
213
- * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
214
- * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
215
- * every call
216
- *
217
- * @access private
218
- */
219
- function _computeKey()
220
- {
221
- if ($this->key === false) {
222
- $this->computedKey = false;
223
- return;
224
- }
225
-
226
- if (strlen($this->key) <= $this->b) {
227
- $this->computedKey = $this->key;
228
- return;
229
- }
230
-
231
- switch ($mode) {
232
- case CRYPT_HASH_MODE_MHASH:
233
- $this->computedKey = mhash($this->hash, $this->key);
234
- break;
235
- case CRYPT_HASH_MODE_HASH:
236
- $this->computedKey = hash($this->hash, $this->key, true);
237
- break;
238
- case CRYPT_HASH_MODE_INTERNAL:
239
- $this->computedKey = call_user_func($this->hash, $this->key);
240
- }
241
  }
242
 
243
  /**
@@ -287,25 +241,6 @@ class Crypt_Hash
287
  $this->l = 64;
288
  }
289
 
290
- switch ($hash) {
291
- case 'md2-96':
292
- case 'md2':
293
- $this->b = 16;
294
- case 'md5-96':
295
- case 'sha1-96':
296
- case 'sha224-96':
297
- case 'sha256-96':
298
- case 'md2':
299
- case 'md5':
300
- case 'sha1':
301
- case 'sha224':
302
- case 'sha256':
303
- $this->b = 64;
304
- break;
305
- default:
306
- $this->b = 128;
307
- }
308
-
309
  switch ($hash) {
310
  case 'md2':
311
  $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
@@ -332,7 +267,6 @@ class Crypt_Hash
332
  default:
333
  $this->hash = MHASH_SHA1;
334
  }
335
- $this->_computeKey();
336
  return;
337
  case CRYPT_HASH_MODE_HASH:
338
  switch ($hash) {
@@ -349,33 +283,35 @@ class Crypt_Hash
349
  default:
350
  $this->hash = 'sha1';
351
  }
352
- $this->_computeKey();
353
  return;
354
  }
355
 
356
  switch ($hash) {
357
  case 'md2':
 
358
  $this->hash = array($this, '_md2');
359
  break;
360
  case 'md5':
 
361
  $this->hash = array($this, '_md5');
362
  break;
363
  case 'sha256':
 
364
  $this->hash = array($this, '_sha256');
365
  break;
366
  case 'sha384':
367
  case 'sha512':
 
368
  $this->hash = array($this, '_sha512');
369
  break;
370
  case 'sha1':
371
  default:
 
372
  $this->hash = array($this, '_sha1');
373
  }
374
 
375
  $this->ipad = str_repeat(chr(0x36), $this->b);
376
  $this->opad = str_repeat(chr(0x5C), $this->b);
377
-
378
- $this->_computeKey();
379
  }
380
 
381
  /**
@@ -392,19 +328,25 @@ class Crypt_Hash
392
  if (!empty($this->key) || is_string($this->key)) {
393
  switch ($mode) {
394
  case CRYPT_HASH_MODE_MHASH:
395
- $output = mhash($this->hash, $text, $this->computedKey);
396
  break;
397
  case CRYPT_HASH_MODE_HASH:
398
- $output = hash_hmac($this->hash, $text, $this->computedKey, true);
399
  break;
400
  case CRYPT_HASH_MODE_INTERNAL:
401
- $key = str_pad($this->computedKey, $this->b, chr(0)); // step 1
402
- $temp = $this->ipad ^ $key; // step 2
403
- $temp .= $text; // step 3
404
- $temp = call_user_func($this->hash, $temp); // step 4
405
- $output = $this->opad ^ $key; // step 5
406
- $output.= $temp; // step 6
407
- $output = call_user_func($this->hash, $output); // step 7
 
 
 
 
 
 
408
  }
409
  } else {
410
  switch ($mode) {
126
  */
127
  var $key = false;
128
 
 
 
 
 
 
 
 
 
 
129
  /**
130
  * Outer XOR (Internal HMAC)
131
  *
192
  function setKey($key = false)
193
  {
194
  $this->key = $key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
196
 
197
  /**
241
  $this->l = 64;
242
  }
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  switch ($hash) {
245
  case 'md2':
246
  $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
267
  default:
268
  $this->hash = MHASH_SHA1;
269
  }
 
270
  return;
271
  case CRYPT_HASH_MODE_HASH:
272
  switch ($hash) {
283
  default:
284
  $this->hash = 'sha1';
285
  }
 
286
  return;
287
  }
288
 
289
  switch ($hash) {
290
  case 'md2':
291
+ $this->b = 16;
292
  $this->hash = array($this, '_md2');
293
  break;
294
  case 'md5':
295
+ $this->b = 64;
296
  $this->hash = array($this, '_md5');
297
  break;
298
  case 'sha256':
299
+ $this->b = 64;
300
  $this->hash = array($this, '_sha256');
301
  break;
302
  case 'sha384':
303
  case 'sha512':
304
+ $this->b = 128;
305
  $this->hash = array($this, '_sha512');
306
  break;
307
  case 'sha1':
308
  default:
309
+ $this->b = 64;
310
  $this->hash = array($this, '_sha1');
311
  }
312
 
313
  $this->ipad = str_repeat(chr(0x36), $this->b);
314
  $this->opad = str_repeat(chr(0x5C), $this->b);
 
 
315
  }
316
 
317
  /**
328
  if (!empty($this->key) || is_string($this->key)) {
329
  switch ($mode) {
330
  case CRYPT_HASH_MODE_MHASH:
331
+ $output = mhash($this->hash, $text, $this->key);
332
  break;
333
  case CRYPT_HASH_MODE_HASH:
334
+ $output = hash_hmac($this->hash, $text, $this->key, true);
335
  break;
336
  case CRYPT_HASH_MODE_INTERNAL:
337
+ /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
338
+ resultant L byte string as the actual key to HMAC."
339
+
340
+ -- http://tools.ietf.org/html/rfc2104#section-2 */
341
+ $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
342
+
343
+ $key = str_pad($key, $this->b, chr(0)); // step 1
344
+ $temp = $this->ipad ^ $key; // step 2
345
+ $temp .= $text; // step 3
346
+ $temp = call_user_func($this->hash, $temp); // step 4
347
+ $output = $this->opad ^ $key; // step 5
348
+ $output.= $temp; // step 6
349
+ $output = call_user_func($this->hash, $output); // step 7
350
  }
351
  } else {
352
  switch ($mode) {
phpseclib/File/ASN1.php CHANGED
@@ -390,9 +390,6 @@ class File_ASN1
390
  $remainingLength = $length;
391
  while ($remainingLength > 0) {
392
  $temp = $this->_decode_ber($content, $start, $content_pos);
393
- if ($temp === false) {
394
- break;
395
- }
396
  $length = $temp['length'];
397
  // end-of-content octets - see paragraph 8.1.5
398
  if (substr($content, $content_pos + $length, 2) == "\0\0") {
@@ -444,9 +441,6 @@ class File_ASN1
444
  $current['content'] = substr($content, $content_pos);
445
  } else {
446
  $temp = $this->_decode_ber($content, $start, $content_pos);
447
- if ($temp === false) {
448
- return false;
449
- }
450
  $length-= (strlen($content) - $content_pos);
451
  $last = count($temp) - 1;
452
  for ($i = 0; $i < $last; $i++) {
@@ -471,9 +465,6 @@ class File_ASN1
471
  $length = 0;
472
  while (substr($content, $content_pos, 2) != "\0\0") {
473
  $temp = $this->_decode_ber($content, $length + $start, $content_pos);
474
- if ($temp === false) {
475
- return false;
476
- }
477
  $content_pos += $temp['length'];
478
  // all subtags should be octet strings
479
  //if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
@@ -506,9 +497,6 @@ class File_ASN1
506
  break 2;
507
  }
508
  $temp = $this->_decode_ber($content, $start + $offset, $content_pos);
509
- if ($temp === false) {
510
- return false;
511
- }
512
  $content_pos += $temp['length'];
513
  $current['content'][] = $temp;
514
  $offset+= $temp['length'];
390
  $remainingLength = $length;
391
  while ($remainingLength > 0) {
392
  $temp = $this->_decode_ber($content, $start, $content_pos);
 
 
 
393
  $length = $temp['length'];
394
  // end-of-content octets - see paragraph 8.1.5
395
  if (substr($content, $content_pos + $length, 2) == "\0\0") {
441
  $current['content'] = substr($content, $content_pos);
442
  } else {
443
  $temp = $this->_decode_ber($content, $start, $content_pos);
 
 
 
444
  $length-= (strlen($content) - $content_pos);
445
  $last = count($temp) - 1;
446
  for ($i = 0; $i < $last; $i++) {
465
  $length = 0;
466
  while (substr($content, $content_pos, 2) != "\0\0") {
467
  $temp = $this->_decode_ber($content, $length + $start, $content_pos);
 
 
 
468
  $content_pos += $temp['length'];
469
  // all subtags should be octet strings
470
  //if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
497
  break 2;
498
  }
499
  $temp = $this->_decode_ber($content, $start + $offset, $content_pos);
 
 
 
500
  $content_pos += $temp['length'];
501
  $current['content'][] = $temp;
502
  $offset+= $temp['length'];
phpseclib/File/X509.php CHANGED
@@ -2122,7 +2122,7 @@ class File_X509
2122
  *
2123
  * If $date isn't defined it is assumed to be the current date.
2124
  *
2125
- * @param \DateTime|int|string $date optional
2126
  * @access public
2127
  */
2128
  function validateDate($date = null)
@@ -2133,7 +2133,7 @@ class File_X509
2133
 
2134
  if (!isset($date)) {
2135
  $date = class_exists('DateTime') ?
2136
- new DateTime(null, new DateTimeZone(@date_default_timezone_get())) :
2137
  time();
2138
  }
2139
 
@@ -2143,18 +2143,12 @@ class File_X509
2143
  $notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
2144
  $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
2145
 
2146
- switch (true) {
2147
- case is_string($date) && class_exists('DateTime'):
2148
- $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
2149
- case is_object($date) && strtolower(get_class($date)) == 'datetime':
2150
- $notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
2151
- $notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
2152
- break;
2153
- case is_string($date):
2154
- $date = @strtotime($date);
2155
- default:
2156
- $notBefore = @strtotime($notBefore);
2157
- $notAfter = @strtotime($notAfter);
2158
  }
2159
 
2160
  switch (true) {
2122
  *
2123
  * If $date isn't defined it is assumed to be the current date.
2124
  *
2125
+ * @param int $date optional
2126
  * @access public
2127
  */
2128
  function validateDate($date = null)
2133
 
2134
  if (!isset($date)) {
2135
  $date = class_exists('DateTime') ?
2136
+ new DateTime($date, new DateTimeZone(@date_default_timezone_get())) :
2137
  time();
2138
  }
2139
 
2143
  $notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
2144
  $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
2145
 
2146
+ if (class_exists('DateTime')) {
2147
+ $notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
2148
+ $notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
2149
+ } else {
2150
+ $notBefore = @strtotime($notBefore);
2151
+ $notAfter = @strtotime($notAfter);
 
 
 
 
 
 
2152
  }
2153
 
2154
  switch (true) {
phpseclib/Math/BigInteger.php CHANGED
@@ -65,6 +65,7 @@
65
  * @author Jim Wigginton <terrafrost@php.net>
66
  * @copyright 2006 Jim Wigginton
67
  * @license http://www.opensource.org/licenses/mit-license.html MIT License
 
68
  */
69
 
70
  /**#@+
65
  * @author Jim Wigginton <terrafrost@php.net>
66
  * @copyright 2006 Jim Wigginton
67
  * @license http://www.opensource.org/licenses/mit-license.html MIT License
68
+ * @link http://pear.php.net/package/Math_BigInteger
69
  */
70
 
71
  /**#@+
phpseclib/Net/SFTP.php CHANGED
@@ -919,17 +919,7 @@ class Net_SFTP extends Net_SSH2
919
  unset($files[$key]);
920
  continue;
921
  }
922
- $is_directory = false;
923
- if ($key != '.' && $key != '..') {
924
- if ($this->use_stat_cache) {
925
- $is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)));
926
- } else {
927
- $stat = $this->lstat($dir . '/' . $key);
928
- $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY;
929
- }
930
- }
931
-
932
- if ($is_directory) {
933
  $depth++;
934
  $files[$key] = $this->rawlist($dir . '/' . $key, true);
935
  $depth--;
919
  unset($files[$key]);
920
  continue;
921
  }
922
+ if ($key != '.' && $key != '..' && is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)))) {
 
 
 
 
 
 
 
 
 
 
923
  $depth++;
924
  $files[$key] = $this->rawlist($dir . '/' . $key, true);
925
  $depth--;
phpseclib/Net/SSH2.php CHANGED
@@ -923,22 +923,6 @@ class Net_SSH2
923
  */
924
  var $binary_packet_buffer = false;
925
 
926
- /**
927
- * Preferred Signature Format
928
- *
929
- * @var string|false
930
- * @access private
931
- */
932
- var $preferred_signature_format = false;
933
-
934
- /**
935
- * Authentication Credentials
936
- *
937
- * @var array
938
- * @access private
939
- */
940
- var $auth = array();
941
-
942
  /**
943
  * Default Constructor.
944
  *
@@ -1175,12 +1159,11 @@ class Net_SSH2
1175
  }
1176
  $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
1177
 
1178
- if ($this->curTimeout) {
1179
- $this->curTimeout-= $elapsed;
1180
- if ($this->curTimeout < 0) {
1181
- $this->is_timeout = true;
1182
- return false;
1183
- }
1184
  }
1185
  }
1186
 
@@ -1229,7 +1212,6 @@ class Net_SSH2
1229
  }
1230
 
1231
  if (feof($this->fsock)) {
1232
- $this->bitmap = 0;
1233
  user_error('Connection closed by server');
1234
  return false;
1235
  }
@@ -1241,7 +1223,7 @@ class Net_SSH2
1241
 
1242
  $this->server_identifier = trim($temp, "\r\n");
1243
  if (strlen($extra)) {
1244
- $this->errors[] = $extra;
1245
  }
1246
 
1247
  if (version_compare($matches[1], '1.99', '<')) {
@@ -1256,7 +1238,6 @@ class Net_SSH2
1256
  if (!$this->send_kex_first) {
1257
  $response = $this->_get_binary_packet();
1258
  if ($response === false) {
1259
- $this->bitmap = 0;
1260
  user_error('Connection closed by server');
1261
  return false;
1262
  }
@@ -1328,8 +1309,6 @@ class Net_SSH2
1328
  );
1329
 
1330
  static $server_host_key_algorithms = array(
1331
- 'rsa-sha2-256', // RFC 8332
1332
- 'rsa-sha2-512', // RFC 8332
1333
  'ssh-rsa', // RECOMMENDED sign Raw RSA Key
1334
  'ssh-dss' // REQUIRED sign Raw DSS Key
1335
  );
@@ -1489,7 +1468,6 @@ class Net_SSH2
1489
 
1490
  $kexinit_payload_server = $this->_get_binary_packet();
1491
  if ($kexinit_payload_server === false) {
1492
- $this->bitmap = 0;
1493
  user_error('Connection closed by server');
1494
  return false;
1495
  }
@@ -1617,7 +1595,6 @@ class Net_SSH2
1617
 
1618
  $response = $this->_get_binary_packet();
1619
  if ($response === false) {
1620
- $this->bitmap = 0;
1621
  user_error('Connection closed by server');
1622
  return false;
1623
  }
@@ -1713,14 +1690,12 @@ class Net_SSH2
1713
  $data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
1714
 
1715
  if (!$this->_send_binary_packet($data)) {
1716
- $this->bitmap = 0;
1717
  user_error('Connection closed by server');
1718
  return false;
1719
  }
1720
 
1721
  $response = $this->_get_binary_packet();
1722
  if ($response === false) {
1723
- $this->bitmap = 0;
1724
  user_error('Connection closed by server');
1725
  return false;
1726
  }
@@ -1801,18 +1776,7 @@ class Net_SSH2
1801
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1802
  }
1803
 
1804
- switch ($server_host_key_algorithm) {
1805
- case 'ssh-dss':
1806
- $expected_key_format = 'ssh-dss';
1807
- break;
1808
- //case 'rsa-sha2-256':
1809
- //case 'rsa-sha2-512':
1810
- //case 'ssh-rsa':
1811
- default:
1812
- $expected_key_format = 'ssh-rsa';
1813
- }
1814
-
1815
- if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) {
1816
  user_error('Server Host Key Algorithm Mismatch');
1817
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1818
  }
@@ -1829,7 +1793,6 @@ class Net_SSH2
1829
  $response = $this->_get_binary_packet();
1830
 
1831
  if ($response === false) {
1832
- $this->bitmap = 0;
1833
  user_error('Connection closed by server');
1834
  return false;
1835
  }
@@ -2004,7 +1967,7 @@ class Net_SSH2
2004
 
2005
  if ($this->encrypt) {
2006
  if ($this->crypto_engine) {
2007
- $this->encrypt->setPreferredEngine($this->crypto_engine);
2008
  }
2009
  $this->encrypt->enableContinuousBuffer();
2010
  $this->encrypt->disablePadding();
@@ -2024,7 +1987,7 @@ class Net_SSH2
2024
 
2025
  if ($this->decrypt) {
2026
  if ($this->crypto_engine) {
2027
- $this->decrypt->setPreferredEngine($this->crypto_engine);
2028
  }
2029
  $this->decrypt->enableContinuousBuffer();
2030
  $this->decrypt->disablePadding();
@@ -2228,7 +2191,6 @@ class Net_SSH2
2228
  function login($username)
2229
  {
2230
  $args = func_get_args();
2231
- $this->auth[] = $args;
2232
  return call_user_func_array(array(&$this, '_login'), $args);
2233
  }
2234
 
@@ -2300,7 +2262,6 @@ class Net_SSH2
2300
  }
2301
  return $this->_login_helper($username, $password);
2302
  }
2303
- $this->bitmap = 0;
2304
  user_error('Connection closed by server');
2305
  return false;
2306
  }
@@ -2357,7 +2318,6 @@ class Net_SSH2
2357
 
2358
  $response = $this->_get_binary_packet();
2359
  if ($response === false) {
2360
- $this->bitmap = 0;
2361
  user_error('Connection closed by server');
2362
  return false;
2363
  }
@@ -2416,7 +2376,6 @@ class Net_SSH2
2416
 
2417
  $response = $this->_get_binary_packet();
2418
  if ($response === false) {
2419
- $this->bitmap = 0;
2420
  user_error('Connection closed by server');
2421
  return false;
2422
  }
@@ -2435,7 +2394,7 @@ class Net_SSH2
2435
  return false;
2436
  }
2437
  extract(unpack('Nlength', $this->_string_shift($response, 4)));
2438
- $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $this->_string_shift($response, $length);
2439
  return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
2440
  case NET_SSH2_MSG_USERAUTH_FAILURE:
2441
  // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
@@ -2517,7 +2476,6 @@ class Net_SSH2
2517
  } else {
2518
  $orig = $response = $this->_get_binary_packet();
2519
  if ($response === false) {
2520
- $this->bitmap = 0;
2521
  user_error('Connection closed by server');
2522
  return false;
2523
  }
@@ -2706,7 +2664,6 @@ class Net_SSH2
2706
 
2707
  $response = $this->_get_binary_packet();
2708
  if ($response === false) {
2709
- $this->bitmap = 0;
2710
  user_error('Connection closed by server');
2711
  return false;
2712
  }
@@ -2738,23 +2695,8 @@ class Net_SSH2
2738
 
2739
  $packet = $part1 . chr(1) . $part2;
2740
  $privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
2741
- switch ($this->signature_format) {
2742
- case 'rsa-sha2-512':
2743
- $hash = 'sha512';
2744
- $type = 'rsa-sha2-512';
2745
- break;
2746
- case 'rsa-sha2-256':
2747
- $hash = 'sha256';
2748
- $type = 'rsa-sha2-256';
2749
- break;
2750
- //case 'ssh-rsa':
2751
- default:
2752
- $hash = 'sha1';
2753
- $type = 'ssh-rsa';
2754
- }
2755
- $privatekey->setHash($hash);
2756
  $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
2757
- $signature = pack('Na*Na*', strlen($type), $type, strlen($signature), $signature);
2758
  $packet.= pack('Na*', strlen($signature), $signature);
2759
 
2760
  if (!$this->_send_binary_packet($packet)) {
@@ -2763,7 +2705,6 @@ class Net_SSH2
2763
 
2764
  $response = $this->_get_binary_packet();
2765
  if ($response === false) {
2766
- $this->bitmap = 0;
2767
  user_error('Connection closed by server');
2768
  return false;
2769
  }
@@ -2890,7 +2831,6 @@ class Net_SSH2
2890
 
2891
  $response = $this->_get_binary_packet();
2892
  if ($response === false) {
2893
- $this->bitmap = 0;
2894
  user_error('Connection closed by server');
2895
  return false;
2896
  }
@@ -3031,7 +2971,6 @@ class Net_SSH2
3031
 
3032
  $response = $this->_get_binary_packet();
3033
  if ($response === false) {
3034
- $this->bitmap = 0;
3035
  user_error('Connection closed by server');
3036
  return false;
3037
  }
@@ -3346,66 +3285,6 @@ class Net_SSH2
3346
  return (bool) ($this->bitmap & NET_SSH2_MASK_LOGIN);
3347
  }
3348
 
3349
- /**
3350
- * Pings a server connection, or tries to reconnect if the connection has gone down
3351
- *
3352
- * Inspired by http://php.net/manual/en/mysqli.ping.php
3353
- *
3354
- * @return bool
3355
- * @access public
3356
- */
3357
- function ping()
3358
- {
3359
- if (!$this->isAuthenticated()) {
3360
- return false;
3361
- }
3362
-
3363
- $this->window_size_server_to_client[NET_SSH2_CHANNEL_KEEP_ALIVE] = $this->window_size;
3364
- $packet_size = 0x4000;
3365
- $packet = pack(
3366
- 'CNa*N3',
3367
- NET_SSH2_MSG_CHANNEL_OPEN,
3368
- strlen('session'),
3369
- 'session',
3370
- NET_SSH2_CHANNEL_KEEP_ALIVE,
3371
- $this->window_size_server_to_client[NET_SSH2_CHANNEL_KEEP_ALIVE],
3372
- $packet_size
3373
- );
3374
-
3375
- if (!@$this->_send_binary_packet($packet)) {
3376
- return $this->_reconnect();
3377
- }
3378
-
3379
- $this->channel_status[NET_SSH2_CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN;
3380
-
3381
- $response = @$this->_get_channel_packet(NET_SSH2_CHANNEL_KEEP_ALIVE);
3382
- if ($response !== false) {
3383
- $this->_close_channel(NET_SSH2_CHANNEL_KEEP_ALIVE);
3384
- return true;
3385
- }
3386
-
3387
- return $this->_reconnect();
3388
- }
3389
-
3390
- /**
3391
- * In situ reconnect method
3392
- *
3393
- * @return boolean
3394
- * @access private
3395
- */
3396
- function _reconnect()
3397
- {
3398
- $this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
3399
- $this->retry_connect = true;
3400
- if (!$this->_connect()) {
3401
- return false;
3402
- }
3403
- foreach ($this->auth as $auth) {
3404
- $result = call_user_func_array(array(&$this, 'parent::login'), $auth);
3405
- }
3406
- return $result;
3407
- }
3408
-
3409
  /**
3410
  * Resets a connection for re-use
3411
  *
@@ -3436,8 +3315,8 @@ class Net_SSH2
3436
  function _get_binary_packet($skip_channel_filter = false)
3437
  {
3438
  if (!is_resource($this->fsock) || feof($this->fsock)) {
3439
- $this->bitmap = 0;
3440
  user_error('Connection closed prematurely');
 
3441
  return false;
3442
  }
3443
 
@@ -3480,8 +3359,8 @@ class Net_SSH2
3480
  while ($remaining_length > 0) {
3481
  $temp = fread($this->fsock, $remaining_length);
3482
  if ($temp === false || feof($this->fsock)) {
3483
- $this->bitmap = 0;
3484
  user_error('Error reading from socket');
 
3485
  return false;
3486
  }
3487
  $buffer.= $temp;
@@ -3499,8 +3378,8 @@ class Net_SSH2
3499
  if ($this->hmac_check !== false) {
3500
  $hmac = fread($this->fsock, $this->hmac_size);
3501
  if ($hmac === false || strlen($hmac) != $this->hmac_size) {
3502
- $this->bitmap = 0;
3503
  user_error('Error reading socket');
 
3504
  return false;
3505
  } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
3506
  user_error('Invalid HMAC');
@@ -3544,7 +3423,7 @@ class Net_SSH2
3544
  return false;
3545
  }
3546
  extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
3547
- $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . $this->_string_shift($payload, $length);
3548
  $this->bitmap = 0;
3549
  return false;
3550
  case NET_SSH2_MSG_IGNORE:
@@ -3556,7 +3435,7 @@ class Net_SSH2
3556
  return false;
3557
  }
3558
  extract(unpack('Nlength', $this->_string_shift($payload, 4)));
3559
- $this->errors[] = 'SSH_MSG_DEBUG: ' . $this->_string_shift($payload, $length);
3560
  $payload = $this->_get_binary_packet($skip_channel_filter);
3561
  break;
3562
  case NET_SSH2_MSG_UNIMPLEMENTED:
@@ -3579,7 +3458,7 @@ class Net_SSH2
3579
  return false;
3580
  }
3581
  extract(unpack('Nlength', $this->_string_shift($payload, 4)));
3582
- $this->banner_message = $this->_string_shift($payload, $length);
3583
  $payload = $this->_get_binary_packet();
3584
  }
3585
 
@@ -3808,7 +3687,6 @@ class Net_SSH2
3808
 
3809
  $response = $this->_get_binary_packet(true);
3810
  if ($response === false) {
3811
- $this->bitmap = 0;
3812
  user_error('Connection closed by server');
3813
  return false;
3814
  }
@@ -3817,6 +3695,10 @@ class Net_SSH2
3817
  if ($client_channel == -1 && $response === true) {
3818
  return true;
3819
  }
 
 
 
 
3820
  if (!strlen($response)) {
3821
  return false;
3822
  }
@@ -4701,8 +4583,6 @@ class Net_SSH2
4701
 
4702
  break;
4703
  case 'ssh-rsa':
4704
- case 'rsa-sha2-256':
4705
- case 'rsa-sha2-512':
4706
  if (strlen($server_public_host_key) < 4) {
4707
  return false;
4708
  }
@@ -4729,18 +4609,6 @@ class Net_SSH2
4729
  }
4730
 
4731
  $rsa = new Crypt_RSA();
4732
- switch ($this->signature_format) {
4733
- case 'rsa-sha2-512':
4734
- $hash = 'sha512';
4735
- break;
4736
- case 'rsa-sha2-256':
4737
- $hash = 'sha256';
4738
- break;
4739
- //case 'ssh-rsa':
4740
- default:
4741
- $hash = 'sha1';
4742
- }
4743
- $rsa->setHash($hash);
4744
  $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
4745
  $rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
4746
  if (!$rsa->verify($this->exchange_hash, $signature)) {
@@ -4769,30 +4637,7 @@ class Net_SSH2
4769
  $s = $s->modPow($e, $n);
4770
  $s = $s->toBytes();
4771
 
4772
- switch ($this->signature_format) {
4773
- case 'rsa-sha2-512':
4774
- $hash = 'sha512';
4775
- break;
4776
- case 'rsa-sha2-256':
4777
- $hash = 'sha256';
4778
- break;
4779
- //case 'ssh-rsa':
4780
- default:
4781
- $hash = 'sha1';
4782
- }
4783
- $hashObj = new Crypt_Hash($hash);
4784
- switch ($this->signature_format) {
4785
- case 'rsa-sha2-512':
4786
- $h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash));
4787
- break;
4788
- case 'rsa-sha2-256':
4789
- $h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash));
4790
- break;
4791
- //case 'ssh-rsa':
4792
- default:
4793
- $hash = 'sha1';
4794
- $h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash));
4795
- }
4796
  $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
4797
 
4798
  if ($s != $h) {
923
  */
924
  var $binary_packet_buffer = false;
925
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
926
  /**
927
  * Default Constructor.
928
  *
1159
  }
1160
  $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
1161
 
1162
+ $this->curTimeout-= $elapsed;
1163
+
1164
+ if ($this->curTimeout <= 0) {
1165
+ $this->is_timeout = true;
1166
+ return false;
 
1167
  }
1168
  }
1169
 
1212
  }
1213
 
1214
  if (feof($this->fsock)) {
 
1215
  user_error('Connection closed by server');
1216
  return false;
1217
  }
1223
 
1224
  $this->server_identifier = trim($temp, "\r\n");
1225
  if (strlen($extra)) {
1226
+ $this->errors[] = utf8_decode($extra);
1227
  }
1228
 
1229
  if (version_compare($matches[1], '1.99', '<')) {
1238
  if (!$this->send_kex_first) {
1239
  $response = $this->_get_binary_packet();
1240
  if ($response === false) {
 
1241
  user_error('Connection closed by server');
1242
  return false;
1243
  }
1309
  );
1310
 
1311
  static $server_host_key_algorithms = array(
 
 
1312
  'ssh-rsa', // RECOMMENDED sign Raw RSA Key
1313
  'ssh-dss' // REQUIRED sign Raw DSS Key
1314
  );
1468
 
1469
  $kexinit_payload_server = $this->_get_binary_packet();
1470
  if ($kexinit_payload_server === false) {
 
1471
  user_error('Connection closed by server');
1472
  return false;
1473
  }
1595
 
1596
  $response = $this->_get_binary_packet();
1597
  if ($response === false) {
 
1598
  user_error('Connection closed by server');
1599
  return false;
1600
  }
1690
  $data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
1691
 
1692
  if (!$this->_send_binary_packet($data)) {
 
1693
  user_error('Connection closed by server');
1694
  return false;
1695
  }
1696
 
1697
  $response = $this->_get_binary_packet();
1698
  if ($response === false) {
 
1699
  user_error('Connection closed by server');
1700
  return false;
1701
  }
1776
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1777
  }
1778
 
1779
+ if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) {
 
 
 
 
 
 
 
 
 
 
 
1780
  user_error('Server Host Key Algorithm Mismatch');
1781
  return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
1782
  }
1793
  $response = $this->_get_binary_packet();
1794
 
1795
  if ($response === false) {
 
1796
  user_error('Connection closed by server');
1797
  return false;
1798
  }
1967
 
1968
  if ($this->encrypt) {
1969
  if ($this->crypto_engine) {
1970
+ $this->encrypt->setEngine($this->crypto_engine);
1971
  }
1972
  $this->encrypt->enableContinuousBuffer();
1973
  $this->encrypt->disablePadding();
1987
 
1988
  if ($this->decrypt) {
1989
  if ($this->crypto_engine) {
1990
+ $this->decrypt->setEngine($this->crypto_engine);
1991
  }
1992
  $this->decrypt->enableContinuousBuffer();
1993
  $this->decrypt->disablePadding();
2191
  function login($username)
2192
  {
2193
  $args = func_get_args();
 
2194
  return call_user_func_array(array(&$this, '_login'), $args);
2195
  }
2196
 
2262
  }
2263
  return $this->_login_helper($username, $password);
2264
  }
 
2265
  user_error('Connection closed by server');
2266
  return false;
2267
  }
2318
 
2319
  $response = $this->_get_binary_packet();
2320
  if ($response === false) {
 
2321
  user_error('Connection closed by server');
2322
  return false;
2323
  }
2376
 
2377
  $response = $this->_get_binary_packet();
2378
  if ($response === false) {
 
2379
  user_error('Connection closed by server');
2380
  return false;
2381
  }
2394
  return false;
2395
  }
2396
  extract(unpack('Nlength', $this->_string_shift($response, 4)));
2397
+ $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . utf8_decode($this->_string_shift($response, $length));
2398
  return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
2399
  case NET_SSH2_MSG_USERAUTH_FAILURE:
2400
  // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
2476
  } else {
2477
  $orig = $response = $this->_get_binary_packet();
2478
  if ($response === false) {
 
2479
  user_error('Connection closed by server');
2480
  return false;
2481
  }
2664
 
2665
  $response = $this->_get_binary_packet();
2666
  if ($response === false) {
 
2667
  user_error('Connection closed by server');
2668
  return false;
2669
  }
2695
 
2696
  $packet = $part1 . chr(1) . $part2;
2697
  $privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2698
  $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
2699
+ $signature = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($signature), $signature);
2700
  $packet.= pack('Na*', strlen($signature), $signature);
2701
 
2702
  if (!$this->_send_binary_packet($packet)) {
2705
 
2706
  $response = $this->_get_binary_packet();
2707
  if ($response === false) {
 
2708
  user_error('Connection closed by server');
2709
  return false;
2710
  }
2831
 
2832
  $response = $this->_get_binary_packet();
2833
  if ($response === false) {
 
2834
  user_error('Connection closed by server');
2835
  return false;
2836
  }
2971
 
2972
  $response = $this->_get_binary_packet();
2973
  if ($response === false) {
 
2974
  user_error('Connection closed by server');
2975
  return false;
2976
  }
3285
  return (bool) ($this->bitmap & NET_SSH2_MASK_LOGIN);
3286
  }
3287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3288
  /**
3289
  * Resets a connection for re-use
3290
  *
3315
  function _get_binary_packet($skip_channel_filter = false)
3316
  {
3317
  if (!is_resource($this->fsock) || feof($this->fsock)) {
 
3318
  user_error('Connection closed prematurely');
3319
+ $this->bitmap = 0;
3320
  return false;
3321
  }
3322
 
3359
  while ($remaining_length > 0) {
3360
  $temp = fread($this->fsock, $remaining_length);
3361
  if ($temp === false || feof($this->fsock)) {
 
3362
  user_error('Error reading from socket');
3363
+ $this->bitmap = 0;
3364
  return false;
3365
  }
3366
  $buffer.= $temp;
3378
  if ($this->hmac_check !== false) {
3379
  $hmac = fread($this->fsock, $this->hmac_size);
3380
  if ($hmac === false || strlen($hmac) != $this->hmac_size) {
 
3381
  user_error('Error reading socket');
3382
+ $this->bitmap = 0;
3383
  return false;
3384
  } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
3385
  user_error('Invalid HMAC');
3423
  return false;
3424
  }
3425
  extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
3426
+ $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode($this->_string_shift($payload, $length));
3427
  $this->bitmap = 0;
3428
  return false;
3429
  case NET_SSH2_MSG_IGNORE:
3435
  return false;
3436
  }
3437
  extract(unpack('Nlength', $this->_string_shift($payload, 4)));
3438
+ $this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode($this->_string_shift($payload, $length));
3439
  $payload = $this->_get_binary_packet($skip_channel_filter);
3440
  break;
3441
  case NET_SSH2_MSG_UNIMPLEMENTED:
3458
  return false;
3459
  }
3460
  extract(unpack('Nlength', $this->_string_shift($payload, 4)));
3461
+ $this->banner_message = utf8_decode($this->_string_shift($payload, $length));
3462
  $payload = $this->_get_binary_packet();
3463
  }
3464
 
3687
 
3688
  $response = $this->_get_binary_packet(true);
3689
  if ($response === false) {
 
3690
  user_error('Connection closed by server');
3691
  return false;
3692
  }
3695
  if ($client_channel == -1 && $response === true) {
3696
  return true;
3697
  }
3698
+ if (!strlen($response)) {
3699
+ return '';
3700
+ }
3701
+
3702
  if (!strlen($response)) {
3703
  return false;
3704
  }
4583
 
4584
  break;
4585
  case 'ssh-rsa':
 
 
4586
  if (strlen($server_public_host_key) < 4) {
4587
  return false;
4588
  }
4609
  }
4610
 
4611
  $rsa = new Crypt_RSA();
 
 
 
 
 
 
 
 
 
 
 
 
4612
  $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
4613
  $rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
4614
  if (!$rsa->verify($this->exchange_hash, $signature)) {
4637
  $s = $s->modPow($e, $n);
4638
  $s = $s->toBytes();
4639
 
4640
+ $h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->exchange_hash));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4641
  $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
4642
 
4643
  if ($s != $h) {
phpseclib/System/SSH/Agent.php CHANGED
@@ -202,18 +202,6 @@ class System_SSH_Agent_Identity
202
  {
203
  }
204
 
205
- /**
206
- * Set Hash
207
- *
208
- * ssh-agent doesn't support using hashes for RSA other than SHA1
209
- *
210
- * @param string $hash
211
- * @access public
212
- */
213
- function setHash($hash)
214
- {
215
- }
216
-
217
  /**
218
  * Create a signature
219
  *
@@ -342,14 +330,12 @@ class System_SSH_Agent
342
  $packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
343
  if (strlen($packet) != fputs($this->fsock, $packet)) {
344
  user_error('Connection closed while requesting identities');
345
- return array();
346
  }
347
 
348
  $length = current(unpack('N', fread($this->fsock, 4)));
349
  $type = ord(fread($this->fsock, 1));
350
  if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
351
  user_error('Unable to request identities');
352
- return array();
353
  }
354
 
355
  $identities = array();
202
  {
203
  }
204
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  /**
206
  * Create a signature
207
  *
330
  $packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
331
  if (strlen($packet) != fputs($this->fsock, $packet)) {
332
  user_error('Connection closed while requesting identities');
 
333
  }
334
 
335
  $length = current(unpack('N', fread($this->fsock, 4)));
336
  $type = ord(fread($this->fsock, 1));
337
  if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
338
  user_error('Unable to request identities');
 
339
  }
340
 
341
  $identities = array();
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://sourceforge.net/donate/index.php?group_id=198487
4
  Tags: ssh, sftp
5
  Requires at least: 3.1
6
  Tested up to: 5.0
7
- Stable tag: 0.7.6
8
 
9
  "SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
10
 
@@ -41,6 +41,14 @@ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPres
41
 
42
  == Changelog ==
43
 
 
 
 
 
 
 
 
 
44
  * TWEAK: Clarify the installation instructions
45
  * TWEAK: Add function visibility markers throughout WP_Filesystem_SSH2
46
 
@@ -100,4 +108,4 @@ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPres
100
  * Initial Release
101
 
102
  == Upgrade Notice ==
103
- * 0.7.6: Documentation improvement and small code tidy
4
  Tags: ssh, sftp
5
  Requires at least: 3.1
6
  Tested up to: 5.0
7
+ Stable tag: 0.8.0
8
 
9
  "SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
10
 
41
 
42
  == Changelog ==
43
 
44
+ = 0.8.0 - 2018/Dec/14 =
45
+
46
+ * TWEAK: Replaced the deprecated 'var' visibility indicator
47
+ * TWEAK: Add various sanity checks to return error codes instead of causing fatal errors if another component calls the WP_Filesystem API incorrectly
48
+ * TWEAK: Add an extra sanity check that should prevent a fatal error if a component directly requests the 'direct' filesystem method but WP won't let it have it
49
+
50
+ = 0.7.6 - 2018/Nov/26 =
51
+
52
  * TWEAK: Clarify the installation instructions
53
  * TWEAK: Add function visibility markers throughout WP_Filesystem_SSH2
54
 
108
  * Initial Release
109
 
110
  == Upgrade Notice ==
111
+ * 0.8.0 : Better handle calls from other plugins (etc.) that don't check for error conditions
sftp.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: SSH SFTP Updater Support
4
  Plugin URI: https://wordpress.org/plugins/ssh-sftp-updater-support/
5
  Description: Update your WordPress blog / plugins via SFTP without libssh2
6
- Version: 0.7.6
7
  Author: TerraFrost, David Anderson + Team Updraft
8
  Author URI: https://updraftplus.com/
9
  */
@@ -12,7 +12,7 @@ if (!defined('ABSPATH')) die('No direct access allowed');
12
 
13
  define('SSH_SFTP_UPDATER_SUPPORT_MAIN_PATH', plugin_dir_path(__FILE__));
14
  define('SSH_SFTP_UPDATER_SUPPORT_BASENAME', plugin_basename(__FILE__));
15
- define('SSH_SFTP_UPDATER_SUPPORT_VERSION', '0.7.6');
16
  define('SSH_SFTP_UPDATER_SUPPORT_URL', plugin_dir_url(__FILE__));
17
  // see http://adambrown.info/p/wp_hooks/hook/<filter name>
18
  add_filter('filesystem_method', 'phpseclib_filesystem_method', 10, 2); // since 2.6 - WordPress will ignore the ssh option if the php ssh extension is not loaded
@@ -57,7 +57,7 @@ function phpseclib_request_filesystem_credentials($value, $form_post, $type = ''
57
  $type = get_filesystem_method(array(), $context, $allow_relaxed_file_ownership);
58
 
59
  if ( 'direct' == $type )
60
- return true;
61
 
62
  if ( is_null( $extra_fields ) )
63
  $extra_fields = array( 'version', 'locale' );
3
  Plugin Name: SSH SFTP Updater Support
4
  Plugin URI: https://wordpress.org/plugins/ssh-sftp-updater-support/
5
  Description: Update your WordPress blog / plugins via SFTP without libssh2
6
+ Version: 0.8.0
7
  Author: TerraFrost, David Anderson + Team Updraft
8
  Author URI: https://updraftplus.com/
9
  */
12
 
13
  define('SSH_SFTP_UPDATER_SUPPORT_MAIN_PATH', plugin_dir_path(__FILE__));
14
  define('SSH_SFTP_UPDATER_SUPPORT_BASENAME', plugin_basename(__FILE__));
15
+ define('SSH_SFTP_UPDATER_SUPPORT_VERSION', '0.8.0');
16
  define('SSH_SFTP_UPDATER_SUPPORT_URL', plugin_dir_url(__FILE__));
17
  // see http://adambrown.info/p/wp_hooks/hook/<filter name>
18
  add_filter('filesystem_method', 'phpseclib_filesystem_method', 10, 2); // since 2.6 - WordPress will ignore the ssh option if the php ssh extension is not loaded
57
  $type = get_filesystem_method(array(), $context, $allow_relaxed_file_ownership);
58
 
59
  if ( 'direct' == $type )
60
+ return $value;
61
 
62
  if ( is_null( $extra_fields ) )
63
  $extra_fields = array( 'version', 'locale' );