Merge branch '3.0-logging-enhancements' into 3.0

This commit is contained in:
terrafrost 2022-08-16 19:19:40 -05:00
commit e78edac015
2 changed files with 116 additions and 59 deletions

View File

@ -203,6 +203,39 @@ class SFTP extends SSH2
*/ */
private $packet_log = []; private $packet_log = [];
/**
* Real-time log file pointer
*
* @see self::_append_log()
* @var resource|closed-resource
*/
private $realtime_log_file;
/**
* Real-time log file size
*
* @see self::_append_log()
* @var int
*/
private $realtime_log_size;
/**
* Real-time log file wrap boolean
*
* @see self::_append_log()
* @var bool
*/
private $realtime_log_wrap;
/**
* Current log size
*
* Should never exceed self::LOG_MAX_SIZE
*
* @var int
*/
private $log_size;
/** /**
* Error information * Error information
* *
@ -3222,24 +3255,7 @@ class SFTP extends SSH2
if (defined('NET_SFTP_LOGGING')) { if (defined('NET_SFTP_LOGGING')) {
$packet_type = '-> ' . $this->packet_types[$type] . $packet_type = '-> ' . $this->packet_types[$type] .
' (' . round($stop - $start, 4) . 's)'; ' (' . round($stop - $start, 4) . 's)';
if (NET_SFTP_LOGGING == self::LOG_REALTIME) { $this->append_log($packet_type, $data);
switch (PHP_SAPI) {
case 'cli':
$start = $stop = "\r\n";
break;
default:
$start = '<pre>';
$stop = '</pre>';
}
echo $start . $this->format_log([$data], [$packet_type]) . $stop;
@flush();
@ob_flush();
} else {
$this->packet_type_log[] = $packet_type;
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
$this->packet_log[] = $data;
}
}
} }
} }
@ -3343,24 +3359,7 @@ class SFTP extends SSH2
if (defined('NET_SFTP_LOGGING')) { if (defined('NET_SFTP_LOGGING')) {
$packet_type = '<- ' . $this->packet_types[$this->packet_type] . $packet_type = '<- ' . $this->packet_types[$this->packet_type] .
' (' . round($stop - $start, 4) . 's)'; ' (' . round($stop - $start, 4) . 's)';
if (NET_SFTP_LOGGING == self::LOG_REALTIME) { $this->append_log($packet_type, $packet);
switch (PHP_SAPI) {
case 'cli':
$start = $stop = "\r\n";
break;
default:
$start = '<pre>';
$stop = '</pre>';
}
echo $start . $this->format_log([$packet], [$packet_type]) . $stop;
@flush();
@ob_flush();
} else {
$this->packet_type_log[] = $packet_type;
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
$this->packet_log[] = $packet;
}
}
} }
if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) { if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) {
@ -3374,6 +3373,29 @@ class SFTP extends SSH2
return $packet; return $packet;
} }
/**
* Logs data packets
*
* Makes sure that only the last 1MB worth of packets will be logged
*
* @param string $message_number
* @param string $message
*/
private function append_log($message_number, $message)
{
$this->append_log_helper(
NET_SFTP_LOGGING,
$message_number,
$message,
$this->packet_type_log,
$this->packet_log,
$this->log_size,
$this->realtime_log_file,
$this->realtime_log_wrap,
$this->realtime_log_size
);
}
/** /**
* Returns a log of the packets that have been sent and received. * Returns a log of the packets that have been sent and received.
* *

View File

@ -139,16 +139,16 @@ class SSH2
const LOG_COMPLEX = 2; const LOG_COMPLEX = 2;
/** /**
* Outputs the content real-time * Outputs the content real-time
*
* @see \phpseclib3\Net\SSH2::getLog()
*/ */
const LOG_REALTIME = 3; const LOG_REALTIME = 3;
/** /**
* Dumps the content real-time to a file * Dumps the content real-time to a file
*
* @see \phpseclib3\Net\SSH2::getLog()
*/ */
const LOG_REALTIME_FILE = 4; const LOG_REALTIME_FILE = 4;
/**
* Outputs the message numbers real-time
*/
const LOG_SIMPLE_REALTIME = 5;
/** /**
* Make sure that the log never gets larger than this * Make sure that the log never gets larger than this
* *
@ -792,6 +792,7 @@ class SSH2
* Real-time log file wrap boolean * Real-time log file wrap boolean
* *
* @see self::_append_log() * @see self::_append_log()
* @var bool
*/ */
private $realtime_log_wrap; private $realtime_log_wrap;
@ -4150,25 +4151,59 @@ class SSH2
* @param string $message * @param string $message
*/ */
private function append_log($message_number, $message) private function append_log($message_number, $message)
{
$this->append_log_helper(
NET_SSH2_LOGGING,
$message_number,
$message,
$this->message_number_log,
$this->message_log,
$this->log_size,
$this->realtime_log_file,
$this->realtime_log_wrap,
$this->realtime_log_size
);
}
/**
* Logs data packet helper
*
* @param int $constant
* @param string $message_number
* @param string $message
* @param array &$message_number_log
* @param array &$message_log
* @param int &$log_size
* @param resource &$realtime_log_file
* @param bool &$realtime_log_wrap
* @param int &$realtime_log_size
*/
protected function append_log_helper($constant, $message_number, $message, array &$message_number_log, array &$message_log, &$log_size, &$realtime_log_file, &$realtime_log_wrap, &$realtime_log_size)
{ {
// remove the byte identifying the message type from all but the first two messages (ie. the identification strings) // remove the byte identifying the message type from all but the first two messages (ie. the identification strings)
if (strlen($message_number) > 2) { if (strlen($message_number) > 2) {
Strings::shift($message); Strings::shift($message);
} }
switch (NET_SSH2_LOGGING) { switch ($constant) {
// useful for benchmarks // useful for benchmarks
case self::LOG_SIMPLE: case self::LOG_SIMPLE:
$this->message_number_log[] = $message_number; $message_number_log[] = $message_number;
break;
case self::LOG_SIMPLE_REALTIME:
echo $message_number;
echo PHP_SAPI == 'cli' ? "\r\n" : '<br>';
@flush();
@ob_flush();
break; break;
// the most useful log for SSH2 // the most useful log for SSH2
case self::LOG_COMPLEX: case self::LOG_COMPLEX:
$this->message_number_log[] = $message_number; $message_number_log[] = $message_number;
$this->log_size += strlen($message); $log_size += strlen($message);
$this->message_log[] = $message; $message_log[] = $message;
while ($this->log_size > self::LOG_MAX_SIZE) { while ($log_size > self::LOG_MAX_SIZE) {
$this->log_size -= strlen(array_shift($this->message_log)); $log_size -= strlen(array_shift($message_log));
array_shift($this->message_number_log); array_shift($message_number_log);
} }
break; break;
// dump the output out realtime; packets may be interspersed with non packets, // dump the output out realtime; packets may be interspersed with non packets,
@ -4192,28 +4227,28 @@ class SSH2
// the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily
// at the beginning of the file // at the beginning of the file
case self::LOG_REALTIME_FILE: case self::LOG_REALTIME_FILE:
if (!isset($this->realtime_log_file)) { if (!isset($realtime_log_file)) {
// PHP doesn't seem to like using constants in fopen() // PHP doesn't seem to like using constants in fopen()
$filename = NET_SSH2_LOG_REALTIME_FILENAME; $filename = NET_SSH2_LOG_REALTIME_FILENAME;
$fp = fopen($filename, 'w'); $fp = fopen($filename, 'w');
$this->realtime_log_file = $fp; $realtime_log_file = $fp;
} }
if (!is_resource($this->realtime_log_file)) { if (!is_resource($realtime_log_file)) {
break; break;
} }
$entry = $this->format_log([$message], [$message_number]); $entry = $this->format_log([$message], [$message_number]);
if ($this->realtime_log_wrap) { if ($realtime_log_wrap) {
$temp = "<<< START >>>\r\n"; $temp = "<<< START >>>\r\n";
$entry .= $temp; $entry .= $temp;
fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp)); fseek($realtime_log_file, ftell($realtime_log_file) - strlen($temp));
} }
$this->realtime_log_size += strlen($entry); $realtime_log_size += strlen($entry);
if ($this->realtime_log_size > self::LOG_MAX_SIZE) { if ($realtime_log_size > self::LOG_MAX_SIZE) {
fseek($this->realtime_log_file, 0); fseek($realtime_log_file, 0);
$this->realtime_log_size = strlen($entry); $realtime_log_size = strlen($entry);
$this->realtime_log_wrap = true; $realtime_log_wrap = true;
} }
fputs($this->realtime_log_file, $entry); fputs($realtime_log_file, $entry);
} }
} }