1
0
mirror of https://github.com/danog/phpseclib.git synced 2024-12-02 17:52:59 +01:00

SSH/SFTP: make message numbers / packet types static as well

This commit is contained in:
terrafrost 2023-03-23 12:38:39 -05:00
parent 9705cbbc26
commit b799abd1a0
2 changed files with 244 additions and 240 deletions

View File

@ -93,7 +93,7 @@ class SFTP extends SSH2
* @var array * @var array
* @access private * @access private
*/ */
private $packet_types = []; private static $packet_types = [];
/** /**
* Status Codes * Status Codes
@ -102,19 +102,19 @@ class SFTP extends SSH2
* @var array * @var array
* @access private * @access private
*/ */
private $status_codes = []; private static $status_codes = [];
/** @var array<int, string> */ /** @var array<int, string> */
private $attributes; private static $attributes;
/** @var array<int, string> */ /** @var array<int, string> */
private $open_flags; private static $open_flags;
/** @var array<int, string> */ /** @var array<int, string> */
private $open_flags5; private static $open_flags5;
/** @var array<int, string> */ /** @var array<int, string> */
private $file_types; private static $file_types;
/** /**
* The Request ID * The Request ID
@ -360,154 +360,156 @@ class SFTP extends SSH2
$this->max_sftp_packet = 1 << 15; $this->max_sftp_packet = 1 << 15;
$this->packet_types = [ if (empty(self::$packet_types)) {
1 => 'NET_SFTP_INIT', self::$packet_types = [
2 => 'NET_SFTP_VERSION', 1 => 'NET_SFTP_INIT',
3 => 'NET_SFTP_OPEN', 2 => 'NET_SFTP_VERSION',
4 => 'NET_SFTP_CLOSE', 3 => 'NET_SFTP_OPEN',
5 => 'NET_SFTP_READ', 4 => 'NET_SFTP_CLOSE',
6 => 'NET_SFTP_WRITE', 5 => 'NET_SFTP_READ',
7 => 'NET_SFTP_LSTAT', 6 => 'NET_SFTP_WRITE',
9 => 'NET_SFTP_SETSTAT', 7 => 'NET_SFTP_LSTAT',
10 => 'NET_SFTP_FSETSTAT', 9 => 'NET_SFTP_SETSTAT',
11 => 'NET_SFTP_OPENDIR', 10 => 'NET_SFTP_FSETSTAT',
12 => 'NET_SFTP_READDIR', 11 => 'NET_SFTP_OPENDIR',
13 => 'NET_SFTP_REMOVE', 12 => 'NET_SFTP_READDIR',
14 => 'NET_SFTP_MKDIR', 13 => 'NET_SFTP_REMOVE',
15 => 'NET_SFTP_RMDIR', 14 => 'NET_SFTP_MKDIR',
16 => 'NET_SFTP_REALPATH', 15 => 'NET_SFTP_RMDIR',
17 => 'NET_SFTP_STAT', 16 => 'NET_SFTP_REALPATH',
18 => 'NET_SFTP_RENAME', 17 => 'NET_SFTP_STAT',
19 => 'NET_SFTP_READLINK', 18 => 'NET_SFTP_RENAME',
20 => 'NET_SFTP_SYMLINK', 19 => 'NET_SFTP_READLINK',
21 => 'NET_SFTP_LINK', 20 => 'NET_SFTP_SYMLINK',
21 => 'NET_SFTP_LINK',
101 => 'NET_SFTP_STATUS', 101 => 'NET_SFTP_STATUS',
102 => 'NET_SFTP_HANDLE', 102 => 'NET_SFTP_HANDLE',
103 => 'NET_SFTP_DATA', 103 => 'NET_SFTP_DATA',
104 => 'NET_SFTP_NAME', 104 => 'NET_SFTP_NAME',
105 => 'NET_SFTP_ATTRS', 105 => 'NET_SFTP_ATTRS',
200 => 'NET_SFTP_EXTENDED' 200 => 'NET_SFTP_EXTENDED'
]; ];
$this->status_codes = [ self::$status_codes = [
0 => 'NET_SFTP_STATUS_OK', 0 => 'NET_SFTP_STATUS_OK',
1 => 'NET_SFTP_STATUS_EOF', 1 => 'NET_SFTP_STATUS_EOF',
2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE',
3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED',
4 => 'NET_SFTP_STATUS_FAILURE', 4 => 'NET_SFTP_STATUS_FAILURE',
5 => 'NET_SFTP_STATUS_BAD_MESSAGE', 5 => 'NET_SFTP_STATUS_BAD_MESSAGE',
6 => 'NET_SFTP_STATUS_NO_CONNECTION', 6 => 'NET_SFTP_STATUS_NO_CONNECTION',
7 => 'NET_SFTP_STATUS_CONNECTION_LOST', 7 => 'NET_SFTP_STATUS_CONNECTION_LOST',
8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED',
9 => 'NET_SFTP_STATUS_INVALID_HANDLE', 9 => 'NET_SFTP_STATUS_INVALID_HANDLE',
10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH',
11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS',
12 => 'NET_SFTP_STATUS_WRITE_PROTECT', 12 => 'NET_SFTP_STATUS_WRITE_PROTECT',
13 => 'NET_SFTP_STATUS_NO_MEDIA', 13 => 'NET_SFTP_STATUS_NO_MEDIA',
14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM',
15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED',
16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL',
17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT',
18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY',
19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY',
20 => 'NET_SFTP_STATUS_INVALID_FILENAME', 20 => 'NET_SFTP_STATUS_INVALID_FILENAME',
21 => 'NET_SFTP_STATUS_LINK_LOOP', 21 => 'NET_SFTP_STATUS_LINK_LOOP',
22 => 'NET_SFTP_STATUS_CANNOT_DELETE', 22 => 'NET_SFTP_STATUS_CANNOT_DELETE',
23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER',
24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY',
25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT',
26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED',
27 => 'NET_SFTP_STATUS_DELETE_PENDING', 27 => 'NET_SFTP_STATUS_DELETE_PENDING',
28 => 'NET_SFTP_STATUS_FILE_CORRUPT', 28 => 'NET_SFTP_STATUS_FILE_CORRUPT',
29 => 'NET_SFTP_STATUS_OWNER_INVALID', 29 => 'NET_SFTP_STATUS_OWNER_INVALID',
30 => 'NET_SFTP_STATUS_GROUP_INVALID', 30 => 'NET_SFTP_STATUS_GROUP_INVALID',
31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK'
]; ];
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
// the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why
$this->attributes = [ self::$attributes = [
0x00000001 => 'NET_SFTP_ATTR_SIZE', 0x00000001 => 'NET_SFTP_ATTR_SIZE',
0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+
0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+ 0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+
0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS',
0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME',
0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+ 0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+
0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME', 0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME',
0x00000040 => 'NET_SFTP_ATTR_ACL', 0x00000040 => 'NET_SFTP_ATTR_ACL',
0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES', 0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES',
0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+ 0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+
0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+ 0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+
0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT', 0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT',
0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE', 0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE',
0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT', 0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT',
0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME', 0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME',
0x00008000 => 'NET_SFTP_ATTR_CTIME', 0x00008000 => 'NET_SFTP_ATTR_CTIME',
// 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers
// yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
// two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
// that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
(PHP_INT_SIZE == 4 ? -1 : 0xFFFFFFFF) => 'NET_SFTP_ATTR_EXTENDED' (PHP_INT_SIZE == 4 ? -1 : 0xFFFFFFFF) => 'NET_SFTP_ATTR_EXTENDED'
]; ];
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
// the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
// the array for that $this->open5_flags and similarly alter the constant names. // the array for that $this->open5_flags and similarly alter the constant names.
$this->open_flags = [ self::$open_flags = [
0x00000001 => 'NET_SFTP_OPEN_READ', 0x00000001 => 'NET_SFTP_OPEN_READ',
0x00000002 => 'NET_SFTP_OPEN_WRITE', 0x00000002 => 'NET_SFTP_OPEN_WRITE',
0x00000004 => 'NET_SFTP_OPEN_APPEND', 0x00000004 => 'NET_SFTP_OPEN_APPEND',
0x00000008 => 'NET_SFTP_OPEN_CREATE', 0x00000008 => 'NET_SFTP_OPEN_CREATE',
0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE',
0x00000020 => 'NET_SFTP_OPEN_EXCL', 0x00000020 => 'NET_SFTP_OPEN_EXCL',
0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4 0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4
]; ];
// SFTPv5+ changed the flags up: // SFTPv5+ changed the flags up:
// https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3 // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3
$this->open_flags5 = [ self::$open_flags5 = [
// when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened
0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW', 0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW',
0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE', 0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE',
0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING', 0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING',
0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE', 0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE',
0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING', 0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING',
// the rest of the flags are not supported // the rest of the flags are not supported
0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored" 0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored"
0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC', 0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC',
0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE', 0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE',
0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ', 0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ',
0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE', 0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE',
0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE', 0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE',
0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY', 0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY',
0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW', 0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW',
0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE', 0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE',
0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO', 0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO',
0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP', 0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP',
0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM', 0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM',
0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER', 0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER',
]; ];
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
// see \phpseclib3\Net\SFTP::_parseLongname() for an explanation // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation
$this->file_types = [ self::$file_types = [
1 => 'NET_SFTP_TYPE_REGULAR', 1 => 'NET_SFTP_TYPE_REGULAR',
2 => 'NET_SFTP_TYPE_DIRECTORY', 2 => 'NET_SFTP_TYPE_DIRECTORY',
3 => 'NET_SFTP_TYPE_SYMLINK', 3 => 'NET_SFTP_TYPE_SYMLINK',
4 => 'NET_SFTP_TYPE_SPECIAL', 4 => 'NET_SFTP_TYPE_SPECIAL',
5 => 'NET_SFTP_TYPE_UNKNOWN', 5 => 'NET_SFTP_TYPE_UNKNOWN',
// the following types were first defined for use in SFTPv5+ // the following types were first defined for use in SFTPv5+
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2
6 => 'NET_SFTP_TYPE_SOCKET', 6 => 'NET_SFTP_TYPE_SOCKET',
7 => 'NET_SFTP_TYPE_CHAR_DEVICE', 7 => 'NET_SFTP_TYPE_CHAR_DEVICE',
8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE',
9 => 'NET_SFTP_TYPE_FIFO' 9 => 'NET_SFTP_TYPE_FIFO'
]; ];
self::define_array( self::define_array(
$this->packet_types, self::$packet_types,
$this->status_codes, self::$status_codes,
$this->attributes, self::$attributes,
$this->open_flags, self::$open_flags,
$this->open_flags5, self::$open_flags5,
$this->file_types self::$file_types
); );
}
if (!defined('NET_SFTP_QUEUE_SIZE')) { if (!defined('NET_SFTP_QUEUE_SIZE')) {
define('NET_SFTP_QUEUE_SIZE', 32); define('NET_SFTP_QUEUE_SIZE', 32);
@ -815,7 +817,7 @@ class SFTP extends SSH2
list($status) = Strings::unpackSSH2('N', $response); list($status) = Strings::unpackSSH2('N', $response);
} }
$error = $this->status_codes[$status]; $error = self::$status_codes[$status];
if ($this->version > 2) { if ($this->version > 2) {
list($message) = Strings::unpackSSH2('s', $response); list($message) = Strings::unpackSSH2('s', $response);
@ -3041,7 +3043,7 @@ class SFTP extends SSH2
list($flags) = Strings::unpackSSH2('N', $response); list($flags) = Strings::unpackSSH2('N', $response);
} }
foreach ($this->attributes as $key => $value) { foreach (self::$attributes as $key => $value) {
switch ($flags & $key) { switch ($flags & $key) {
case NET_SFTP_ATTR_UIDGID: case NET_SFTP_ATTR_UIDGID:
if ($this->version > 3) { if ($this->version > 3) {
@ -3272,7 +3274,7 @@ class SFTP extends SSH2
$stop = microtime(true); $stop = microtime(true);
if (defined('NET_SFTP_LOGGING')) { if (defined('NET_SFTP_LOGGING')) {
$packet_type = '-> ' . $this->packet_types[$type] . $packet_type = '-> ' . self::$packet_types[$type] .
' (' . round($stop - $start, 4) . 's)'; ' (' . round($stop - $start, 4) . 's)';
$this->append_log($packet_type, $data); $this->append_log($packet_type, $data);
} }
@ -3376,7 +3378,7 @@ class SFTP extends SSH2
$packet = Strings::shift($this->packet_buffer, $length); $packet = Strings::shift($this->packet_buffer, $length);
if (defined('NET_SFTP_LOGGING')) { if (defined('NET_SFTP_LOGGING')) {
$packet_type = '<- ' . $this->packet_types[$this->packet_type] . $packet_type = '<- ' . self::$packet_types[$this->packet_type] .
' (' . round($stop - $start, 4) . 's)'; ' (' . round($stop - $start, 4) . 's)';
$this->append_log($packet_type, $packet); $this->append_log($packet_type, $packet);
} }

View File

@ -553,7 +553,7 @@ class SSH2
* @var array * @var array
* @access private * @access private
*/ */
private $message_numbers = []; private static $message_numbers = [];
/** /**
* Disconnection Message 'reason codes' defined in RFC4253 * Disconnection Message 'reason codes' defined in RFC4253
@ -562,7 +562,7 @@ class SSH2
* @var array * @var array
* @access private * @access private
*/ */
private $disconnect_reasons = []; private static $disconnect_reasons = [];
/** /**
* SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254
@ -571,7 +571,7 @@ class SSH2
* @var array * @var array
* @access private * @access private
*/ */
private $channel_open_failure_reasons = []; private static $channel_open_failure_reasons = [];
/** /**
* Terminal Modes * Terminal Modes
@ -581,7 +581,7 @@ class SSH2
* @var array * @var array
* @access private * @access private
*/ */
private $terminal_modes = []; private static $terminal_modes = [];
/** /**
* SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes
@ -591,7 +591,7 @@ class SSH2
* @var array * @var array
* @access private * @access private
*/ */
private $channel_extended_data_type_codes = []; private static $channel_extended_data_type_codes = [];
/** /**
* Send Sequence Number * Send Sequence Number
@ -1099,84 +1099,86 @@ class SSH2
*/ */
public function __construct($host, $port = 22, $timeout = 10) public function __construct($host, $port = 22, $timeout = 10)
{ {
$this->message_numbers = [ if (empty(self::$message_numbers)) {
1 => 'NET_SSH2_MSG_DISCONNECT', self::$message_numbers = [
2 => 'NET_SSH2_MSG_IGNORE', 1 => 'NET_SSH2_MSG_DISCONNECT',
3 => 'NET_SSH2_MSG_UNIMPLEMENTED', 2 => 'NET_SSH2_MSG_IGNORE',
4 => 'NET_SSH2_MSG_DEBUG', 3 => 'NET_SSH2_MSG_UNIMPLEMENTED',
5 => 'NET_SSH2_MSG_SERVICE_REQUEST', 4 => 'NET_SSH2_MSG_DEBUG',
6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', 5 => 'NET_SSH2_MSG_SERVICE_REQUEST',
20 => 'NET_SSH2_MSG_KEXINIT', 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT',
21 => 'NET_SSH2_MSG_NEWKEYS', 20 => 'NET_SSH2_MSG_KEXINIT',
30 => 'NET_SSH2_MSG_KEXDH_INIT', 21 => 'NET_SSH2_MSG_NEWKEYS',
31 => 'NET_SSH2_MSG_KEXDH_REPLY', 30 => 'NET_SSH2_MSG_KEXDH_INIT',
50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', 31 => 'NET_SSH2_MSG_KEXDH_REPLY',
51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST',
52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE',
53 => 'NET_SSH2_MSG_USERAUTH_BANNER', 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS',
53 => 'NET_SSH2_MSG_USERAUTH_BANNER',
80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST',
81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS',
82 => 'NET_SSH2_MSG_REQUEST_FAILURE', 82 => 'NET_SSH2_MSG_REQUEST_FAILURE',
90 => 'NET_SSH2_MSG_CHANNEL_OPEN', 90 => 'NET_SSH2_MSG_CHANNEL_OPEN',
91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION',
92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE',
93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST',
94 => 'NET_SSH2_MSG_CHANNEL_DATA', 94 => 'NET_SSH2_MSG_CHANNEL_DATA',
95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA',
96 => 'NET_SSH2_MSG_CHANNEL_EOF', 96 => 'NET_SSH2_MSG_CHANNEL_EOF',
97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE',
98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST',
99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS',
100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE'
]; ];
$this->disconnect_reasons = [ self::$disconnect_reasons = [
1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT',
2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR',
3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED',
4 => 'NET_SSH2_DISCONNECT_RESERVED', 4 => 'NET_SSH2_DISCONNECT_RESERVED',
5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR',
6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR',
7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE',
8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED',
9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE',
10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST',
11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION',
12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS',
13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER',
14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE',
15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME'
]; ];
$this->channel_open_failure_reasons = [ self::$channel_open_failure_reasons = [
1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED'
]; ];
$this->terminal_modes = [ self::$terminal_modes = [
0 => 'NET_SSH2_TTY_OP_END' 0 => 'NET_SSH2_TTY_OP_END'
]; ];
$this->channel_extended_data_type_codes = [ self::$channel_extended_data_type_codes = [
1 => 'NET_SSH2_EXTENDED_DATA_STDERR' 1 => 'NET_SSH2_EXTENDED_DATA_STDERR'
]; ];
self::define_array( self::define_array(
$this->message_numbers, self::$message_numbers,
$this->disconnect_reasons, self::$disconnect_reasons,
$this->channel_open_failure_reasons, self::$channel_open_failure_reasons,
$this->terminal_modes, self::$terminal_modes,
$this->channel_extended_data_type_codes, self::$channel_extended_data_type_codes,
[60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'],
[60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'],
[60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'],
// RFC 4419 - diffie-hellman-group-exchange-sha{1,256} // RFC 4419 - diffie-hellman-group-exchange-sha{1,256}
[30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD',
31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP',
32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT',
33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY',
34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'],
// RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org)
[30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT',
31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY']
); );
}
/** /**
* Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508 * Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508
@ -3600,7 +3602,7 @@ class SSH2
if (defined('NET_SSH2_LOGGING')) { if (defined('NET_SSH2_LOGGING')) {
$current = microtime(true); $current = microtime(true);
$message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; $message_number = isset(self::$message_numbers[ord($payload[0])]) ? self::$message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')';
$message_number = '<- ' . $message_number . $message_number = '<- ' . $message_number .
' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
$this->append_log($message_number, $payload); $this->append_log($message_number, $payload);
@ -3682,7 +3684,7 @@ class SSH2
case NET_SSH2_MSG_DISCONNECT: case NET_SSH2_MSG_DISCONNECT:
Strings::shift($payload, 1); Strings::shift($payload, 1);
list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload); list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload);
$this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n$message"; $this->errors[] = 'SSH_MSG_DISCONNECT: ' . static::$disconnect_reasons[$reason_code] . "\r\n$message";
$this->bitmap = 0; $this->bitmap = 0;
return false; return false;
case NET_SSH2_MSG_IGNORE: case NET_SSH2_MSG_IGNORE:
@ -4255,7 +4257,7 @@ class SSH2
if (defined('NET_SSH2_LOGGING')) { if (defined('NET_SSH2_LOGGING')) {
$current = microtime(true); $current = microtime(true);
$message_number = isset($this->message_numbers[ord($logged[0])]) ? $this->message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')'; $message_number = isset(self::$message_numbers[ord($logged[0])]) ? self::$message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')';
$message_number = '-> ' . $message_number . $message_number = '-> ' . $message_number .
' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
$this->append_log($message_number, $logged); $this->append_log($message_number, $logged);