SSH SFTP Updater Support - Version 0.8.2

Version Description

  • 2019/Jun/22 =

  • TWEAK: Make the FTP_ constants apply.

Download this release

Release Info

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

Code changes from version 0.8.1 to 0.8.2

class-wp-filesystem-ssh2.php CHANGED
@@ -373,4 +373,77 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
373
  }
374
  return $ret;
375
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  }
373
  }
374
  return $ret;
375
  }
376
+
377
+ /**
378
+ * Locates a folder on the remote filesystem. Added from includes/class-wp-filesystem-base.php in 0.8.2 to make the FTP_constants work
379
+ *
380
+ * Assumes that on Windows systems, Stripping off the Drive
381
+ * letter is OK Sanitizes \\ to / in Windows filepaths.
382
+ *
383
+ * @since 2.7.0
384
+ *
385
+ * @param string $folder the folder to locate.
386
+ * @return string|false The location of the remote path, false on failure.
387
+ */
388
+ public function find_folder( $folder ) {
389
+ if ( isset( $this->cache[ $folder ] ) ) {
390
+ return $this->cache[ $folder ];
391
+ }
392
+
393
+ // The true here is because we always want to use them if inside this class - a minimal change from the core method, making future merging of upstream changes easier
394
+ if ( true || stripos( $this->method, 'ftp' ) !== false ) {
395
+ $constant_overrides = array(
396
+ 'FTP_BASE' => ABSPATH,
397
+ 'FTP_CONTENT_DIR' => WP_CONTENT_DIR,
398
+ 'FTP_PLUGIN_DIR' => WP_PLUGIN_DIR,
399
+ 'FTP_LANG_DIR' => WP_LANG_DIR,
400
+ );
401
+
402
+ // Direct matches ( folder = CONSTANT/ )
403
+ foreach ( $constant_overrides as $constant => $dir ) {
404
+ if ( ! defined( $constant ) ) {
405
+ continue;
406
+ }
407
+ if ( $folder === $dir ) {
408
+ return trailingslashit( constant( $constant ) );
409
+ }
410
+ }
411
+
412
+ // Prefix Matches ( folder = CONSTANT/subdir )
413
+ foreach ( $constant_overrides as $constant => $dir ) {
414
+ if ( ! defined( $constant ) ) {
415
+ continue;
416
+ }
417
+ if ( 0 === stripos( $folder, $dir ) ) { // $folder starts with $dir
418
+ $potential_folder = preg_replace( '#^' . preg_quote( $dir, '#' ) . '/#i', trailingslashit( constant( $constant ) ), $folder );
419
+ $potential_folder = trailingslashit( $potential_folder );
420
+
421
+ if ( $this->is_dir( $potential_folder ) ) {
422
+ $this->cache[ $folder ] = $potential_folder;
423
+ return $potential_folder;
424
+ }
425
+ }
426
+ }
427
+ } elseif ( 'direct' == $this->method ) {
428
+ $folder = str_replace( '\\', '/', $folder ); // Windows path sanitisation
429
+ return trailingslashit( $folder );
430
+ }
431
+
432
+ $folder = preg_replace( '|^([a-z]{1}):|i', '', $folder ); // Strip out windows drive letter if it's there.
433
+ $folder = str_replace( '\\', '/', $folder ); // Windows path sanitisation
434
+
435
+ if ( isset( $this->cache[ $folder ] ) ) {
436
+ return $this->cache[ $folder ];
437
+ }
438
+
439
+ if ( $this->exists( $folder ) ) { // Folder exists at that absolute path.
440
+ $folder = trailingslashit( $folder );
441
+ $this->cache[ $folder ] = $folder;
442
+ return $folder;
443
+ }
444
+ if ( $return = $this->search_for_folder( $folder ) ) {
445
+ $this->cache[ $folder ] = $return;
446
+ }
447
+ return $return;
448
+ }
449
  }
phpseclib/Crypt/RSA.php CHANGED
@@ -210,6 +210,10 @@ define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2);
210
  * PKCS#8 formatted private key
211
  */
212
  define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 8);
 
 
 
 
213
  /**#@-*/
214
 
