mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-29 04:23:34 +00:00
Merge branch '3.0'
This commit is contained in:
commit
48259b20b3
@ -158,9 +158,9 @@ abstract class Strings
|
|||||||
/**
|
/**
|
||||||
* Create SSH2-style string
|
* Create SSH2-style string
|
||||||
*
|
*
|
||||||
* @param string[] ...$elements
|
* @param string|int|float|array|bool ...$elements
|
||||||
* @access public
|
* @access public
|
||||||
* @return mixed
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function packSSH2(...$elements)
|
public static function packSSH2(...$elements)
|
||||||
{
|
{
|
||||||
|
@ -123,6 +123,12 @@ abstract class AsymmetricKey
|
|||||||
*/
|
*/
|
||||||
private $comment;
|
private $comment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $type
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract public function toString($type, array $options = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor
|
* The constructor
|
||||||
*/
|
*/
|
||||||
@ -245,7 +251,7 @@ abstract class AsymmetricKey
|
|||||||
* @param string $type
|
* @param string $type
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param string $password optional
|
* @param string $password optional
|
||||||
* @return AsymmetricKey
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function loadFormat($type, $key, $password = false)
|
public static function loadFormat($type, $key, $password = false)
|
||||||
{
|
{
|
||||||
|
@ -213,6 +213,13 @@ abstract class SymmetricKey
|
|||||||
self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)'
|
self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** @var string|null */
|
||||||
|
public $fixed;
|
||||||
|
/** @var string|null */
|
||||||
|
public $invocation_counter;
|
||||||
|
/** @var string|null */
|
||||||
|
public $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Encryption Mode
|
* The Encryption Mode
|
||||||
*
|
*
|
||||||
@ -3412,4 +3419,4 @@ abstract class SymmetricKey
|
|||||||
{
|
{
|
||||||
return array_flip(self::MODE_MAP)[$this->mode];
|
return array_flip(self::MODE_MAP)[$this->mode];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ abstract class DH extends AsymmetricKey
|
|||||||
* - a string (eg. diffie-hellman-group14-sha1)
|
* - a string (eg. diffie-hellman-group14-sha1)
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return \phpseclib3\Crypt\DH|bool
|
* @return Parameters
|
||||||
*/
|
*/
|
||||||
public static function createParameters(...$args)
|
public static function createParameters(...$args)
|
||||||
{
|
{
|
||||||
@ -397,4 +397,4 @@ abstract class DH extends AsymmetricKey
|
|||||||
$key = $type::saveParameters($this->prime, $this->base);
|
$key = $type::saveParameters($this->prime, $this->base);
|
||||||
return self::load($key, 'PKCS1');
|
return self::load($key, 'PKCS1');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ abstract class DSA extends AsymmetricKey
|
|||||||
SSH DSA implementations only support keys with an N of 160.
|
SSH DSA implementations only support keys with an N of 160.
|
||||||
puttygen let's you set the size of L (but not the size of N) and uses 2048 as the
|
puttygen let's you set the size of L (but not the size of N) and uses 2048 as the
|
||||||
default L value. that's not really compliant with any of the FIPS standards, however,
|
default L value. that's not really compliant with any of the FIPS standards, however,
|
||||||
for the purposes of maintaining compatibility with puttygen, we'll support it
|
for the purposes of maintaining compatibility with puttygen, we'll support it
|
||||||
*/
|
*/
|
||||||
//case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160:
|
//case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160:
|
||||||
// FIPS 186-3 changed this as follows:
|
// FIPS 186-3 changed this as follows:
|
||||||
@ -341,4 +341,4 @@ abstract class DSA extends AsymmetricKey
|
|||||||
{
|
{
|
||||||
return $this->shortFormat;
|
return $this->shortFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,11 @@ class Hash
|
|||||||
*/
|
*/
|
||||||
const PADDING_SHAKE = 3;
|
const PADDING_SHAKE = 3;
|
||||||
|
|
||||||
|
/** @var int|false */
|
||||||
|
public $etm;
|
||||||
|
/** @var string|false */
|
||||||
|
public $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Padding Type
|
* Padding Type
|
||||||
*
|
*
|
||||||
|
@ -51,7 +51,7 @@ abstract class Random
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return \random_bytes($length);
|
return random_bytes($length);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// random_compat will throw an Exception, which in PHP 5 does not implement Throwable
|
// random_compat will throw an Exception, which in PHP 5 does not implement Throwable
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
@ -116,6 +116,18 @@ class SFTP extends SSH2
|
|||||||
*/
|
*/
|
||||||
private $status_codes = [];
|
private $status_codes = [];
|
||||||
|
|
||||||
|
/** @var array<int, string> */
|
||||||
|
private $attributes;
|
||||||
|
|
||||||
|
/** @var array<int, string> */
|
||||||
|
private $open_flags;
|
||||||
|
|
||||||
|
/** @var array<int, string> */
|
||||||
|
private $open_flags5;
|
||||||
|
|
||||||
|
/** @var array<int, string> */
|
||||||
|
private $file_types;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Request ID
|
* The Request ID
|
||||||
*
|
*
|
||||||
@ -188,7 +200,7 @@ class SFTP extends SSH2
|
|||||||
/**
|
/**
|
||||||
* Current working directory
|
* Current working directory
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string|bool
|
||||||
* @see self::realpath()
|
* @see self::realpath()
|
||||||
* @see self::chdir()
|
* @see self::chdir()
|
||||||
* @access private
|
* @access private
|
||||||
@ -242,7 +254,7 @@ class SFTP extends SSH2
|
|||||||
*
|
*
|
||||||
* @see self::__construct()
|
* @see self::__construct()
|
||||||
* @see self::get()
|
* @see self::get()
|
||||||
* @var array
|
* @var int
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private $max_sftp_packet;
|
private $max_sftp_packet;
|
||||||
@ -781,7 +793,7 @@ class SFTP extends SSH2
|
|||||||
/**
|
/**
|
||||||
* Returns the current directory name
|
* Returns the current directory name
|
||||||
*
|
*
|
||||||
* @return string|false
|
* @return string|bool
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
public function pwd()
|
public function pwd()
|
||||||
@ -1226,7 +1238,7 @@ class SFTP extends SSH2
|
|||||||
* $sftp->setListOrder();
|
* $sftp->setListOrder();
|
||||||
* Don't do any sort of sorting
|
* Don't do any sort of sorting
|
||||||
*
|
*
|
||||||
* @param string[] ...$args
|
* @param string ...$args
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
public function setListOrder(...$args)
|
public function setListOrder(...$args)
|
||||||
@ -1809,7 +1821,7 @@ class SFTP extends SSH2
|
|||||||
$packet = Strings::packSSH2('s', $path);
|
$packet = Strings::packSSH2('s', $path);
|
||||||
$packet.= $this->version >= 4 ?
|
$packet.= $this->version >= 4 ?
|
||||||
pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) :
|
pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) :
|
||||||
$atr;
|
$attr;
|
||||||
$this->send_sftp_packet(NET_SFTP_SETSTAT, $packet);
|
$this->send_sftp_packet(NET_SFTP_SETSTAT, $packet);
|
||||||
|
|
||||||
$i++;
|
$i++;
|
||||||
@ -3131,7 +3143,7 @@ class SFTP extends SSH2
|
|||||||
// see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4
|
// see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4
|
||||||
// represents the number of bytes that the file consumes on the disk. will
|
// represents the number of bytes that the file consumes on the disk. will
|
||||||
// usually be larger than the 'size' field
|
// usually be larger than the 'size' field
|
||||||
list($attr['allocation-size']) = Strings::unpack('Q', $response);
|
list($attr['allocation-size']) = Strings::unpackSSH2('Q', $response);
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800
|
case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800
|
||||||
// https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10
|
// https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10
|
||||||
@ -3146,7 +3158,7 @@ class SFTP extends SSH2
|
|||||||
break;
|
break;
|
||||||
case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000
|
case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000
|
||||||
// see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12
|
// see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12
|
||||||
list($attr['link-count']) = Strings::unpackSS2('N', $response);
|
list($attr['link-count']) = Strings::unpackSSH2('N', $response);
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000
|
case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000
|
||||||
// see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13
|
// see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13
|
||||||
|
@ -204,7 +204,7 @@ class SSH2
|
|||||||
/**
|
/**
|
||||||
* The Socket Object
|
* The Socket Object
|
||||||
*
|
*
|
||||||
* @var object
|
* @var resource|closed-resource|null
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
public $fsock;
|
public $fsock;
|
||||||
@ -711,7 +711,7 @@ class SSH2
|
|||||||
* Interactive Buffer
|
* Interactive Buffer
|
||||||
*
|
*
|
||||||
* @see self::read()
|
* @see self::read()
|
||||||
* @var array
|
* @var string
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private $interactiveBuffer = '';
|
private $interactiveBuffer = '';
|
||||||
@ -756,7 +756,7 @@ class SSH2
|
|||||||
* Real-time log file pointer
|
* Real-time log file pointer
|
||||||
*
|
*
|
||||||
* @see self::_append_log()
|
* @see self::_append_log()
|
||||||
* @var resource
|
* @var resource|closed-resource
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private $realtime_log_file;
|
private $realtime_log_file;
|
||||||
@ -798,7 +798,7 @@ class SSH2
|
|||||||
/**
|
/**
|
||||||
* Time of first network activity
|
* Time of first network activity
|
||||||
*
|
*
|
||||||
* @var int
|
* @var float
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private $last_packet;
|
private $last_packet;
|
||||||
@ -966,7 +966,7 @@ class SSH2
|
|||||||
/**
|
/**
|
||||||
* A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
|
* A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
|
||||||
*
|
*
|
||||||
* @var \phpseclib3\System\Ssh\Agent
|
* @var Agent
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private $agent;
|
private $agent;
|
||||||
@ -975,7 +975,7 @@ class SSH2
|
|||||||
* Connection storage to replicates ssh2 extension functionality:
|
* Connection storage to replicates ssh2 extension functionality:
|
||||||
* {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
|
* {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
|
||||||
*
|
*
|
||||||
* @var SSH2[]
|
* @var array<string, SSH2|\WeakReference<SSH2>>
|
||||||
*/
|
*/
|
||||||
private static $connections;
|
private static $connections;
|
||||||
|
|
||||||
@ -1063,7 +1063,7 @@ class SSH2
|
|||||||
/**
|
/**
|
||||||
* Decompression method
|
* Decompression method
|
||||||
*
|
*
|
||||||
* @var resource|object
|
* @var int
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private $decompress = self::NET_SSH2_COMPRESSION_NONE;
|
private $decompress = self::NET_SSH2_COMPRESSION_NONE;
|
||||||
@ -1071,7 +1071,7 @@ class SSH2
|
|||||||
/**
|
/**
|
||||||
* Compression context
|
* Compression context
|
||||||
*
|
*
|
||||||
* @var int
|
* @var resource|false|null
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private $compress_context;
|
private $compress_context;
|
||||||
@ -1200,7 +1200,13 @@ class SSH2
|
|||||||
31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY']
|
31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY']
|
||||||
);
|
);
|
||||||
|
|
||||||
self::$connections[$this->getResourceId()] = class_exists('WeakReference') ? \WeakReference::create($this) : $this;
|
/**
|
||||||
|
* Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508
|
||||||
|
* @var \WeakReference<SSH2>|SSH2
|
||||||
|
*/
|
||||||
|
self::$connections[$this->getResourceId()] = class_exists('WeakReference')
|
||||||
|
? \WeakReference::create($this)
|
||||||
|
: $this;
|
||||||
|
|
||||||
if (is_resource($host)) {
|
if (is_resource($host)) {
|
||||||
$this->fsock = $host;
|
$this->fsock = $host;
|
||||||
@ -1411,7 +1417,7 @@ class SSH2
|
|||||||
if (!$this->send_kex_first) {
|
if (!$this->send_kex_first) {
|
||||||
$response = $this->get_binary_packet();
|
$response = $this->get_binary_packet();
|
||||||
|
|
||||||
if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
if (is_bool($response) || !strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
||||||
$this->bitmap = 0;
|
$this->bitmap = 0;
|
||||||
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
||||||
}
|
}
|
||||||
@ -1546,7 +1552,11 @@ class SSH2
|
|||||||
|
|
||||||
$kexinit_payload_server = $this->get_binary_packet();
|
$kexinit_payload_server = $this->get_binary_packet();
|
||||||
|
|
||||||
if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) {
|
if (
|
||||||
|
is_bool($kexinit_payload_server)
|
||||||
|
|| !strlen($kexinit_payload_server)
|
||||||
|
|| ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT
|
||||||
|
) {
|
||||||
$this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR);
|
$this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR);
|
||||||
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
||||||
}
|
}
|
||||||
@ -2159,7 +2169,7 @@ class SSH2
|
|||||||
* Login Helper
|
* Login Helper
|
||||||
*
|
*
|
||||||
* @param string $username
|
* @param string $username
|
||||||
* @param string[] ...$args
|
* @param string ...$args
|
||||||
* @return bool
|
* @return bool
|
||||||
* @see self::_login_helper()
|
* @see self::_login_helper()
|
||||||
* @access private
|
* @access private
|
||||||
@ -2402,7 +2412,7 @@ class SSH2
|
|||||||
* See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator.
|
* See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator.
|
||||||
*
|
*
|
||||||
* @param string $username
|
* @param string $username
|
||||||
* @param string $password
|
* @param string|array $password
|
||||||
* @return bool
|
* @return bool
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
@ -2425,7 +2435,7 @@ class SSH2
|
|||||||
/**
|
/**
|
||||||
* Handle the keyboard-interactive requests / responses.
|
* Handle the keyboard-interactive requests / responses.
|
||||||
*
|
*
|
||||||
* @param mixed[] ...$responses
|
* @param string|array ...$responses
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws \RuntimeException on connection error
|
* @throws \RuntimeException on connection error
|
||||||
* @access private
|
* @access private
|
||||||
@ -2719,12 +2729,12 @@ class SSH2
|
|||||||
* In all likelihood, this is not a feature you want to be taking advantage of.
|
* In all likelihood, this is not a feature you want to be taking advantage of.
|
||||||
*
|
*
|
||||||
* @param string $command
|
* @param string $command
|
||||||
* @param callback $callback
|
* @return string|bool
|
||||||
* @return string
|
* @psalm-return ($callback is callable ? bool : string|bool)
|
||||||
* @throws \RuntimeException on connection error
|
* @throws \RuntimeException on connection error
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
public function exec($command, $callback = null)
|
public function exec($command, callable $callback = null)
|
||||||
{
|
{
|
||||||
$this->curTimeout = $this->timeout;
|
$this->curTimeout = $this->timeout;
|
||||||
$this->is_timeout = false;
|
$this->is_timeout = false;
|
||||||
@ -3290,12 +3300,15 @@ class SSH2
|
|||||||
*
|
*
|
||||||
* @see self::_send_binary_packet()
|
* @see self::_send_binary_packet()
|
||||||
* @param bool $skip_channel_filter
|
* @param bool $skip_channel_filter
|
||||||
* @return string
|
* @return bool|string
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private function get_binary_packet($skip_channel_filter = false)
|
private function get_binary_packet($skip_channel_filter = false)
|
||||||
{
|
{
|
||||||
if ($skip_channel_filter) {
|
if ($skip_channel_filter) {
|
||||||
|
if (!is_resource($this->fsock)) {
|
||||||
|
throw new \InvalidArgumentException('fsock is not a resource.');
|
||||||
|
}
|
||||||
$read = [$this->fsock];
|
$read = [$this->fsock];
|
||||||
$write = $except = null;
|
$write = $except = null;
|
||||||
|
|
||||||
@ -3314,9 +3327,6 @@ class SSH2
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$read = [$this->fsock];
|
|
||||||
$write = $except = null;
|
|
||||||
|
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
|
|
||||||
if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) {
|
if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) {
|
||||||
@ -3590,7 +3600,7 @@ class SSH2
|
|||||||
* @see self::_get_binary_packet()
|
* @see self::_get_binary_packet()
|
||||||
* @param string $payload
|
* @param string $payload
|
||||||
* @param bool $skip_channel_filter
|
* @param bool $skip_channel_filter
|
||||||
* @return string
|
* @return string|bool
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
private function filter($payload, $skip_channel_filter)
|
private function filter($payload, $skip_channel_filter)
|
||||||
@ -3624,7 +3634,7 @@ class SSH2
|
|||||||
}
|
}
|
||||||
|
|
||||||
// see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
|
// see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
|
||||||
if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
|
if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && !is_bool($payload) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
|
||||||
Strings::shift($payload, 1);
|
Strings::shift($payload, 1);
|
||||||
list($this->banner_message) = Strings::unpackSSH2('s', $payload);
|
list($this->banner_message) = Strings::unpackSSH2('s', $payload);
|
||||||
$payload = $this->get_binary_packet();
|
$payload = $this->get_binary_packet();
|
||||||
@ -3632,8 +3642,8 @@ class SSH2
|
|||||||
|
|
||||||
// only called when we've already logged in
|
// only called when we've already logged in
|
||||||
if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
|
if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
|
||||||
if ($payload === true) {
|
if (is_bool($payload)) {
|
||||||
return true;
|
return $payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ord($payload[0])) {
|
switch (ord($payload[0])) {
|
||||||
@ -4364,7 +4374,7 @@ class SSH2
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->bitmap = 0;
|
$this->bitmap = 0;
|
||||||
if (is_resource($this->fsock) && get_resource_type($this->fsock) == 'stream') {
|
if (is_resource($this->fsock) && get_resource_type($this->fsock) === 'stream') {
|
||||||
fclose($this->fsock);
|
fclose($this->fsock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5115,11 +5125,12 @@ class SSH2
|
|||||||
/**
|
/**
|
||||||
* Return all excising connections
|
* Return all excising connections
|
||||||
*
|
*
|
||||||
* @return SSH2[]
|
* @return array<string, SSH2>
|
||||||
*/
|
*/
|
||||||
public static function getConnections()
|
public static function getConnections()
|
||||||
{
|
{
|
||||||
if (!class_exists('WeakReference')) {
|
if (!class_exists('WeakReference')) {
|
||||||
|
/** @var array<string, SSH2> */
|
||||||
return self::$connections;
|
return self::$connections;
|
||||||
}
|
}
|
||||||
$temp = [];
|
$temp = [];
|
||||||
|
29
psalm.xml
Normal file
29
psalm.xml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
errorLevel="6"
|
||||||
|
resolveFromConfigFile="true"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="https://getpsalm.org/schema/config"
|
||||||
|
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||||
|
findUnusedPsalmSuppress="true"
|
||||||
|
sealAllMethods="true"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="phpseclib/Net"/>
|
||||||
|
</projectFiles>
|
||||||
|
<fileExtensions>
|
||||||
|
<extension name=".php"/>
|
||||||
|
</fileExtensions>
|
||||||
|
<issueHandlers>
|
||||||
|
<Trace>
|
||||||
|
<errorLevel type="error">
|
||||||
|
<directory name="."/>
|
||||||
|
</errorLevel>
|
||||||
|
</Trace>
|
||||||
|
<UndefinedConstant>
|
||||||
|
<errorLevel type="suppress">
|
||||||
|
<directory name="phpseclib/Net"/>
|
||||||
|
</errorLevel>
|
||||||
|
</UndefinedConstant>
|
||||||
|
</issueHandlers>
|
||||||
|
</psalm>
|
Loading…
Reference in New Issue
Block a user