SSH SFTP Updater Support - Version 0.7.6

Version Description

Download this release

Release Info

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

Code changes from version 0.7.5 to 0.7.6

class-wp-filesystem-ssh2.php CHANGED
@@ -73,7 +73,7 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
73
  }
74
  }
75
 
76
- function connect() {
77
  $this->link = new Net_SFTP($this->options['hostname'], $this->options['port']);
78
 
79
  if ( !$this->keys ) {
@@ -101,7 +101,7 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
101
  return true;
102
  }
103
 
104
- 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'));
@@ -111,7 +111,7 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
111
  return false;
112
  }
113
 
114
- function run_command( $command, $returnbool = false) {
115
 
116
  if ( ! $this->link )
117
  return false;
@@ -124,11 +124,11 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
124
  return $data;
125
  }
126
 
127
- function get_contents($file, $type = '', $resumepos = 0 ) {
128
  return $this->link->get($file);
129
  }
130
 
131
- 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)
@@ -136,7 +136,7 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
136
  return $newLines;
137
  }
138
 
139
- function put_contents($file, $contents, $mode = false ) {
140
  $ret = $this->link->put($file, $contents);
141
 
142
  $this->chmod($file, $mode);
@@ -144,19 +144,19 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
144
  return false !== $ret;
145
  }
146
 
147
- function cwd() {
148
  $cwd = $this->run_command('pwd');
149
  if ( $cwd )
150
  $cwd = trailingslashit($cwd);
151
  return $cwd;
152
  }
153
 
154
- function chdir($dir) {
155
  $this->list->chdir($dir);
156
  return $this->run_command('cd ' . $dir, true);
157
  }
158
 
159
- function chgrp($file, $group, $recursive = false ) {
160
  if ( ! $this->exists($file) )
161
  return false;
162
  if ( ! $recursive || ! $this->is_dir($file) )
@@ -164,11 +164,11 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
164
  return $this->run_command(sprintf('chgrp -R %o %s', $mode, escapeshellarg($file)), true);
165
  }
166
 
167
- function chmod($file, $mode = false, $recursive = false) {
168
  return $mode === false ? false : $this->link->chmod($mode, $file, $recursive);
169
  }
170
 
171
- function chown($file, $owner, $recursive = false ) {
172
  if ( ! $this->exists($file) )
173
  return false;
174
  if ( ! $recursive || ! $this->is_dir($file) )
@@ -176,7 +176,7 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
176
  return $this->run_command(sprintf('chown -R %o %s', $mode, escapeshellarg($file)), true);
177
  }
178
 