215
  /**#@+
@@ -878,6 +882,58 @@ class Crypt_RSA
878
  $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
879
 
880
  return $key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
881
  default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
882
  $components = array();
883
  foreach ($raw as $name => $value) {
@@ -1497,6 +1553,75 @@ class Crypt_RSA
1497
  }
1498
  $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($private, $length), -256));
1499
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1500
  return $components;
1501
  }
1502
  }
@@ -1653,7 +1778,8 @@ class Crypt_RSA
1653
  CRYPT_RSA_PRIVATE_FORMAT_PKCS1,
1654
  CRYPT_RSA_PRIVATE_FORMAT_XML,
1655
  CRYPT_RSA_PRIVATE_FORMAT_PUTTY,
1656
- CRYPT_RSA_PUBLIC_FORMAT_OPENSSH
 
1657
  );
1658
  foreach ($types as $type) {
1659
  $components = $this->_parseKey($key, $type);
@@ -2301,6 +2427,10 @@ class Crypt_RSA
2301
  */
2302
  function _equals($x, $y)
2303
  {
 
 
 
 
2304
  if (strlen($x) != strlen($y)) {
2305
  return false;
2306
  }
210
  * PKCS#8 formatted private key
211
  */
212
  define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 8);
213
+ /**
214
+ * OpenSSH formatted private key
215
+ */
216
+ define('CRYPT_RSA_PRIVATE_FORMAT_OPENSSH', 9);
217
  /**#@-*/
218
 
219
  /**#@+
882
  $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
883
 
884
  return $key;
885
+ case CRYPT_RSA_PRIVATE_FORMAT_OPENSSH:
886
+ if ($num_primes != 2) {
887
+ return false;
888
+ }
889
+ $publicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']);
890
+ $privateKey = pack(
891
+ 'Na*Na*Na*Na*Na*Na*Na*',
892
+ strlen('ssh-rsa'),
893
+ 'ssh-rsa',
894
+ strlen($raw['modulus']),
895
+ $raw['modulus'],
896
+ strlen($raw['publicExponent']),
897
+ $raw['publicExponent'],
898
+ strlen($raw['privateExponent']),
899
+ $raw['privateExponent'],
900
+ strlen($raw['coefficient']),
901
+ $raw['coefficient'],
902
+ strlen($raw['prime1']),
903
+ $raw['prime1'],
904
+ strlen($raw['prime2']),
905
+ $raw['prime2']
906
+ );
907
+ $checkint = crypt_random_string(4);
908
+ $paddedKey = pack(
909
+ 'a*Na*',
910
+ $checkint . $checkint . $privateKey,
911
+ strlen($this->comment),
912
+ $this->comment
913
+ );
914
+ $paddingLength = (7 * strlen($paddedKey)) % 8;
915
+ for ($i = 1; $i <= $paddingLength; $i++) {
916
+ $paddedKey.= chr($i);
917
+ }
918
+ $key = pack(
919
+ 'Na*Na*Na*NNa*Na*',
920
+ strlen('none'),
921
+ 'none',
922
+ strlen('none'),
923
+ 'none',
924
+ 0,
925
+ '',
926
+ 1,
927
+ strlen($publicKey),
928
+ $publicKey,
929
+ strlen($paddedKey),
930
+ $paddedKey
931
+ );
932
+ $key = "openssh-key-v1\0$key";
933
+
934
+ return "-----BEGIN OPENSSH PRIVATE KEY-----\r\n" .
935
+ chunk_split(base64_encode($key), 70) .
936
+ "-----END OPENSSH PRIVATE KEY-----";
937
  default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
938
  $components = array();
939
  foreach ($raw as $name => $value) {
1553
  }
1554
  $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($private, $length), -256));
1555
 
1556
+ return $components;
1557
+ case CRYPT_RSA_PRIVATE_FORMAT_OPENSSH:
1558
+ $components = array();
1559
+ $decoded = $this->_extractBER($key);
1560
+ $magic = $this->_string_shift($decoded, 15);
1561
+ if ($magic !== "openssh-key-v1\0") {
1562
+ return false;
1563
+ }
1564
+ $options = $this->_string_shift($decoded, 24);
1565
+ // \0\0\0\4none = ciphername
1566
+ // \0\0\0\4none = kdfname
1567
+ // \0\0\0\0 = kdfoptions
1568
+ // \0\0\0\1 = numkeys
1569
+ if ($options != "\0\0\0\4none\0\0\0\4none\0\0\0\0\0\0\0\1") {
1570
+ return false;
1571
+ }
1572
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
1573
+ if (strlen($decoded) < $length) {
1574
+ return false;
1575
+ }
1576
+ $publicKey = $this->_string_shift($decoded, $length);
1577
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
1578
+ if (strlen($decoded) < $length) {
1579
+ return false;
1580
+ }
1581
+ $paddedKey = $this->_string_shift($decoded, $length);
1582
+
1583
+ if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") {
1584
+ return false;
1585
+ }
1586
+
1587
+ $checkint1 = $this->_string_shift($paddedKey, 4);
1588
+ $checkint2 = $this->_string_shift($paddedKey, 4);
1589
+ if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) {
1590
+ return false;
1591
+ }
1592
+
1593
+ if ($this->_string_shift($paddedKey, 11) !== "\0\0\0\7ssh-rsa") {
1594
+ return false;
1595
+ }
1596
+
1597
+ $values = array(
1598
+ &$components['modulus'],
1599
+ &$components['publicExponent'],
1600
+ &$components['privateExponent'],
1601
+ &$components['coefficients'][2],
1602
+ &$components['primes'][1],
1603
+ &$components['primes'][2]
1604
+ );
1605
+
1606
+ foreach ($values as &$value) {
1607
+ extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
1608
+ if (strlen($paddedKey) < $length) {
1609
+ return false;
1610
+ }
1611
+ $value = new Math_BigInteger($this->_string_shift($paddedKey, $length), -256);
1612
+ }
1613
+
1614
+ extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
1615
+ if (strlen($paddedKey) < $length) {
1616
+ return false;
1617
+ }
1618
+ $components['comment'] = $this->_string_shift($decoded, $length);
1619
+
1620
+ $temp = $components['primes'][1]->subtract($this->one);
1621
+ $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
1622
+ $temp = $components['primes'][2]->subtract($this->one);
1623
+ $components['exponents'][] = $components['publicExponent']->modInverse($temp);
1624
+
1625
  return $components;
1626
  }
1627
  }
1778
  CRYPT_RSA_PRIVATE_FORMAT_PKCS1,
1779
  CRYPT_RSA_PRIVATE_FORMAT_XML,
1780
  CRYPT_RSA_PRIVATE_FORMAT_PUTTY,
1781
+ CRYPT_RSA_PUBLIC_FORMAT_OPENSSH,
1782
+ CRYPT_RSA_PRIVATE_FORMAT_OPENSSH
1783
  );
1784
  foreach ($types as $type) {
1785
  $components = $this->_parseKey($key, $type);
2427
  */
