Subversion Repositories oidplus

Compare Revisions

Regard whitespace Rev 1116 → Rev 1117

/trunk/includes/classes/OIDplus.class.php
1958,13 → 1958,17
const ENFORCE_SSL_NO = 0;
const ENFORCE_SSL_YES = 1;
const ENFORCE_SSL_AUTO = 2;
 
/**
* @var bool|null
*/
private static $sslAvailableCache = null;
 
/**
* @return bool|void|null
* @return bool
* @throws OIDplusException, OIDplusConfigInitializationException
*/
public static function isSslAvailable() {
public static function isSslAvailable(): bool {
if (!is_null(self::$sslAvailableCache)) return self::$sslAvailableCache;
 
if (PHP_SAPI == 'cli') {
2040,6 → 2044,9
return false;
}
}
} else {
assert(false);
return false;
}
}
}
/trunk/includes/classes/OIDplusSessionHandler.class.php
46,7 → 46,7
@ini_set('session.use_trans_sid', '0');
 
// Uses a secure connection (HTTPS) if possible
@ini_set('session.cookie_secure', OIDplus::isSslAvailable());
@ini_set('session.cookie_secure', OIDplus::isSslAvailable() ? '1' : '0');
 
$path = OIDplus::webpath(null,OIDplus::PATH_RELATIVE);
if (empty($path)) $path = '/';
/trunk/plugins/viathinksoft/database/oci/OIDplusQueryResultOci.class.php
147,7 → 147,7
// Oracle returns $ret['VALUE'] because unquoted column-names are always upper-case
// We can't quote every single column throughout the whole program, so we use this workaround...
if ($ret) {
foreach ($ret as $name => $val) { /* @phpstan-ignore-line */
foreach ($ret as $name => $val) {
$ret->{strtoupper($name)} = $val;
$ret->{strtolower($name)} = $val;
}
/trunk/vendor/composer/installed.json
774,12 → 774,12
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "abbc1ab7c794b6cbb7ddb2d94dfe85c02634f020"
"reference": "b799abd1a0c387590c2f58ee3e12a640412b6031"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/abbc1ab7c794b6cbb7ddb2d94dfe85c02634f020",
"reference": "abbc1ab7c794b6cbb7ddb2d94dfe85c02634f020",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/b799abd1a0c387590c2f58ee3e12a640412b6031",
"reference": "b799abd1a0c387590c2f58ee3e12a640412b6031",
"shasum": ""
},
"require": {
797,7 → 797,7
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
},
"time": "2023-03-15T02:43:29+00:00",
"time": "2023-03-23T18:04:07+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
/trunk/vendor/composer/installed.php
178,7 → 178,7
'phpseclib/phpseclib' => array(
'pretty_version' => '3.0.x-dev',
'version' => '3.0.9999999.9999999-dev',
'reference' => 'abbc1ab7c794b6cbb7ddb2d94dfe85c02634f020',
'reference' => 'b799abd1a0c387590c2f58ee3e12a640412b6031',
'type' => 'library',
'install_path' => __DIR__ . '/../phpseclib/phpseclib',
'aliases' => array(),
/trunk/vendor/licenses
26,7 → 26,7
matthiasmullie/path-converter 1.1.3 MIT
paragonie/constant_time_encoding v2.6.3 MIT
paragonie/random_compat v9.99.100 MIT
phpseclib/phpseclib 3.0.x-dev abbc1ab MIT
phpseclib/phpseclib 3.0.x-dev b799abd MIT
script47/bs5-utils master master MIT
spamspan/spamspan master GPL-2.0-only
symfony/polyfill-mbstring v1.19.0 MIT
/trunk/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
93,7 → 93,7
* @var array
* @access private
*/
private $packet_types = [];
private static $packet_types = [];
 
/**
* Status Codes
102,19 → 102,19
* @var array
* @access private
*/
private $status_codes = [];
private static $status_codes = [];
 
/** @var array<int, string> */
private $attributes;
private static $attributes;
 
/** @var array<int, string> */
private $open_flags;
private static $open_flags;
 
/** @var array<int, string> */
private $open_flags5;
private static $open_flags5;
 
/** @var array<int, string> */
private $file_types;
private static $file_types;
 
/**
* The Request ID
360,7 → 360,8
 
$this->max_sftp_packet = 1 << 15;
 
$this->packet_types = [
if (empty(self::$packet_types)) {
self::$packet_types = [
1 => 'NET_SFTP_INIT',
2 => 'NET_SFTP_VERSION',
3 => 'NET_SFTP_OPEN',
390,7 → 391,7
 
200 => 'NET_SFTP_EXTENDED'
];
$this->status_codes = [
self::$status_codes = [
0 => 'NET_SFTP_STATUS_OK',
1 => 'NET_SFTP_STATUS_EOF',
2 => 'NET_SFTP_STATUS_NO_SUCH_FILE',
426,7 → 427,7
];
// 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
$this->attributes = [
self::$attributes = [
0x00000001 => 'NET_SFTP_ATTR_SIZE',
0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+
0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+
452,7 → 453,7
// 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 array for that $this->open5_flags and similarly alter the constant names.
$this->open_flags = [
self::$open_flags = [
0x00000001 => 'NET_SFTP_OPEN_READ',
0x00000002 => 'NET_SFTP_OPEN_WRITE',
0x00000004 => 'NET_SFTP_OPEN_APPEND',
463,7 → 464,7
];
// SFTPv5+ changed the flags up:
// 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
0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW',
0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE',
487,7 → 488,7
];
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
// see \phpseclib3\Net\SFTP::_parseLongname() for an explanation
$this->file_types = [
self::$file_types = [
1 => 'NET_SFTP_TYPE_REGULAR',
2 => 'NET_SFTP_TYPE_DIRECTORY',
3 => 'NET_SFTP_TYPE_SYMLINK',
500,14 → 501,15
8 => 'NET_SFTP_TYPE_BLOCK_DEVICE',
9 => 'NET_SFTP_TYPE_FIFO'
];
$this->define_array(
$this->packet_types,
$this->status_codes,
$this->attributes,
$this->open_flags,
$this->open_flags5,
$this->file_types
self::define_array(
self::$packet_types,
self::$status_codes,
self::$attributes,
self::$open_flags,
self::$open_flags5,
self::$file_types
);
}
 
if (!defined('NET_SFTP_QUEUE_SIZE')) {
define('NET_SFTP_QUEUE_SIZE', 32);
815,7 → 817,7
list($status) = Strings::unpackSSH2('N', $response);
}
 
$error = $this->status_codes[$status];
$error = self::$status_codes[$status];
 
if ($this->version > 2) {
list($message) = Strings::unpackSSH2('s', $response);
3041,7 → 3043,7
list($flags) = Strings::unpackSSH2('N', $response);
}
 
foreach ($this->attributes as $key => $value) {
foreach (self::$attributes as $key => $value) {
switch ($flags & $key) {
case NET_SFTP_ATTR_UIDGID:
if ($this->version > 3) {
3272,7 → 3274,7
$stop = microtime(true);
 
if (defined('NET_SFTP_LOGGING')) {
$packet_type = '-> ' . $this->packet_types[$type] .
$packet_type = '-> ' . self::$packet_types[$type] .
' (' . round($stop - $start, 4) . 's)';
$this->append_log($packet_type, $data);
}
3376,7 → 3378,7
$packet = Strings::shift($this->packet_buffer, $length);
 
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)';
$this->append_log($packet_type, $packet);
}
/trunk/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
553,7 → 553,7
* @var array
* @access private
*/
private $message_numbers = [];
private static $message_numbers = [];
 
/**
* Disconnection Message 'reason codes' defined in RFC4253
562,7 → 562,7
* @var array
* @access private
*/
private $disconnect_reasons = [];
private static $disconnect_reasons = [];
 
/**
* SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254
571,7 → 571,7
* @var array
* @access private
*/
private $channel_open_failure_reasons = [];
private static $channel_open_failure_reasons = [];
 
/**
* Terminal Modes
581,7 → 581,7
* @var array
* @access private
*/
private $terminal_modes = [];
private static $terminal_modes = [];
 
/**
* SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes
591,7 → 591,7
* @var array
* @access private
*/
private $channel_extended_data_type_codes = [];
private static $channel_extended_data_type_codes = [];
 
/**
* Send Sequence Number
647,6 → 647,14
protected $channel_status = [];
 
/**
* The identifier of the interactive channel which was opened most recently
*
* @see self::getInteractiveChannelId()
* @var int
*/
private $channel_id_last_interactive = 0;
 
/**
* Packet Size
*
* Maximum packet size indexed by channel
838,20 → 846,6
private $request_pty = false;
 
/**
* Flag set while exec() is running when using enablePTY()
*
* @var bool
*/
private $in_request_pty_exec = false;
 
/**
* Flag set after startSubsystem() is called
*
* @var bool
*/
private $in_subsystem;
 
/**
* Contents of stdError
*
* @var string
1105,7 → 1099,8
*/
public function __construct($host, $port = 22, $timeout = 10)
{
$this->message_numbers = [
if (empty(self::$message_numbers)) {
self::$message_numbers = [
1 => 'NET_SSH2_MSG_DISCONNECT',
2 => 'NET_SSH2_MSG_IGNORE',
3 => 'NET_SSH2_MSG_UNIMPLEMENTED',
1136,7 → 1131,7
99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS',
100 => 'NET_SSH2_MSG_CHANNEL_FAILURE'
];
$this->disconnect_reasons = [
self::$disconnect_reasons = [
1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT',
2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR',
3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED',
1153,22 → 1148,22
14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE',
15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME'
];
$this->channel_open_failure_reasons = [
self::$channel_open_failure_reasons = [
1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED'
];
$this->terminal_modes = [
self::$terminal_modes = [
0 => 'NET_SSH2_TTY_OP_END'
];
$this->channel_extended_data_type_codes = [
self::$channel_extended_data_type_codes = [
1 => 'NET_SSH2_EXTENDED_DATA_STDERR'
];
 
$this->define_array(
$this->message_numbers,
$this->disconnect_reasons,
$this->channel_open_failure_reasons,
$this->terminal_modes,
$this->channel_extended_data_type_codes,
self::define_array(
self::$message_numbers,
self::$disconnect_reasons,
self::$channel_open_failure_reasons,
self::$terminal_modes,
self::$channel_extended_data_type_codes,
[60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'],
[60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'],
[60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
1183,6 → 1178,7
[30 => 'NET_SSH2_MSG_KEX_ECDH_INIT',
31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY']
);
}
 
/**
* Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508
2729,7 → 2725,7
return false;
}
 
if ($this->in_request_pty_exec) {
if ($this->isPTYOpen()) {
throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.');
}
 
2779,8 → 2775,6
$this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION);
throw new \RuntimeException('Unable to request pseudo-terminal');
}
 
$this->in_request_pty_exec = true;
}
 
// sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things
2810,7 → 2804,8
 
$this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA;
 
if ($this->in_request_pty_exec) {
if ($this->request_pty === true) {
$this->channel_id_last_interactive = self::CHANNEL_EXEC;
return true;
}
 
2838,18 → 2833,27
/**
* Creates an interactive shell
*
* Returns bool(true) if the shell was opened.
* Returns bool(false) if the shell was already open.
*
* @see self::isShellOpen()
* @see self::read()
* @see self::write()
* @return bool
* @throws InsufficientSetupException if not authenticated
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
*/
private function initShell()
public function openShell()
{
if ($this->in_request_pty_exec === true) {
return true;
if ($this->isShellOpen()) {
return false;
}
 
if (!$this->isAuthenticated()) {
throw new InsufficientSetupException('Operation disallowed prior to login()');
}
 
$this->window_size_server_to_client[self::CHANNEL_SHELL] = $this->window_size;
$packet_size = 0x4000;
 
2907,6 → 2911,8
 
$this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA;
 
$this->channel_id_last_interactive = self::CHANNEL_SHELL;
 
$this->bitmap |= self::MASK_SHELL;
 
return true;
2913,8 → 2919,10
}
 
/**
* Return the channel to be used with read() / write()
*
* Return the channel to be used with read(), write(), and reset(), if none were specified
* @deprecated for lack of transparency in intended channel target, to be potentially replaced
* with method which guarantees open-ness of all yielded channels and throws
* error for multiple open channels
* @see self::read()
* @see self::write()
* @return int
2922,9 → 2930,9
private function get_interactive_channel()
{
switch (true) {
case $this->in_subsystem:
case $this->is_channel_status_data(self::CHANNEL_SUBSYSTEM):
return self::CHANNEL_SUBSYSTEM;
case $this->in_request_pty_exec:
case $this->is_channel_status_data(self::CHANNEL_EXEC):
return self::CHANNEL_EXEC;
default:
return self::CHANNEL_SHELL;
2932,6 → 2940,17
}
 
/**
* Indicates the DATA status on the given channel
*
* @param int $channel The channel number to evaluate
* @return bool
*/
private function is_channel_status_data($channel)
{
return isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA;
}
 
/**
* Return an available open channel
*
* @return int
2987,27 → 3006,38
* Returns when there's a match for $expect, which can take the form of a string literal or,
* if $mode == self::READ_REGEX, a regular expression.
*
* If not specifying a channel, an open interactive channel will be selected, or, if there are
* no open channels, an interactive shell will be created. If there are multiple open
* interactive channels, a legacy behavior will apply in which channel selection prioritizes
* an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive
* channels, callers are discouraged from relying on this legacy behavior and should specify
* the intended channel.
*
* @see self::write()
* @param string $expect
* @param int $mode
* @param int $mode One of the self::READ_* constants
* @param int|null $channel Channel id returned by self::getInteractiveChannelId()
* @return string|bool|null
* @throws \RuntimeException on connection error
* @throws InsufficientSetupException on unexpected channel status, possibly due to closure
*/
public function read($expect = '', $mode = self::READ_SIMPLE)
public function read($expect = '', $mode = self::READ_SIMPLE, $channel = null)
{
$this->curTimeout = $this->timeout;
$this->is_timeout = false;
 
if (!$this->isAuthenticated()) {
throw new InsufficientSetupException('Operation disallowed prior to login()');
if ($channel === null) {
$channel = $this->get_interactive_channel();
}
 
if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) {
if (!$this->isInteractiveChannelOpen($channel)) {
if ($channel != self::CHANNEL_SHELL) {
throw new InsufficientSetupException('Data is not available on channel');
} elseif (!$this->openShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session');
}
}
 
$channel = $this->get_interactive_channel();
 
if ($mode == self::READ_NEXT) {
return $this->get_channel_packet($channel);
}
3024,7 → 3054,6
}
$response = $this->get_channel_packet($channel);
if ($response === true) {
$this->in_request_pty_exec = false;
return Strings::shift($this->interactiveBuffer, strlen($this->interactiveBuffer));
}
 
3035,22 → 3064,35
/**
* Inputs a command into an interactive shell.
*
* If not specifying a channel, an open interactive channel will be selected, or, if there are
* no open channels, an interactive shell will be created. If there are multiple open
* interactive channels, a legacy behavior will apply in which channel selection prioritizes
* an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive
* channels, callers are discouraged from relying on this legacy behavior and should specify
* the intended channel.
*
* @see SSH2::read()
* @param string $cmd
* @param int|null $channel Channel id returned by self::getInteractiveChannelId()
* @return void
* @throws \RuntimeException on connection error
* @throws InsufficientSetupException on unexpected channel status, possibly due to closure
*/
public function write($cmd)
public function write($cmd, $channel = null)
{
if (!$this->isAuthenticated()) {
throw new InsufficientSetupException('Operation disallowed prior to login()');
if ($channel === null) {
$channel = $this->get_interactive_channel();
}
 
if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) {
if (!$this->isInteractiveChannelOpen($channel)) {
if ($channel != self::CHANNEL_SHELL) {
throw new InsufficientSetupException('Data is not available on channel');
} elseif (!$this->openShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session');
}
}
 
$this->send_channel_packet($this->get_interactive_channel(), $cmd);
$this->send_channel_packet($channel, $cmd);
}
 
/**
3103,8 → 3145,7
 
$this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA;
 
$this->bitmap |= self::MASK_SHELL;
$this->in_subsystem = true;
$this->channel_id_last_interactive = self::CHANNEL_SUBSYSTEM;
 
return true;
}
3117,8 → 3158,9
*/
public function stopSubsystem()
{
$this->in_subsystem = false;
if ($this->isInteractiveChannelOpen(self::CHANNEL_SUBSYSTEM)) {
$this->close_channel(self::CHANNEL_SUBSYSTEM);
}
return true;
}
 
3127,11 → 3169,24
*
* If read() timed out you might want to just close the channel and have it auto-restart on the next read() call
*
* If not specifying a channel, an open interactive channel will be selected. If there are
* multiple open interactive channels, a legacy behavior will apply in which channel selection
* prioritizes an active subsystem, the exec pty, and, lastly, the shell. If using multiple
* interactive channels, callers are discouraged from relying on this legacy behavior and
* should specify the intended channel.
*
* @param int|null $channel Channel id returned by self::getInteractiveChannelId()
* @return void
*/
public function reset()
public function reset($channel = null)
{
$this->close_channel($this->get_interactive_channel());
if ($channel === null) {
$channel = $this->get_interactive_channel();
}
if ($this->isInteractiveChannelOpen($channel)) {
$this->close_channel($channel);
}
}
 
/**
* Is timeout?
3190,6 → 3245,49
}
 
/**
* Is the interactive shell active?
*
* @return bool
*/
public function isShellOpen()
{
return $this->isInteractiveChannelOpen(self::CHANNEL_SHELL);
}
 
/**
* Is the exec pty active?
*
* @return bool
*/
public function isPTYOpen()
{
return $this->isInteractiveChannelOpen(self::CHANNEL_EXEC);
}
 
/**
* Is the given interactive channel active?
*
* @param int $channel Channel id returned by self::getInteractiveChannelId()
* @return bool
*/
public function isInteractiveChannelOpen($channel)
{
return $this->isAuthenticated() && $this->is_channel_status_data($channel);
}
 
/**
* Returns a channel identifier, presently of the last interactive channel opened, regardless of current status.
* Returns 0 if no interactive channel has been opened.
*
* @see self::isInteractiveChannelOpen()
* @return int
*/
public function getInteractiveChannelId()
{
return $this->channel_id_last_interactive;
}
 
/**
* Pings a server connection, or tries to reconnect if the connection has gone down
*
* Inspired by http://php.net/manual/en/mysqli.ping.php
3504,7 → 3602,7
 
if (defined('NET_SSH2_LOGGING')) {
$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 .
' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
$this->append_log($message_number, $payload);
3586,7 → 3684,7
case NET_SSH2_MSG_DISCONNECT:
Strings::shift($payload, 1);
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;
return false;
case NET_SSH2_MSG_IGNORE:
3773,9 → 3871,8
*/
public function disablePTY()
{
if ($this->in_request_pty_exec) {
if ($this->isPTYOpen()) {
$this->close_channel(self::CHANNEL_EXEC);
$this->in_request_pty_exec = false;
}
$this->request_pty = false;
}
3801,6 → 3898,7
* - if the connection times out
* - if the channel status is CHANNEL_OPEN and the response was CHANNEL_OPEN_CONFIRMATION
* - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_SUCCESS
* - if the channel status is CHANNEL_CLOSE and the response was CHANNEL_CLOSE
*
* bool(false) is returned if:
*
3968,9 → 4066,12
throw new \RuntimeException('Unable to fulfill channel request');
}
case NET_SSH2_MSG_CHANNEL_CLOSE:
return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->get_channel_packet($client_channel, $skip_extended);
if ($client_channel == $channel && $type == NET_SSH2_MSG_CHANNEL_CLOSE) {
return true;
}
return $this->get_channel_packet($client_channel, $skip_extended);
}
}
 
// ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA
 
4003,9 → 4104,8
case NET_SSH2_MSG_CHANNEL_CLOSE:
$this->curTimeout = 5;
 
if ($this->bitmap & self::MASK_SHELL) {
$this->bitmap &= ~self::MASK_SHELL;
}
$this->close_channel_bitmap($channel);
 
if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) {
$this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
}
4157,7 → 4257,7
 
if (defined('NET_SSH2_LOGGING')) {
$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 .
' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
$this->append_log($message_number, $logged);
4348,18 → 4448,31
while (!is_bool($this->get_channel_packet($client_channel))) {
}
 
if ($this->is_timeout) {
$this->disconnect();
}
 
if ($want_reply) {
$this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
}
 
$this->close_channel_bitmap($client_channel);
}
 
/**
* Maintains execution state bitmap in response to channel closure
*
* @param int $client_channel The channel number to maintain closure status of
* @return void
*/
private function close_channel_bitmap($client_channel)
{
switch ($client_channel) {
case self::CHANNEL_SHELL:
// Shell status has been maintained in the bitmap for backwards
// compatibility sake, but can be removed going forward
if ($this->bitmap & self::MASK_SHELL) {
$this->bitmap &= ~self::MASK_SHELL;
}
break;
}
}
 
/**
* Disconnect
4395,7 → 4508,7
* @param mixed[] ...$args
* @access protected
*/
protected function define_array(...$args)
protected static function define_array(...$args)
{
foreach ($args as $arg) {
foreach ($arg as $key => $value) {