179
- function owner($file, $owneruid = false) {
180
  if ($owneruid === false) {
181
  $result = $this->link->stat($file);
182
  $owneruid = $result['uid'];
@@ -190,13 +190,13 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
190
  return $ownerarray['name'];
191
  }
192
 
193
- function getchmod($file) {
194
  $result = $this->link->stat($file);
195
 
196
  return substr(decoct($result['permissions']),3);
197
  }
198
 
199
- function group($file, $gid = false) {
200
  if ($gid === false) {
201
  $result = $this->link->stat($file);
202
  $gid = $result['gid'];
@@ -210,7 +210,7 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
210
  return $grouparray['name'];
211
  }
212
 
213
- function copy($source, $destination, $overwrite = false, $mode = false) {
214
  if ( ! $overwrite && $this->exists($destination) )
215
  return false;
216
  $content = $this->get_contents($source);
@@ -219,11 +219,11 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
219
  return $this->put_contents($destination, $content, $mode);
220
  }
221
 
222
- function move($source, $destination, $overwrite = false) {
223
  return $this->link->rename($source, $destination);
224
  }
225
 
226
- function delete($file, $recursive = false, $type = false) {
227
  if ( 'f' == $type || $this->is_file($file) )
228
  return $this->link->delete($file);
229
  if ( ! $recursive )
@@ -231,52 +231,52 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
231
  return $this->link->delete($file, $recursive);
232
  }
233
 
234
- function exists($file) {
235
  return $this->link->stat($file) !== false;
236
  }
237
 
238
- function is_file($file) {
239
  $result = $this->link->stat($file);
240
  return $result['type'] == NET_SFTP_TYPE_REGULAR;
241
  }
242
 
243
- function is_dir($path) {
244
  $result = $this->link->stat($path);
245
  return $result['type'] == NET_SFTP_TYPE_DIRECTORY;
246
  }
247
 
248
- function is_readable($file) {
249
  return true;
250
 
251
  return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
252
  }
253
 
254
- function is_writable($file) {
255
  return true;
256
 
257
  return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
258
  }
259
 
260
- function atime($file) {
261
  $result = $this->link->stat($file);
262
  return $result['atime'];
263
  }
264
 
265
- function mtime($file) {
266
  $result = $this->link->stat($file);
267
  return $result['mtime'];
268
  }
269
 
270
- function size($file) {
271
  $result = $this->link->stat($file);
272
  return $result['size'];
273
  }
274
 
275
- function touch($file, $time = 0, $atime = 0) {
276
  //Not implmented.
277
  }
278
 
279
- function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
280
  $path = untrailingslashit($path);
281
  if ( ! $chmod )
282
  $chmod = FS_CHMOD_DIR;
@@ -291,11 +291,11 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
291
  return true;
292
  }
293
 
294
- function rmdir($path, $recursive = false) {
295
  return $this->delete($path, $recursive);
296
  }
297
 
298
- function dirlist($path, $include_hidden = true, $recursive = false) {
299
  if ( $this->is_file($path) ) {
300
  $limit_file = basename($path);
301
  $path = dirname($path);
73
  }
74
  }
75
 
76
+ public function connect() {
77
  $this->link = new Net_SFTP($this->options['hostname'], $this->options['port']);
78
 
79
  if ( !$this->keys ) {
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'));
111
  return false;
112
  }
113
 
114
+ public function run_command( $command, $returnbool = false) {
115
 
116
  if ( ! $this->link )
117
  return false;
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)
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);
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) )
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) )
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'];
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'];
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);
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 )
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;
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);
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])) {
665
  $dkLen = $func_args[5];
666
  } else {
667
  $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
@@ -696,10 +696,10 @@ class Crypt_Base
696
  include_once 'Crypt/Hash.php';
697
  }
698
  $i = 1;
 
 
 