2428
  function _equals($x, $y)
2429
  {
2430
+ if (function_exists('hash_equals')) {
2431
+ return hash_equals($x, $y);
2432
+ }
2433
+
2434
  if (strlen($x) != strlen($y)) {
2435
  return false;
2436
  }
phpseclib/File/ASN1.php CHANGED
@@ -326,9 +326,10 @@ class File_ASN1
326
  $tag = 0;
327
  // process septets (since the eighth bit is ignored, it's not an octet)
328
  do {
329
- $loop = ord($encoded[0]) >> 7;
 
330
  $tag <<= 7;
331
- $tag |= ord($encoded[$encoded_pos++]) & 0x7F;
332
  $start++;
333
  } while ($loop);
334
  }
@@ -515,24 +516,7 @@ class File_ASN1
515
  }
516
  break;
517
  case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
518
- $temp = ord($content[$content_pos++]);
519
- $current['content'] = sprintf('%d.%d', floor($temp / 40), $temp % 40);
520
- $valuen = 0;
521
- // process septets
522
- $content_len = strlen($content);
523
- while ($content_pos < $content_len) {
524
- $temp = ord($content[$content_pos++]);
525
- $valuen <<= 7;
526
- $valuen |= $temp & 0x7F;
527
- if (~$temp & 0x80) {
528
- $current['content'].= ".$valuen";
529
- $valuen = 0;
530
- }
531
- }
532
- // the eighth bit of the last byte should not be 1
533
- //if ($temp >> 7) {
534
- // return false;
535
- //}
536
  break;
