mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-28 12:10:59 +00:00
Merge branch '3.0'
This commit is contained in:
commit
48259b20b3
@ -158,9 +158,9 @@ abstract class Strings
|
||||
/**
|
||||
* Create SSH2-style string
|
||||
*
|
||||
* @param string[] ...$elements
|
||||
* @param string|int|float|array|bool ...$elements
|
||||
* @access public
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public static function packSSH2(...$elements)
|
||||
{
|
||||
|
@ -123,6 +123,12 @@ abstract class AsymmetricKey
|
||||
*/
|
||||
private $comment;
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
abstract public function toString($type, array $options = []);
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
@ -245,7 +251,7 @@ abstract class AsymmetricKey
|
||||
* @param string $type
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return AsymmetricKey
|
||||
* @return static
|
||||
*/
|
||||
public static function loadFormat($type, $key, $password = false)
|
||||
{
|
||||
|
@ -213,6 +213,13 @@ abstract class SymmetricKey
|
||||
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
|
||||
*
|
||||
@ -3412,4 +3419,4 @@ abstract class SymmetricKey
|
||||
{
|
||||
return array_flip(self::MODE_MAP)[$this->mode];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ abstract class DH extends AsymmetricKey
|
||||
* - a string (eg. diffie-hellman-group14-sha1)
|
||||
*
|
||||
* @access public
|
||||
* @return \phpseclib3\Crypt\DH|bool
|
||||
* @return Parameters
|
||||
*/
|
||||
public static function createParameters(...$args)
|
||||
{
|
||||
@ -397,4 +397,4 @@ abstract class DH extends AsymmetricKey
|
||||
$key = $type::saveParameters($this->prime, $this->base);
|
||||
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.
|
||||
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,
|
||||
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:
|
||||
// FIPS 186-3 changed this as follows:
|
||||
@ -341,4 +341,4 @@ abstract class DSA extends AsymmetricKey
|
||||
{
|
||||
return $this->shortFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,11 @@ class Hash
|
||||
*/
|
||||
const PADDING_SHAKE = 3;
|
||||
|
||||
/** @var int|false */
|
||||
public $etm;
|
||||
/** @var string|false */
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Padding Type
|
||||
*
|
||||
|
@ -51,7 +51,7 @@ abstract class Random
|
||||
}
|
||||
|
||||
try {
|
||||
return \random_bytes($length);
|
||||
return random_bytes($length);
|
||||
} catch (\Exception $e) {
|
||||
// random_compat will throw an Exception, which in PHP 5 does not implement Throwable
|
||||
} catch (\Throwable $e) {
|
||||
|
@ -116,6 +116,18 @@ class SFTP extends SSH2
|
||||
*/
|
||||
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
|
||||
*
|
||||
@ -188,7 +200,7 @@ class SFTP extends SSH2
|
||||
/**
|
||||
* Current working directory
|
||||
*
|
||||
* @var string
|
||||
* @var string|bool
|
||||
* @see self::realpath()
|
||||
* @see self::chdir()
|
||||
* @access private
|
||||
@ -242,7 +254,7 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @see self::__construct()
|
||||
* @see self::get()
|
||||
* @var array
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
private $max_sftp_packet;
|
||||
@ -781,7 +793,7 @@ class SFTP extends SSH2
|
||||
/**
|
||||
* Returns the current directory name
|
||||
*
|
||||
* @return string|false
|
||||
* @return string|bool
|
||||
* @access public
|
||||
*/
|
||||
public function pwd()
|
||||
@ -1226,7 +1238,7 @@ class SFTP extends SSH2
|
||||
* $sftp->setListOrder();
|
||||
* Don't do any sort of sorting
|
||||
*
|
||||
* @param string[] ...$args
|
||||
* @param string ...$args
|
||||
* @access public
|
||||
*/
|
||||
public function setListOrder(...$args)
|
||||
@ -1809,7 +1821,7 @@ class SFTP extends SSH2
|
||||
$packet = Strings::packSSH2('s', $path);
|
||||
$packet.= $this->version >= 4 ?
|
||||
pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) :
|
||||
$atr;
|
||||
$attr;
|
||||
$this->send_sftp_packet(NET_SFTP_SETSTAT, $packet);
|
||||
|
||||
$i++;
|
||||
@ -3131,7 +3143,7 @@ class SFTP extends SSH2
|
||||
// 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
|
||||
// usually be larger than the 'size' field
|
||||
list($attr['allocation-size']) = Strings::unpack('Q', $response);
|
||||
list($attr['allocation-size']) = Strings::unpackSSH2('Q', $response);
|
||||
break;
|
||||
case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800
|
||||
// https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10
|
||||
@ -3146,7 +3158,7 @@ class SFTP extends SSH2
|
||||
break;
|
||||
case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000
|
||||
// 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;
|
||||
case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000
|
||||
// see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13
|
||||
|
@ -204,7 +204,7 @@ class SSH2
|
||||
/**
|
||||
* The Socket Object
|
||||
*
|
||||
* @var object
|
||||
* @var resource|closed-resource|null
|
||||
* @access private
|
||||
*/
|
||||
public $fsock;
|
||||
@ -711,7 +711,7 @@ class SSH2
|
||||
* Interactive Buffer
|
||||
*
|
||||
* @see self::read()
|
||||
* @var array
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
private $interactiveBuffer = '';
|
||||
@ -756,7 +756,7 @@ class SSH2
|
||||
* Real-time log file pointer
|
||||
*
|
||||
* @see self::_append_log()
|
||||
* @var resource
|
||||
* @var resource|closed-resource
|
||||
* @access private
|
||||
*/
|
||||
private $realtime_log_file;
|
||||
@ -798,7 +798,7 @@ class SSH2
|
||||
/**
|
||||
* Time of first network activity
|
||||
*
|
||||
* @var int
|
||||
* @var float
|
||||
* @access private
|
||||
*/
|
||||
private $last_packet;
|
||||
@ -966,7 +966,7 @@ class SSH2
|
||||
/**
|
||||
* A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
|
||||
*
|
||||
* @var \phpseclib3\System\Ssh\Agent
|
||||
* @var Agent
|
||||
* @access private
|
||||
*/
|
||||
private $agent;
|
||||
@ -975,7 +975,7 @@ class SSH2
|
||||
* Connection storage to replicates ssh2 extension functionality:
|
||||
* {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
|
||||
*
|
||||
* @var SSH2[]
|
||||
* @var array<string, SSH2|\WeakReference<SSH2>>
|
||||
*/
|
||||
private static $connections;
|
||||
|
||||
@ -1063,7 +1063,7 @@ class SSH2
|
||||
/**
|
||||
* Decompression method
|
||||
*
|
||||
* @var resource|object
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
private $decompress = self::NET_SSH2_COMPRESSION_NONE;
|
||||
@ -1071,7 +1071,7 @@ class SSH2
|
||||
/**
|
||||
* Compression context
|
||||
*
|
||||
* @var int
|
||||
* @var resource|false|null
|
||||
* @access private
|
||||
*/
|
||||
private $compress_context;
|
||||
@ -1200,7 +1200,13 @@ class SSH2
|
||||
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)) {
|
||||
$this->fsock = $host;
|
||||
@ -1411,7 +1417,7 @@ class SSH2
|
||||
if (!$this->send_kex_first) {
|
||||
$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;
|
||||
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
||||
}
|
||||
@ -1546,7 +1552,11 @@ class SSH2
|
||||
|
||||
$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);
|
||||
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
||||
}
|
||||
@ -2159,7 +2169,7 @@ class SSH2
|
||||
* Login Helper
|
||||
*
|
||||
* @param string $username
|
||||
* @param string[] ...$args
|
||||
* @param string ...$args
|
||||
* @return bool
|
||||
* @see self::_login_helper()
|
||||
* @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.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string|array $password
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
@ -2425,7 +2435,7 @@ class SSH2
|
||||
/**
|
||||
* Handle the keyboard-interactive requests / responses.
|
||||
*
|
||||
* @param mixed[] ...$responses
|
||||
* @param string|array ...$responses
|
||||
* @return bool
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access private
|
||||
@ -2719,12 +2729,12 @@ class SSH2
|
||||
* In all likelihood, this is not a feature you want to be taking advantage of.
|
||||
*
|
||||
* @param string $command
|
||||
* @param callback $callback
|
||||
* @return string
|
||||
* @return string|bool
|
||||
* @psalm-return ($callback is callable ? bool : string|bool)
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
public function exec($command, $callback = null)
|
||||
public function exec($command, callable $callback = null)
|
||||
{
|
||||
$this->curTimeout = $this->timeout;
|
||||
$this->is_timeout = false;
|
||||
@ -3290,12 +3300,15 @@ class SSH2
|
||||
*
|
||||
* @see self::_send_binary_packet()
|
||||
* @param bool $skip_channel_filter
|
||||
* @return string
|
||||
* @return bool|string
|
||||
* @access private
|
||||
*/
|
||||
private function get_binary_packet($skip_channel_filter = false)
|
||||
{
|
||||
if ($skip_channel_filter) {
|
||||
if (!is_resource($this->fsock)) {
|
||||
throw new \InvalidArgumentException('fsock is not a resource.');
|
||||
}
|
||||
$read = [$this->fsock];
|
||||
$write = $except = null;
|
||||
|
||||
@ -3314,9 +3327,6 @@ class SSH2
|
||||
return true;
|
||||
}
|
||||
|
||||
$read = [$this->fsock];
|
||||
$write = $except = null;
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) {
|
||||
@ -3590,7 +3600,7 @@ class SSH2
|
||||
* @see self::_get_binary_packet()
|
||||
* @param string $payload
|
||||
* @param bool $skip_channel_filter
|
||||
* @return string
|
||||
* @return string|bool
|
||||
* @access private
|
||||
*/
|
||||
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
|
||||
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);
|
||||
list($this->banner_message) = Strings::unpackSSH2('s', $payload);
|
||||
$payload = $this->get_binary_packet();
|
||||
@ -3632,8 +3642,8 @@ class SSH2
|
||||
|
||||
// only called when we've already logged in
|
||||
if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
|
||||
if ($payload === true) {
|
||||
return true;
|
||||
if (is_bool($payload)) {
|
||||
return $payload;
|
||||
}
|
||||
|
||||
switch (ord($payload[0])) {
|
||||
@ -4364,7 +4374,7 @@ class SSH2
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
@ -5115,11 +5125,12 @@ class SSH2
|
||||
/**
|
||||
* Return all excising connections
|
||||
*
|
||||
* @return SSH2[]
|
||||
* @return array<string, SSH2>
|
||||
*/
|
||||
public static function getConnections()
|
||||
{
|
||||
if (!class_exists('WeakReference')) {
|
||||
/** @var array<string, SSH2> */
|
||||
return self::$connections;
|
||||
}
|
||||
$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