699
  while (strlen($key) < $dkLen) {
700
- $hmac = new Crypt_Hash();
701
- $hmac->setHash($hash);
702
- $hmac->setKey($password);
703
  $f = $u = $hmac->hash($salt . pack('N', $i++));
704
  for ($j = 2; $j <= $count; ++$j) {
705
  $u = $hmac->hash($u);
661
  $count = isset($func_args[4]) ? $func_args[4] : 1000;
662
 
663
  // Keylength
664
+ if (isset($func_args[5]) && $func_args[5] > 0) {
665
  $dkLen = $func_args[5];
666
  } else {
667
  $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
696
  include_once 'Crypt/Hash.php';
697
  }
698
  $i = 1;
699
+ $hmac = new Crypt_Hash();
700
+ $hmac->setHash($hash);
701
+ $hmac->setKey($password);
702
  while (strlen($key) < $dkLen) {
 
 
 
703
  $f = $u = $hmac->hash($salt . pack('N', $i++));
704
  for ($j = 2; $j <= $count; ++$j) {
705
  $u = $hmac->hash($u);
phpseclib/Crypt/Hash.php CHANGED
@@ -126,6 +126,15 @@ class Crypt_Hash
126
  */
127
  var $key = false;
128
 
 
 
 
 
 
 
 
 
 
129
  /**
130
  * Outer XOR (Internal HMAC)
131
  *
@@ -192,6 +201,43 @@ class Crypt_Hash
192
  function setKey($key = false)
193
  {
194
  $this->key = $key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
196
 
197
  /**
@@ -241,6 +287,25 @@ class Crypt_Hash
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,6 +332,7 @@ class Crypt_Hash
267
  default:
268
  $this->hash = MHASH_SHA1;
269
  }
 
270
  return;
271
  case CRYPT_HASH_MODE_HASH:
272
  switch ($hash) {
@@ -283,35 +349,33 @@ class Crypt_Hash
283
  default:
284
  $this->hash = 'sha1';
285
  }
 
286
  return;
287
  }
288
 
289
  switch ($hash) {
290
  case 'md2':
291
- $this->b = 16;
292
  $this->hash = array($this, '_md2');
293
  break;
294
  case 'md5':
295
- $this->b = 64;
296
  $this->hash = array($this, '_md5');
297
  break;
298
  case 'sha256':
299
- $this->b = 64;
300
  $this->hash = array($this, '_sha256');
301
  break;
302
  case 'sha384':
303
  case 'sha512':
304
- $this->b = 128;
305
  $this->hash = array($this, '_sha512');
306
  break;
307
  case 'sha1':
308
  default:
309
- $this->b = 64;
310
  $this->hash = array($this, '_sha1');
311
  }
312
 
313
  $this->ipad = str_repeat(chr(0x36), $this->b);
314
  $this->opad = str_repeat(chr(0x5C), $this->b);
 
 
315
  }
316
 
317
  /**
@@ -328,25 +392,19 @@ class Crypt_Hash
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) {
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
  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
  $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
  default:
333
  $this->hash = MHASH_SHA1;
334
  }
335
+ $this->_computeKey();
336
  return;
337
  case CRYPT_HASH_MODE_HASH:
338
  switch ($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
  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) {
phpseclib/File/ASN1.php CHANGED
@@ -390,6 +390,9 @@ class File_ASN1
390
  $remainingLength = $length;
391
  while ($remainingLength > 0) {
392
  $temp = $this->_decode_ber($content, $start, $content_pos);
 
 
 
393
  $length = $temp['length'];
394
  // end-of-content octets - see paragraph 8.1.5
395
  if (substr($content, $content_pos + $length, 2) == "\0\0") {
@@ -441,6 +444,9 @@ class File_ASN1
441
  $current['content'] = substr($content, $content_pos);
442
  } else {
443
  $temp = $this->_decode_ber($content, $start, $content_pos);
 
 
 
444
  $length-= (strlen($content) - $content_pos);
445
  $last = count($temp) - 1;
446
  for ($i = 0; $i < $last; $i++) {
@@ -465,6 +471,9 @@ class File_ASN1
465
  $length = 0;
466
  while (substr($content, $content_pos, 2) != "\0\0") {
467
  $temp = $this->_decode_ber($content, $length + $start, $content_pos);
 
 
 
468
  $content_pos += $temp['length'];
469
  // all subtags should be octet strings
470
  //if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
@@ -497,6 +506,9 @@ class File_ASN1
497
  break 2;
498
  }
499
  $temp = $this->_decode_ber($content, $start + $offset, $content_pos);
 
 
 
500
  $content_pos += $temp['length'];
501
  $current['content'][] = $temp;
502
  $offset+= $temp['length'];
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
  $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
  $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
  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'];
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 int $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($date, new DateTimeZone(@date_default_timezone_get())) :
2137
  time();
2138
  }
2139
 
@@ -2143,12 +2143,18 @@ class File_X509
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) {
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
 
2134
  if (!isset($date)) {
2135
  $date = class_exists('DateTime') ?
2136
+ new DateTime(null, 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
+ 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) {
phpseclib/Math/BigInteger.php CHANGED
@@ -65,7 +65,6 @@
65
  * @author Jim Wigginton <terrafrost@php.net>
66
  * @copyright 2006 Jim Wigginton
67
  * @license http://www.opensource.org/licenses/mit-license.html MIT License
68
- * @link http://pear.php.net/package/Math_BigInteger
69
  */
70
 
71
  /**#@+
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
  /**#@+
phpseclib/Net/SFTP.php CHANGED
@@ -919,7 +919,17 @@ class Net_SFTP extends Net_SSH2
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--;
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--;
phpseclib/Net/SSH2.php CHANGED
@@ -923,6 +923,22 @@ class Net_SSH2
923
  */
924
  var $binary_packet_buffer = false;
925
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
926
  /**
927
  * Default Constructor.
928
  *
@@ -1159,11 +1175,12 @@ class Net_SSH2
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,6 +1229,7 @@ class Net_SSH2
1212
  }
1213
 
1214
  if (feof($this->fsock)) {
 
1215
  user_error('Connection closed by server');
1216
  return false;
1217
  }
@@ -1223,7 +1241,7 @@ class Net_SSH2
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,6 +1256,7 @@ class Net_SSH2
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,6 +1328,8 @@ class Net_SSH2
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,6 +1489,7 @@ class Net_SSH2
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,6 +1617,7 @@ class Net_SSH2
1595
 
1596
  $response = $this->_get_binary_packet();
1597
  if ($response === false) {
 
1598
  user_error('Connection closed by server');
1599
  return false;
1600
  }
@@ -1690,12 +1713,14 @@ class Net_SSH2
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,7 +1801,18 @@ class Net_SSH2
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,6 +1829,7 @@ class Net_SSH2
1793
  $response = $this->_get_binary_packet();
1794
 
1795
  if ($response === false) {
 
1796
  user_error('Connection closed by server');
1797
  return false;
1798
  }
@@ -1967,7 +2004,7 @@ class Net_SSH2
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,7 +2024,7 @@ class Net_SSH2
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,6 +2228,7 @@ class Net_SSH2
2191
  function login($username)
2192
  {
2193
  $args = func_get_args();
 
2194
  return call_user_func_array(array(&$this, '_login'), $args);
2195
  }
2196
 
@@ -2262,6 +2300,7 @@ class Net_SSH2
2262
  }
2263
  return $this->_login_helper($username, $password);
2264
  }
 
2265
  user_error('Connection closed by server');
2266
  return false;
2267
  }
@@ -2318,6 +2357,7 @@ class Net_SSH2
2318
 
2319
  $response = $this->_get_binary_packet();
2320
  if ($response === false) {
 
2321
  user_error('Connection closed by server');
2322
  return false;
2323
  }
@@ -2376,6 +2416,7 @@ class Net_SSH2
2376
 
2377
  $response = $this->_get_binary_packet();
2378
  if ($response === false) {
 
2379
  user_error('Connection closed by server');
2380
  return false;
2381
  }
@@ -2394,7 +2435,7 @@ class Net_SSH2
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,6 +2517,7 @@ class Net_SSH2
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,6 +2706,7 @@ class Net_SSH2
2664
 
2665
  $response = $this->_get_binary_packet();
2666
  if ($response === false) {
 
2667
  user_error('Connection closed by server');
2668
  return false;
2669
  }
@@ -2695,8 +2738,23 @@ class Net_SSH2
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,6 +2763,7 @@ class Net_SSH2
2705
 
2706
  $response = $this->_get_binary_packet();
2707
  if ($response === false) {
 
2708
  user_error('Connection closed by server');
2709
  return false;
2710
  }
@@ -2831,6 +2890,7 @@ class Net_SSH2
2831
 
2832
  $response = $this->_get_binary_packet();
2833
  if ($response === false) {
 
2834
  user_error('Connection closed by server');
2835
  return false;
2836
  }
@@ -2971,6 +3031,7 @@ class Net_SSH2
2971
 
2972
  $response = $this->_get_binary_packet();
2973
  if ($response === false) {
 
2974
  user_error('Connection closed by server');
2975
  return false;
2976
  }
@@ -3285,6 +3346,66 @@ class Net_SSH2
3285
  return (bool) ($this->bitmap & NET_SSH2_MASK_LOGIN);
3286
  }
3287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3288
  /**
3289
  * Resets a connection for re-use
3290
  *
@@ -3315,8 +3436,8 @@ class Net_SSH2
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,8 +3480,8 @@ class Net_SSH2
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,8 +3499,8 @@ class Net_SSH2
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,7 +3544,7 @@ class Net_SSH2
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,7 +3556,7 @@ class Net_SSH2
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,7 +3579,7 @@ class Net_SSH2
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,6 +3808,7 @@ class Net_SSH2
3687
 
3688
  $response = $this->_get_binary_packet(true);
3689
  if ($response === false) {
 
3690
  user_error('Connection closed by server');
3691
  return false;
3692
  }
@@ -3695,10 +3817,6 @@ class Net_SSH2
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,6 +4701,8 @@ class Net_SSH2
4583
 
4584
  break;
4585
  case 'ssh-rsa':
 
 
4586
  if (strlen($server_public_host_key) < 4) {
4587
  return false;
4588
  }
@@ -4609,6 +4729,18 @@ class Net_SSH2
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,7 +4769,30 @@ class Net_SSH2
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) {
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
  }
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
  }
1230
 
1231
  if (feof($this->fsock)) {
1232
+ $this->bitmap = 0;
1233
  user_error('Connection closed by server');
1234
  return false;
1235
  }
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
  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
  );
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
 
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
 
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
  $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
  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
  $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
 
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
 
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
  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
  }
2301
  return $this->_login_helper($username, $password);
2302
  }
2303
+ $this->bitmap = 0;
2304
  user_error('Connection closed by server');
2305
  return false;
2306
  }
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
 
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
  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
  } 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
 
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
 
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
 
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
 
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
 
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
  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
  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
  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
  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
  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
  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
  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
 
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
  if ($client_channel == -1 && $response === true) {
3818
  return true;
3819
  }
 
 
 
 
3820
  if (!strlen($response)) {
3821
  return false;
3822
  }
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
  }
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
  $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) {
phpseclib/System/SSH/Agent.php CHANGED
@@ -202,6 +202,18 @@ class System_SSH_Agent_Identity
202
  {
203
  }
204
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  /**
206
  * Create a signature
207
  *
@@ -330,12 +342,14 @@ class System_SSH_Agent
330
  $packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
331
  if (strlen($packet) != fputs($this->fsock, $packet)) {
332
  user_error('Connection closed while requesting identities');
 
333
  }
334
 
335
  $length = current(unpack('N', fread($this->fsock, 4)));
336
  $type = ord(fread($this->fsock, 1));
337
  if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
338
  user_error('Unable to request identities');
 
339
  }
340
 
341
  $identities = array();
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
  $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();
readme.txt CHANGED
@@ -4,13 +4,19 @@ 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.5
8
 
9
  "SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
10
 
11
  == Description ==
12
 
13
- Keeping your Wordpress install up-to-date and installing plugins in a hassle-free manner is not so easy if your server uses SFTP. "SSH SFTP Updater Support" for Wordpress uses phpseclib to remedy this deficiency.
 
 
 
 
 
 
14
 
15
  This plugin is offered and maintained as a free service to the WP community. You might also be interested in enhancing your WordPress site with our other top plugins, below.
16
 
@@ -24,10 +30,20 @@ This plugin is offered and maintained as a free service to the WP community. You
24
  == Installation ==
25
 
26
  1. Upload the files to the `/wp-content/plugins/ssh-sftp-updater-support` directory
 
27
  2. Activate the plugin through the 'Plugins' menu in WordPress
28
 
 
 
 
 
 
 
29
  == Changelog ==
30
 
 
 
 
31
  = 0.7.5 - 2018/Oct/13 =
32
 
33
  * TWEAK: Replace use of the submit_button() function (one user was seeing a fatal error related to it)
@@ -84,4 +100,4 @@ This plugin is offered and maintained as a free service to the WP community. You
84
  * Initial Release
85
 
86
  == Upgrade Notice ==
87
- * 0.7.5: Replace use of the submit_button() function (one user was seeing a fatal error related to it)
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
 
11
  == Description ==
12
 
13
+ Keeping your Wordpress install up-to-date and installing plugins in a hassle-free manner is not so easy if your server uses SFTP. "SSH SFTP Updater Support" for WordPress uses phpseclib to remedy this deficiency.
14
+
15
+ To use it, after installing and activating the plugins, add the necessary constants early in the code in your wp-config.php:
16
+
17
+ a) `define('FS_METHOD', 'ssh2');`
18
+
19
+ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants">detailed in the official WP codex</a>
20
 
21
  This plugin is offered and maintained as a free service to the WP community. You might also be interested in enhancing your WordPress site with our other top plugins, below.
22
 
30
  == Installation ==
31
 
32
  1. Upload the files to the `/wp-content/plugins/ssh-sftp-updater-support` directory
33
+
34
  2. Activate the plugin through the 'Plugins' menu in WordPress
35
 
36
+ 3. Add the necessary constants early in the code in your wp-config.php:
37
+
38
+ a) `define('FS_METHOD', 'ssh2');`
39
+
40
+ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants">detailed in the official WP codex</a>
41
+
42
  == Changelog ==
43
 
44
+ * TWEAK: Clarify the installation instructions
45
+ * TWEAK: Add function visibility markers throughout WP_Filesystem_SSH2
46
+
47
  = 0.7.5 - 2018/Oct/13 =
48
 
49
  * TWEAK: Replace use of the submit_button() function (one user was seeing a fatal error related to it)
100
  * Initial Release
101
 
102
  == Upgrade Notice ==
103
+ * 0.7.6: Documentation improvement and small code tidy
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.5
7
  Author: TerraFrost, David Anderson + Team Updraft
8
  Author URI: https://updraftplus.com/
9
  */
@@ -12,21 +12,22 @@ 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.5');
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
19
  add_filter('request_filesystem_credentials', 'phpseclib_request_filesystem_credentials', 10, 1024); // since 2.5 - Alter some strings and don't ask for the public key
20
  add_filter('fs_ftp_connection_types', 'phpseclib_fs_ftp_connection_types'); // since 2.9 - Add the SSH2 option to the connection options
21
  add_filter('filesystem_method_file', 'phpseclib_filesystem_method_file', 10, 2); // since 2.6 - Direct WordPress to use our ssh2 class
22
- if (version_compare(get_bloginfo('version'), '4.2.0') >= 0) // disable the modal dialog on WordPress >= 4.2
23
- add_action('admin_head-plugins.php', 'phpseclib_disable_update_link_onclick');
 
24
 
25
  function phpseclib_disable_update_link_onclick() {
26
  ?>
27
- <script type="text/javascript">
28
- jQuery(function($){
29
- jQuery(".plugin-update-tr").off("click", ".update-link");
30
  });
31
  </script>
32
  <?php
@@ -38,8 +39,11 @@ function phpseclib_filesystem_method_file($path, $method) {
38
  $path;
39
  }
40
 
 
 
 
41
  function phpseclib_filesystem_method($method, $args) {
42
- return ( isset($args['connection_type']) && 'ssh' == $args['connection_type'] ) ? 'ssh2' : $method;
43
  }
44
 
45
  function phpseclib_fs_ftp_connection_types($types) {
@@ -275,6 +279,9 @@ class SSH_SFTP_Updater_Support {
275
 
276
  protected static $_notices_instance = null;
277
 
 
 
 
278
  public function __construct() {
279
  add_action('plugins_loaded', array($this, 'plugins_loaded'), 1);
280
  add_action('admin_init', array($this, 'admin_init'));
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
 
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
19
  add_filter('request_filesystem_credentials', 'phpseclib_request_filesystem_credentials', 10, 1024); // since 2.5 - Alter some strings and don't ask for the public key
20
  add_filter('fs_ftp_connection_types', 'phpseclib_fs_ftp_connection_types'); // since 2.9 - Add the SSH2 option to the connection options
21
  add_filter('filesystem_method_file', 'phpseclib_filesystem_method_file', 10, 2); // since 2.6 - Direct WordPress to use our ssh2 class
22
+
23
+ // disable the modal dialog on WordPress >= 4.2
24
+ if (version_compare(get_bloginfo('version'), '4.2.0', '>=')) add_action('admin_head-plugins.php', 'phpseclib_disable_update_link_onclick');
25
 
26
  function phpseclib_disable_update_link_onclick() {
27
  ?>
28
+ <script>
29
+ jQuery(function($) {
30
+ $(".plugin-update-tr").off("click", ".update-link");
31
  });
32
  </script>
33
  <?php
39
  $path;
40
  }
41
 
42
+ /**
43
+ * Used by the WP filter phpseclib_filesystem_method
44
+ */
45
  function phpseclib_filesystem_method($method, $args) {
46
+ return (isset($args['connection_type']) && 'ssh' == $args['connection_type']) ? 'ssh2' : $method;
47
  }
48
 
49
  function phpseclib_fs_ftp_connection_types($types) {
279
 
280
  protected static $_notices_instance = null;
281
 
282
+ /**
283
+ * Constructor
284
+ */
285
  public function __construct() {
286
  add_action('plugins_loaded', array($this, 'plugins_loaded'), 1);
287
  add_action('admin_init', array($this, 'admin_init'));