537
  /* Each character string type shall be encoded as if it had been declared:
538
  [UNIVERSAL x] IMPLICIT OCTET STRING
@@ -1111,27 +1095,7 @@ class File_ASN1
1111
  $value = base64_decode($source);
1112
  break;
1113
  case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
1114
- $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
1115
- if ($oid === false) {
1116
- user_error('Invalid OID');
1117
- return false;
1118
- }
1119
- $value = '';
1120
- $parts = explode('.', $oid);
1121
- $value = chr(40 * $parts[0] + $parts[1]);
1122
- for ($i = 2; $i < count($parts); $i++) {
1123
- $temp = '';
1124
- if (!$parts[$i]) {
1125
- $temp = "\0";
1126
- } else {
1127
- while ($parts[$i]) {
1128
- $temp = chr(0x80 | ($parts[$i] & 0x7F)) . $temp;
1129
- $parts[$i] >>= 7;
1130
- }
1131
- $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
1132
- }
1133
- $value.= $temp;
1134
- }
1135
  break;
1136
  case FILE_ASN1_TYPE_ANY:
1137
  $loc = $this->location;
@@ -1230,6 +1194,108 @@ class File_ASN1
1230
  return pack('Ca*', 0x80 | strlen($temp), $temp);
1231
  }
1232
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1233
  /**
1234
  * BER-decode the time (using UNIX time)
1235
  *
326
  $tag = 0;
327
  // process septets (since the eighth bit is ignored, it's not an octet)
328
  do {
329
+ $temp = ord($encoded[$encoded_pos++]);
330
+ $loop = $temp >> 7;
331
  $tag <<= 7;
332
+ $tag |= $temp & 0x7F;
333
  $start++;
334
  } while ($loop);
335
  }
516
  }
517
  break;
518
  case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
519
+ $current['content'] = $this->_decodeOID(substr($content, $content_pos));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
  break;
521
  /* Each character string type shall be encoded as if it had been declared:
522
  [UNIVERSAL x] IMPLICIT OCTET STRING
1095
  $value = base64_decode($source);
1096
  break;
1097
  case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
1098
+ $value = $this->_encodeOID($source);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1099
  break;
1100
  case FILE_ASN1_TYPE_ANY:
1101
  $loc = $this->location;
1194
  return pack('Ca*', 0x80 | strlen($temp), $temp);
1195
  }
1196
 
1197
+ /**
1198
+ * BER-decode the OID
1199
+ *
1200
+ * Called by _decode_ber()
1201
+ *
1202
+ * @access private
1203
+ * @param string $content
1204
+ * @return string
1205
+ */
1206
+ function _decodeOID($content)
1207
+ {
1208
+ static $eighty;
1209
+ if (!$eighty) {
1210
+ $eighty = new Math_BigInteger(80);
1211
+ }
1212
+
1213
+ $oid = array();
1214
+ $pos = 0;
1215
+ $len = strlen($content);
1216
+ $n = new Math_BigInteger();
1217
+ while ($pos < $len) {
1218
+ $temp = ord($content[$pos++]);
1219
+ $n = $n->bitwise_leftShift(7);
1220
+ $n = $n->bitwise_or(new Math_BigInteger($temp & 0x7F));
1221
+ if (~$temp & 0x80) {
1222
+ $oid[] = $n;
1223
+ $n = new Math_BigInteger();
1224
+ }
1225
+ }
1226
+ $part1 = array_shift($oid);
1227
+ $first = floor(ord($content[0]) / 40);
1228
+ /*
1229
+ "This packing of the first two object identifier components recognizes that only three values are allocated from the root
1230
+ node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1."
1231
+
1232
+ -- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22
1233
+ */
1234
+ if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78)
1235
+ array_unshift($oid, ord($content[0]) % 40);
1236
+ array_unshift($oid, $first);
1237
+ } else {
1238
+ array_unshift($oid, $part1->subtract($eighty));
1239
+ array_unshift($oid, 2);
1240
+ }
1241
+
1242
+ return implode('.', $oid);
1243
+ }
1244
+
1245
+ /**
1246
+ * DER-encode the OID
1247
+ *
1248
+ * Called by _encode_der()
1249
+ *
1250
+ * @access private
1251
+ * @param string $content
1252
+ * @return string
1253
+ */
1254
+ function _encodeOID($source)
1255
+ {
1256
+ static $mask, $zero, $forty;
1257
+ if (!$mask) {
1258
+ $mask = new Math_BigInteger(0x7F);
1259
+ $zero = new Math_BigInteger();
1260
+ $forty = new Math_BigInteger(40);
1261
+ }
1262
+
1263
+ $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
1264
+ if ($oid === false) {
1265
+ user_error('Invalid OID');
1266
+ return false;
1267
+ }
1268
+ $parts = explode('.', $oid);
1269
+ $part1 = array_shift($parts);
1270
+ $part2 = array_shift($parts);
1271
+
1272
+ $first = new Math_BigInteger($part1);
1273
+ $first = $first->multiply($forty);
1274
+ $first = $first->add(new Math_BigInteger($part2));
1275
+
1276
+ array_unshift($parts, $first->toString());
1277
+
1278
+ $value = '';
1279
+ foreach ($parts as $part) {
1280
+ if (!$part) {
1281
+ $temp = "\0";
1282
+ } else {
1283
+ $temp = '';
1284
+ $part = new Math_BigInteger($part);
1285
+ while (!$part->equals($zero)) {
1286
+ $submask = $part->bitwise_and($mask);
1287
+ $submask->setPrecision(8);
1288
+ $temp = (chr(0x80) | $submask->toBytes()) . $temp;
1289
+ $part = $part->bitwise_rightShift(7);
1290
+ }
1291
+ $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
1292
+ }
1293
+ $value.= $temp;
1294
+ }
1295
+
1296
+ return $value;
1297
+ }
1298
+
1299
  /**
1300
  * BER-decode the time (using UNIX time)
1301
  *
phpseclib/Math/BigInteger.php CHANGED
@@ -441,6 +441,9 @@ class Math_BigInteger
441
  // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
442
  // [^-0-9].*: find any non-numeric characters and then any characters that follow that
443
  $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
 
 
 
444
 
445
  switch (MATH_BIGINTEGER_MODE) {
446
  case MATH_BIGINTEGER_MODE_GMP:
@@ -2724,7 +2727,14 @@ class Math_BigInteger
2724
  {
2725
  switch (MATH_BIGINTEGER_MODE) {
2726
  case MATH_BIGINTEGER_MODE_GMP:
2727
- return gmp_cmp($this->value, $y->value);
 
 
 
 
 
 
 
2728
  case MATH_BIGINTEGER_MODE_BCMATH:
2729
  return bccomp($this->value, $y->value, 0);
2730
  }
441
  // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
442
  // [^-0-9].*: find any non-numeric characters and then any characters that follow that
443
  $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
444
+ if (!strlen($x) || $x == '-') {
445
+ $x = '0';
446
+ }
447
 
448
  switch (MATH_BIGINTEGER_MODE) {
449
  case MATH_BIGINTEGER_MODE_GMP:
2727
  {
2728
  switch (MATH_BIGINTEGER_MODE) {
2729
  case MATH_BIGINTEGER_MODE_GMP:
2730
+ $r = gmp_cmp($this->value, $y->value);
2731
+ if ($r < -1) {
2732
+ $r = -1;
2733
+ }
2734
+ if ($r > 1) {
2735
+ $r = 1;
2736
+ }
2737
+ return $r;
2738
  case MATH_BIGINTEGER_MODE_BCMATH:
2739
  return bccomp($this->value, $y->value, 0);
2740
  }
phpseclib/Net/SFTP.php CHANGED
@@ -3049,7 +3049,9 @@ class Net_SFTP extends Net_SSH2
3049
  return $temp;
3050
  }
3051
 
3052
- $this->curTimeout = false;
 
 
3053
 
3054
  $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
3055
 
@@ -3070,6 +3072,13 @@ class Net_SFTP extends Net_SSH2
3070
  $tempLength = $length;
3071
  $tempLength-= strlen($this->packet_buffer);
3072
 
 
 
 
 
 
 
 
3073
  // SFTP packet type and data payload
3074
  while ($tempLength > 0) {
3075
  $temp = $this->_get_channel_packet(NET_SFTP_CHANNEL, true);
3049
  return $temp;
3050
  }
3051
 
3052
+ // in SSH2.php the timeout is cumulative per function call. eg. exec() will
3053
+ // timeout after 10s. but for SFTP.php it's cumulative per packet
3054
+ $this->curTimeout = $this->timeout;
3055
 
3056
  $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
3057
 
3072
  $tempLength = $length;
3073
  $tempLength-= strlen($this->packet_buffer);
3074
 
3075
+
3076
+ // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h
3077
+ if ($tempLength > 256 * 1024) {
3078
+ user_error('Invalid SFTP packet size');
3079
+ return false;
3080
+ }
3081
+
3082
  // SFTP packet type and data payload
3083
  while ($tempLength > 0) {
3084
  $temp = $this->_get_channel_packet(NET_SFTP_CHANNEL, true);
phpseclib/Net/SSH2.php CHANGED
@@ -142,7 +142,10 @@ define('NET_SSH2_READ_SIMPLE', 1);
142
  */
