aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/phpseclib
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2021-10-08 12:24:19 +0000
committerMario <mario@mariovavti.com>2021-10-08 12:24:19 +0000
commite6dac085cb1d601da1fc63bfd59d811612fa6ef4 (patch)
treef5b704b613c9c8d347857b4e7f8dd0b19cdd7df3 /vendor/phpseclib
parentf5f357060bf0ebcb0b8352519375953d993437e7 (diff)
downloadvolse-hubzilla-e6dac085cb1d601da1fc63bfd59d811612fa6ef4.tar.gz
volse-hubzilla-e6dac085cb1d601da1fc63bfd59d811612fa6ef4.tar.bz2
volse-hubzilla-e6dac085cb1d601da1fc63bfd59d811612fa6ef4.zip
update composer libs
Diffstat (limited to 'vendor/phpseclib')
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php67
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php66
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php80
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/File/X509.php11
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php6
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php75
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php6
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php105
8 files changed, 315 insertions, 101 deletions
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
index efbcd242b..8822b9b88 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
@@ -779,12 +779,14 @@ abstract class Base
}
if ($this->engine === self::ENGINE_MCRYPT) {
+ set_error_handler(array($this, 'do_nothing'));
+
if ($this->changed) {
$this->_setupMcrypt();
$this->changed = false;
}
if ($this->enchanged) {
- @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+ mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
$this->enchanged = false;
}
@@ -817,15 +819,15 @@ abstract class Base
if ($len >= $block_size) {
if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
if ($this->enbuffer['enmcrypt_init'] === true) {
- @mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
+ mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
$this->enbuffer['enmcrypt_init'] = false;
}
- $ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
+ $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
$iv = substr($ciphertext, -$block_size);
$len%= $block_size;
} else {
while ($len >= $block_size) {
- $iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
+ $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
$ciphertext.= $iv;
$len-= $block_size;
$i+= $block_size;
@@ -834,22 +836,26 @@ abstract class Base
}
if ($len) {
- $iv = @mcrypt_generic($this->ecb, $iv);
+ $iv = mcrypt_generic($this->ecb, $iv);
$block = $iv ^ substr($plaintext, -$len);
$iv = substr_replace($iv, $block, 0, $len);
$ciphertext.= $block;
$pos = $len;
}
+ restore_error_handler();
+
return $ciphertext;
}
- $ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext);
+ $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
if (!$this->continuousBuffer) {
- @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+ mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
}
+ restore_error_handler();
+
return $ciphertext;
}
@@ -1118,13 +1124,14 @@ abstract class Base
}
if ($this->engine === self::ENGINE_MCRYPT) {
+ set_error_handler(array($this, 'do_nothing'));
$block_size = $this->block_size;
if ($this->changed) {
$this->_setupMcrypt();
$this->changed = false;
}
if ($this->dechanged) {
- @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+ mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
$this->dechanged = false;
}
@@ -1152,26 +1159,30 @@ abstract class Base
}
if ($len >= $block_size) {
$cb = substr($ciphertext, $i, $len - $len % $block_size);
- $plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
+ $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
$iv = substr($cb, -$block_size);
$len%= $block_size;
}
if ($len) {
- $iv = @mcrypt_generic($this->ecb, $iv);
+ $iv = mcrypt_generic($this->ecb, $iv);
$plaintext.= $iv ^ substr($ciphertext, -$len);
$iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
$pos = $len;
}
+ restore_error_handler();
+
return $plaintext;
}
- $plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext);
+ $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
if (!$this->continuousBuffer) {
- @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+ mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
}
+ restore_error_handler();
+
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
}
@@ -1649,9 +1660,12 @@ abstract class Base
}
return false;
case self::ENGINE_MCRYPT:
- return $this->cipher_name_mcrypt &&
+ set_error_handler(array($this, 'do_nothing'));
+ $result = $this->cipher_name_mcrypt &&
extension_loaded('mcrypt') &&
- in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms());
+ in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms());
+ restore_error_handler();
+ return $result;
case self::ENGINE_INTERNAL:
return true;
}
@@ -1728,17 +1742,19 @@ abstract class Base
}
if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) {
+ set_error_handler(array($this, 'do_nothing'));
// Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
// (re)open them with the module named in $this->cipher_name_mcrypt
- @mcrypt_module_close($this->enmcrypt);
- @mcrypt_module_close($this->demcrypt);
+ mcrypt_module_close($this->enmcrypt);
+ mcrypt_module_close($this->demcrypt);
$this->enmcrypt = null;
$this->demcrypt = null;
if ($this->ecb) {
- @mcrypt_module_close($this->ecb);
+ mcrypt_module_close($this->ecb);
$this->ecb = null;
}
+ restore_error_handler();
}
$this->changed = true;
@@ -1851,19 +1867,19 @@ abstract class Base
self::MODE_STREAM => MCRYPT_MODE_STREAM,
);
- $this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
- $this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
+ $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
+ $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
// we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
// to workaround mcrypt's broken ncfb implementation in buffered mode
// see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
if ($this->mode == self::MODE_CFB) {
- $this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
+ $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
}
} // else should mcrypt_generic_deinit be called?
if ($this->mode == self::MODE_CFB) {
- @mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
+ mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
}
}
@@ -2696,4 +2712,13 @@ abstract class Base
return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
}
}
+
+ /**
+ * Dummy error handler to suppress mcrypt errors
+ *
+ * @access private
+ */
+ function do_nothing()
+ {
+ }
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
index 17e2b8329..e26fe41dd 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
@@ -1219,6 +1219,7 @@ class RSA
$length = $this->_decodeLength($temp);
switch ($this->_string_shift($temp, $length)) {
case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
+ case "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0A": // rsaPSS
break;
case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
/*
@@ -2579,9 +2580,9 @@ class RSA
$offset+= $patternMatch ? 0 : 1;
}
- // we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation
+ // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation
// to protect against timing attacks
- if (!$hashesMatch & !$patternMatch) {
+ if (!$hashesMatch | !$patternMatch) {
user_error('Decryption error');
return false;
}
@@ -2917,6 +2918,59 @@ class RSA
}
/**
+ * EMSA-PKCS1-V1_5-ENCODE (without NULL)
+ *
+ * Quoting https://tools.ietf.org/html/rfc8017#page-65,
+ *
+ * "The parameters field associated with id-sha1, id-sha224, id-sha256,
+ * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should
+ * generally be omitted, but if present, it shall have a value of type
+ * NULL"
+ *
+ * @access private
+ * @param string $m
+ * @param int $emLen
+ * @return string
+ */
+ function _emsa_pkcs1_v1_5_encode_without_null($m, $emLen)
+ {
+ $h = $this->hash->hash($m);
+ if ($h === false) {
+ return false;
+ }
+
+ switch ($this->hashName) {
+ case 'sha1':
+ $t = pack('H*', '301f300706052b0e03021a0414');
+ break;
+ case 'sha256':
+ $t = pack('H*', '302f300b06096086480165030402010420');
+ break;
+ case 'sha384':
+ $t = pack('H*', '303f300b06096086480165030402020430');
+ break;
+ case 'sha512':
+ $t = pack('H*', '304f300b06096086480165030402030440');
+ break;
+ default:
+ return false;
+ }
+ $t.= $h;
+ $tLen = strlen($t);
+
+ if ($emLen < $tLen + 11) {
+ user_error('Intended encoded message length too short');
+ return false;
+ }
+
+ $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
+
+ $em = "\0\1$ps\0$t";
+
+ return $em;
+ }
+
+ /**
* RSASSA-PKCS1-V1_5-SIGN
*
* See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.
@@ -2982,13 +3036,17 @@ class RSA
// EMSA-PKCS1-v1_5 encoding
$em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
- if ($em2 === false) {
+ $em3 = $this->_emsa_pkcs1_v1_5_encode_without_null($m, $this->k);
+
+ if ($em2 === false && $em3 === false) {
user_error('RSA modulus too short');
return false;
}
// Compare
- return $this->_equals($em, $em2);
+
+ return ($em2 !== false && $this->_equals($em, $em2)) ||
+ ($em3 !== false && $this->_equals($em, $em3));
}
/**
diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
index 807ca88ce..fb2d64485 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
@@ -234,8 +234,11 @@ class ASN1
{
$current = array('start' => $start);
+ if (!isset($encoded[$encoded_pos])) {
+ return false;
+ }
$type = ord($encoded[$encoded_pos++]);
- $start++;
+ $startOffset = 1;
$constructed = ($type >> 5) & 1;
@@ -244,15 +247,28 @@ class ASN1
$tag = 0;
// process septets (since the eighth bit is ignored, it's not an octet)
do {
+ if (!isset($encoded[$encoded_pos])) {
+ return false;
+ }
$temp = ord($encoded[$encoded_pos++]);
+ $startOffset++;
$loop = $temp >> 7;
$tag <<= 7;
- $tag |= $temp & 0x7F;
- $start++;
+ $temp &= 0x7F;
+ // "bits 7 to 1 of the first subsequent octet shall not all be zero"
+ if ($startOffset == 2 && $temp == 0) {
+ return false;
+ }
+ $tag |= $temp;
} while ($loop);
}
+ $start+= $startOffset;
+
// Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13
+ if (!isset($encoded[$encoded_pos])) {
+ return false;
+ }
$length = ord($encoded[$encoded_pos++]);
$start++;
if ($length == 0x80) { // indefinite length
@@ -344,13 +360,16 @@ class ASN1
switch ($tag) {
case self::TYPE_BOOLEAN:
// "The contents octets shall consist of a single octet." -- paragraph 8.2.1
- //if (strlen($content) != 1) {
- // return false;
- //}
+ if ($constructed || strlen($content) != 1) {
+ return false;
+ }
$current['content'] = (bool) ord($content[$content_pos]);
break;
case self::TYPE_INTEGER:
case self::TYPE_ENUMERATED:
+ if ($constructed) {
+ return false;
+ }
$current['content'] = new BigInteger(substr($content, $content_pos), -256);
break;
case self::TYPE_REAL: // not currently supported
@@ -370,15 +389,15 @@ class ASN1
$last = count($temp) - 1;
for ($i = 0; $i < $last; $i++) {
// all subtags should be bit strings
- //if ($temp[$i]['type'] != self::TYPE_BIT_STRING) {
- // return false;
- //}
+ if ($temp[$i]['type'] != self::TYPE_BIT_STRING) {
+ return false;
+ }
$current['content'].= substr($temp[$i]['content'], 1);
}
// all subtags should be bit strings
- //if ($temp[$last]['type'] != self::TYPE_BIT_STRING) {
- // return false;
- //}
+ if ($temp[$last]['type'] != self::TYPE_BIT_STRING) {
+ return false;
+ }
$current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1);
}
break;
@@ -395,9 +414,9 @@ class ASN1
}
$content_pos += $temp['length'];
// all subtags should be octet strings
- //if ($temp['type'] != self::TYPE_OCTET_STRING) {
- // return false;
- //}
+ if ($temp['type'] != self::TYPE_OCTET_STRING) {
+ return false;
+ }
$current['content'].= $temp['content'];
$length+= $temp['length'];
}
@@ -408,12 +427,15 @@ class ASN1
break;
case self::TYPE_NULL:
// "The contents octets shall not contain any octets." -- paragraph 8.8.2
- //if (strlen($content)) {
- // return false;
- //}
+ if ($constructed || strlen($content)) {
+ return false;
+ }
break;
case self::TYPE_SEQUENCE:
case self::TYPE_SET:
+ if (!$constructed) {
+ return false;
+ }
$offset = 0;
$current['content'] = array();
$content_len = strlen($content);
@@ -434,7 +456,13 @@ class ASN1
}
break;
case self::TYPE_OBJECT_IDENTIFIER:
+ if ($constructed) {
+ return false;
+ }
$current['content'] = $this->_decodeOID(substr($content, $content_pos));
+ if ($current['content'] === false) {
+ return false;
+ }
break;
/* Each character string type shall be encoded as if it had been declared:
[UNIVERSAL x] IMPLICIT OCTET STRING
@@ -464,12 +492,20 @@ class ASN1
case self::TYPE_UTF8_STRING:
// ????
case self::TYPE_BMP_STRING:
+ if ($constructed) {
+ return false;
+ }
$current['content'] = substr($content, $content_pos);
break;
case self::TYPE_UTC_TIME:
case self::TYPE_GENERALIZED_TIME:
+ if ($constructed) {
+ return false;
+ }
$current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag);
+ break;
default:
+ return false;
}
$start+= $length;
@@ -966,7 +1002,10 @@ class ASN1
case self::TYPE_GENERALIZED_TIME:
$format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y';
$format.= 'mdHis';
+ // if $source does _not_ include timezone information within it then assume that the timezone is GMT
$date = new DateTime($source, new DateTimeZone('GMT'));
+ // if $source _does_ include timezone information within it then convert the time to GMT
+ $date->setTimezone(new DateTimeZone('GMT'));
$value = $date->format($format) . 'Z';
break;
case self::TYPE_BIT_STRING:
@@ -1127,6 +1166,11 @@ class ASN1
$oid = array();
$pos = 0;
$len = strlen($content);
+
+ if (ord($content[$len - 1]) & 0x80) {
+ return false;
+ }
+
$n = new BigInteger();
while ($pos < $len) {
$temp = ord($content[$pos++]);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
index 3520efdc1..0da0b83cc 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
@@ -1622,7 +1622,6 @@ class X509
$id = $extensions[$i]['extnId'];
$value = &$extensions[$i]['extnValue'];
$value = base64_decode($value);
- $decoded = $asn1->decodeBER($value);
/* [extnValue] contains the DER encoding of an ASN.1 value
corresponding to the extension type identified by extnID */
$map = $this->_getMapping($id);
@@ -1630,6 +1629,7 @@ class X509
$decoder = $id == 'id-ce-nameConstraints' ?
array($this, '_decodeNameConstraintIP') :
array($this, '_decodeIP');
+ $decoded = $asn1->decodeBER($value);
$mapped = $asn1->asn1map($decoded[0], $map, array('iPAddress' => $decoder));
$value = $mapped === false ? $decoded[0] : $mapped;
@@ -5054,9 +5054,12 @@ class X509
* subject=/O=organization/OU=org unit/CN=common name
* issuer=/O=organization/CN=common name
*/
- $temp = strlen($str) <= ini_get('pcre.backtrack_limit') ?
- preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1) :
- $str;
+ if (strlen($str) > ini_get('pcre.backtrack_limit')) {
+ $temp = $str;
+ } else {
+ $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
+ $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $temp, 1);
+ }
// remove new lines
$temp = str_replace(array("\r", "\n", ' '), '', $temp);
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
index 9df0bf0f2..fc24b9145 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
@@ -658,11 +658,11 @@ class BigInteger
{
$hex = $this->toHex($twos_compliment);
$bits = '';
- for ($i = strlen($hex) - 8, $start = strlen($hex) & 7; $i >= $start; $i-=8) {
- $bits = str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT) . $bits;
+ for ($i = strlen($hex) - 6, $start = strlen($hex) % 6; $i >= $start; $i-=6) {
+ $bits = str_pad(decbin(hexdec(substr($hex, $i, 6))), 24, '0', STR_PAD_LEFT) . $bits;
}
if ($start) { // hexdec('') == 0
- $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8, '0', STR_PAD_LEFT) . $bits;
+ $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8 * $start, '0', STR_PAD_LEFT) . $bits;
}
$result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0');
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
index 8ae43fa04..1e6fba9fc 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
@@ -270,6 +270,16 @@ class SFTP extends SSH2
var $preserveTime = false;
/**
+ * Was the last packet due to the channels being closed or not?
+ *
+ * @see self::get()
+ * @see self::get_sftp_packet()
+ * @var bool
+ * @access private
+ */
+ var $channel_close = false;
+
+ /**
* Default Constructor.
*
* Connects to an SFTP server
@@ -425,6 +435,17 @@ class SFTP extends SSH2
return false;
}
+ return $this->_init_sftp_connection();
+ }
+
+ /**
+ * (Re)initializes the SFTP channel
+ *
+ * @return bool
+ * @access private
+ */
+ function _init_sftp_connection()
+ {
$this->window_size_server_to_client[self::CHANNEL] = $this->window_size;
$packet = pack(
@@ -446,6 +467,8 @@ class SFTP extends SSH2
$response = $this->_get_channel_packet(self::CHANNEL, true);
if ($response === false) {
return false;
+ } elseif ($response === true && $this->isTimeout()) {
+ return false;
}
$packet = pack(
@@ -492,6 +515,8 @@ class SFTP extends SSH2
if ($response === false) {
return false;
}
+ } elseif ($response === true && $this->isTimeout()) {
+ return false;
}
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA;
@@ -1024,7 +1049,7 @@ class SFTP extends SSH2
uasort($contents, array(&$this, '_comparator'));
}
- return $raw ? $contents : array_keys($contents);
+ return $raw ? $contents : array_map('strval', array_keys($contents));
}
/**
@@ -2293,7 +2318,13 @@ class SFTP extends SSH2
if ($fclose_check) {
fclose($fp);
}
- user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS');
+ // maybe the file was successfully transferred, maybe it wasn't
+ if ($this->channel_close) {
+ $this->_init_sftp_connection();
+ return false;
+ } else {
+ user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS');
+ }
}
$response = null;
}
@@ -3004,9 +3035,17 @@ class SFTP extends SSH2
$packet_type = '-> ' . $this->packet_types[$type] .
' (' . round($stop - $start, 4) . 's)';
if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
- echo "<pre>\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n</pre>\r\n";
- flush();
- ob_flush();
+ switch (PHP_SAPI) {
+ case 'cli':
+ $start = $stop = "\r\n";
+ break;
+ default:
+ $start = '<pre>';
+ $stop = '</pre>';
+ }
+ echo $start . $this->_format_log(array($data), array($packet_type)) . $stop;
+ @flush();
+ @ob_flush();
} else {
$this->packet_type_log[] = $packet_type;
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
@@ -3047,6 +3086,8 @@ class SFTP extends SSH2
*/
function _get_sftp_packet($request_id = null)
{
+ $this->channel_close = false;
+
if (isset($request_id) && isset($this->requestBuffer[$request_id])) {
$this->packet_type = $this->requestBuffer[$request_id]['packet_type'];
$temp = $this->requestBuffer[$request_id]['packet'];
@@ -3063,11 +3104,17 @@ class SFTP extends SSH2
// SFTP packet length
while (strlen($this->packet_buffer) < 4) {
$temp = $this->_get_channel_packet(self::CHANNEL, true);
- if (is_bool($temp)) {
+ if ($temp === true) {
+ if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) {
+ $this->channel_close = true;
+ }
$this->packet_type = false;
$this->packet_buffer = '';
return false;
}
+ if ($temp === false) {
+ return false;
+ }
$this->packet_buffer.= $temp;
}
if (strlen($this->packet_buffer) < 4) {
@@ -3079,7 +3126,7 @@ class SFTP extends SSH2
// 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h
- if ($tempLength > 256 * 1024) {
+ if (!$this->use_request_id && $tempLength > 256 * 1024) {
user_error('Invalid SFTP packet size');
return false;
}
@@ -3113,9 +3160,17 @@ class SFTP extends SSH2
$packet_type = '<- ' . $this->packet_types[$this->packet_type] .
' (' . round($stop - $start, 4) . 's)';
if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
- echo "<pre>\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n</pre>\r\n";
- flush();
- ob_flush();
+ switch (PHP_SAPI) {
+ case 'cli':
+ $start = $stop = "\r\n";
+ break;
+ default:
+ $start = '<pre>';
+ $stop = '</pre>';
+ }
+ echo $start . $this->_format_log(array($packet), array($packet_type)) . $stop;
+ @flush();
+ @ob_flush();
} else {
$this->packet_type_log[] = $packet_type;
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
index 1a44b10a0..ec9e5841a 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
@@ -410,7 +410,7 @@ class Stream
{
switch ($whence) {
case SEEK_SET:
- if ($offset >= $this->size || $offset < 0) {
+ if ($offset < 0) {
return false;
}
break;
@@ -447,7 +447,9 @@ class Stream
// and https://github.com/php/php-src/blob/master/main/php_streams.h#L592
switch ($option) {
case 1: // PHP_STREAM_META_TOUCH
- return $this->sftp->touch($path, $var[0], $var[1]);
+ $time = isset($var[0]) ? $var[0] : null;
+ $atime = isset($var[1]) ? $var[1] : null;
+ return $this->sftp->touch($path, $time, $atime);
case 2: // PHP_STREAM_OWNER_NAME
case 3: // PHP_STREAM_GROUP_NAME
return false;
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
index e2571190b..e449d987a 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
@@ -971,6 +971,14 @@ class SSH2
var $auth = array();
/**
+ * The authentication methods that may productively continue authentication.
+ *
+ * @see https://tools.ietf.org/html/rfc4252#section-5.1
+ * @var array|null
+ */
+ private $auth_methods_to_continue = null;
+
+ /**
* Default Constructor.
*
* $host can either be a string, representing the host, or a stream resource.
@@ -1347,6 +1355,7 @@ class SSH2
function _key_exchange($kexinit_payload_server = false)
{
$preferred = $this->preferred;
+ $send_kex = true;
$kex_algorithms = isset($preferred['kex']) ?
$preferred['kex'] :
@@ -1430,7 +1439,7 @@ class SSH2
0
);
- if ($this->send_kex_first) {
+ if ($kexinit_payload_server === false) {
if (!$this->_send_binary_packet($kexinit_payload_client)) {
return false;
}
@@ -1446,6 +1455,8 @@ class SSH2
user_error('Expected SSH_MSG_KEXINIT');
return false;
}
+
+ $send_kex = false;
}
$response = $kexinit_payload_server;
@@ -1518,7 +1529,7 @@ class SSH2
extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
$first_kex_packet_follows = $first_kex_packet_follows != 0;
- if (!$this->send_kex_first && !$this->_send_binary_packet($kexinit_payload_client)) {
+ if ($send_kex && !$this->_send_binary_packet($kexinit_payload_client)) {
return false;
}
@@ -2131,7 +2142,7 @@ class SSH2
// try logging with 'none' as an authentication method first since that's what
// PuTTY does
- if (substr($this->server_identifier, 0, 13) != 'SSH-2.0-CoreFTP') {
+ if (substr($this->server_identifier, 0, 13) != 'SSH-2.0-CoreFTP' && $this->auth_methods_to_continue === null) {
if ($this->_login($username)) {
return true;
}
@@ -2275,7 +2286,9 @@ class SSH2
case NET_SSH2_MSG_USERAUTH_SUCCESS:
$this->bitmap |= self::MASK_LOGIN;
return true;
- //case NET_SSH2_MSG_USERAUTH_FAILURE:
+ case NET_SSH2_MSG_USERAUTH_FAILURE:
+ extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
+ $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen));
default:
return false;
}
@@ -2347,6 +2360,7 @@ class SSH2
}
extract(unpack('Nlength', $this->_string_shift($response, 4)));
$auth_methods = explode(',', $this->_string_shift($response, $length));
+ $this->auth_methods_to_continue = $auth_methods;
if (!strlen($response)) {
return false;
}
@@ -2519,6 +2533,8 @@ class SSH2
case NET_SSH2_MSG_USERAUTH_SUCCESS:
return true;
case NET_SSH2_MSG_USERAUTH_FAILURE:
+ extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
+ $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen));
return false;
}
@@ -2627,13 +2643,21 @@ class SSH2
if (strlen($response) < 4) {
return false;
}
- extract(unpack('Nlength', $this->_string_shift($response, 4)));
- $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $this->_string_shift($response, $length);
+ extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
+ $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen));
+ $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE';
return false;
case NET_SSH2_MSG_USERAUTH_PK_OK:
// we'll just take it on faith that the public key blob and the public key algorithm name are as
// they should be
$this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK');
+ break;
+ case NET_SSH2_MSG_USERAUTH_SUCCESS:
+ $this->bitmap |= self::MASK_LOGIN;
+ return true;
+ default:
+ user_error('Unexpected response to publickey authentication pt 1');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
$packet = $part1 . chr(1) . $part2;
@@ -2662,13 +2686,16 @@ class SSH2
switch ($type) {
case NET_SSH2_MSG_USERAUTH_FAILURE:
// either the login is bad or the server employs multi-factor authentication
+ extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
+ $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen));
return false;
case NET_SSH2_MSG_USERAUTH_SUCCESS:
$this->bitmap |= self::MASK_LOGIN;
return true;
}
- return false;
+ user_error('Unexpected response to publickey authentication pt 2');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
/**
@@ -2690,7 +2717,7 @@ class SSH2
*
* Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number.
*
- * @param mixed $timeout
+ * @param int $interval
* @access public
*/
function setKeepAlive($interval)
@@ -2927,28 +2954,6 @@ class SSH2
return false;
}
- $response = $this->_get_binary_packet();
- if ($response === false) {
- $this->bitmap = 0;
- user_error('Connection closed by server');
- return false;
- }
-
- if (!strlen($response)) {
- return false;
- }
- list(, $type) = unpack('C', $this->_string_shift($response, 1));
-
- switch ($type) {
- case NET_SSH2_MSG_CHANNEL_SUCCESS:
- // if a pty can't be opened maybe commands can still be executed
- case NET_SSH2_MSG_CHANNEL_FAILURE:
- break;
- default:
- user_error('Unable to request pseudo-terminal');
- return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
- }
-
$packet = pack(
'CNNa*C',
NET_SSH2_MSG_CHANNEL_REQUEST,
@@ -2961,14 +2966,7 @@ class SSH2
return false;
}
- $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST;
-
- $response = $this->_get_channel_packet(self::CHANNEL_SHELL);
- if ($response === false) {
- return false;
- }
-
- $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA;
+ $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_IGNORE;
$this->bitmap |= self::MASK_SHELL;
@@ -3340,7 +3338,7 @@ class SSH2
$read = array($this->fsock);
$write = $except = null;
- if ($this->curTimeout <= 0) {
+ if (!$this->curTimeout) {
if ($this->keepAlive <= 0) {
@stream_select($read, $write, $except, null);
} else {
@@ -3534,6 +3532,10 @@ class SSH2
// only called when we've already logged in
if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
+ if (is_bool($payload)) {
+ return $payload;
+ }
+
switch (ord($payload[0])) {
case NET_SSH2_MSG_CHANNEL_REQUEST:
if (strlen($payload) == 31) {
@@ -3897,6 +3899,16 @@ class SSH2
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
break;
+ case NET_SSH2_MSG_IGNORE:
+ switch ($type) {
+ case NET_SSH2_MSG_CHANNEL_SUCCESS:
+ //$this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_DATA;
+ continue 3;
+ case NET_SSH2_MSG_CHANNEL_FAILURE:
+ user_error('Error opening channel');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ }
+ break;
case NET_SSH2_MSG_CHANNEL_REQUEST:
switch ($type) {
case NET_SSH2_MSG_CHANNEL_SUCCESS:
@@ -3916,6 +3928,10 @@ class SSH2
switch ($type) {
case NET_SSH2_MSG_CHANNEL_DATA:
+ //if ($this->channel_status[$channel] == NET_SSH2_MSG_IGNORE) {
+ // $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_DATA;
+ //}
+
/*
if ($channel == self::CHANNEL_EXEC) {
// SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server
@@ -5150,4 +5166,15 @@ class SSH2
);
}
}
+
+ /**
+ * Return the list of authentication methods that may productively continue authentication.
+ *
+ * @see https://tools.ietf.org/html/rfc4252#section-5.1
+ * @return array|null
+ */
+ public function getAuthMethodsToContinue()
+ {
+ return $this->auth_methods_to_continue;
+ }
}