143
  define('NET_SSH2_READ_REGEX', 2);
144
  /**
145
- * Returns when a string matching the regular expression $expect is found
 
 
 
146
  */
147
  define('NET_SSH2_READ_NEXT', 3);
148
  /**#@-*/
@@ -3408,7 +3411,7 @@ class Net_SSH2
3408
  return false;
3409
  }
3410
  foreach ($this->auth as $auth) {
3411
- $result = call_user_func_array(array(&$this, 'parent::login'), $auth);
3412
  }
3413
  return $result;
3414
  }
@@ -3812,6 +3815,7 @@ class Net_SSH2
3812
  // on windows this returns a "Warning: Invalid CRT parameters detected" error
3813
  if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
3814
  $this->is_timeout = true;
 
3815
  return true;
3816
  }
3817
  $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
142
  */
143
  define('NET_SSH2_READ_REGEX', 2);
144
  /**
145
+ * Returns whenever a data packet is received.
146
+ *
147
+ * Some data packets may only contain a single character so it may be necessary
148
+ * to call read() multiple times when using this option
149
  */
150
  define('NET_SSH2_READ_NEXT', 3);
151
  /**#@-*/
3411
  return false;
3412
  }
3413
  foreach ($this->auth as $auth) {
3414
+ $result = call_user_func_array(array(&$this, 'login'), $auth);
3415
  }
3416
  return $result;
3417
  }
3815
  // on windows this returns a "Warning: Invalid CRT parameters detected" error
3816
  if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
3817
  $this->is_timeout = true;
3818
+ $this->_close_channel($client_channel);
3819
  return true;
3820
  }
3821
  $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === SSH SFTP Updater Support ===
2
  Contributors: DavidAnderson, TerraFrost, pmbaldha
3
- 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.2
7
- Stable tag: 0.8.1
8
 
9
  "SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
10
 
@@ -41,6 +41,10 @@ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPres
41
 
42
  == Changelog ==
43
 
 
 
 
 
44
  = 0.8.1 - 2019/Apr/13 =
45
 
46
  * TWEAK: Don't require phpseclib classes if they already exist
@@ -112,4 +116,4 @@ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPres
112
  * Initial Release
113
 
114
  == Upgrade Notice ==
115
- * 0.8.1 : Don't require phpseclib classes if they already exist
1
  === SSH SFTP Updater Support ===
2
  Contributors: DavidAnderson, TerraFrost, pmbaldha
3
+ Donate link: https://sourceforge.net/donate/index.php?group_id=198487
4
  Tags: ssh, sftp
5
  Requires at least: 3.1
6
  Tested up to: 5.2
7
+ Stable tag: 0.8.2
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.2 - 2019/Jun/22 =
45
+
46
+ * TWEAK: Make the FTP_ constants apply.
47
+
48
  = 0.8.1 - 2019/Apr/13 =
49
 
50
  * TWEAK: Don't require phpseclib classes if they already exist
116
  * Initial Release
117
 
118
  == Upgrade Notice ==
119
+ * 0.8.2 : Make the FTP_* constants apply
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.8.1
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.8.1');
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
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.2
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.2');
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