-
Notifications
You must be signed in to change notification settings - Fork 8k
Closed
Description
Description
The following code:
<?php
class SSH
{
protected $data = [
'host' => '',
'username' => '',
'password' => '',
'port' => 22,
'timeout' => 90,
];
private $_link;
private $_sftp;
private $_lastConnectionHash;
private $_lastLoginHash;
private $_currentConnectionHash;
private $_currentLoginHash;
public function __set($key, $value)
{
return $this->data[$key] = $value;
}
public function __get($key)
{
return $this->data[$key];
}
public function sftp()
{
if (!isset($this->_sftp) && !($this->_sftp = @ssh2_sftp($this->_link))) {
$this->ssherror($this->data);
}
}
public function disconnect()
{
if ($this->_sftp) {
@ssh2_disconnect($this->_sftp);
$this->_sftp = null;
unset($this->_sftp);
}
$test = @ssh2_disconnect($this->_link);
$this->_link = null;
unset($this->_link);
return $test;
}
public function __call($func, $args)
{
if (str_contains($func, 'scp')) {
$linker = $this->_link;
} elseif (str_contains($func, 'sftp_')) {
if (!$this->_sftp) {
$this->sftp();
}
$linker = $this->_sftp;
} else {
$linker = $this->_link;
}
if ($func != 'fetch_stream') {
array_unshift(
$args,
$linker
);
}
$func = 'ssh2_' . $func;
return $func(...$args);
}
public function connect(
$host = '',
$port = 0,
$autologin = true,
$connectmethod = 'ssh2_connect'
) {
try {
$this->_currentConnectionHash = password_hash(
print_r($this->data, 1),
PASSWORD_BCRYPT,
['cost'=>11]
);
if ($this->_link
&& $this->_currentConnectionHash == $this->_lastConnectionHash
) {
return $this;
}
if (!$host) {
$host = $this->host;
}
if (!$port) {
$port = $this->port;
}
$this->_link = ssh2_connect($host, $port);
if ($this->_link === false) {
trigger_error(_('SSH Connection Failed'), E_USER_NOTICE);
$this->ssherror($this->data);
}
if ($autologin) {
$this->login();
}
$this->_lastConnectionHash = $this->_currentConnectionHash;
} catch (Exception $e) {
error_log($e->getMessage());
return false;
}
return $this;
}
public function ssherror($data)
{
$error = error_get_last();
throw new Exception(
sprintf(
'%s: %s, %s: %s, %s: %s, %s: %s, %s: %s, %s: %s',
_('Type'),
$error['type'],
_('File'),
$error['file'],
_('Line'),
$error['line'],
_('Message'),
$error['message'],
_('Host'),
$data['host'],
_('Username'),
$data['username']
)
);
}
public function login(
$username = null,
$password = null
) {
try {
$this->_currentLoginHash = password_hash(
is_object($this->_link) ? spl_object_id($this->_link) : spl_object_id($this),
PASSWORD_BCRYPT,
['cost'=>11]
);
if ($this->_currentLoginHash == $this->_lastLoginHash) {
return $this;
}
if (!$username) {
$username = $this->username;
}
if (!$password) {
$password = $this->password;
}
if ($this->auth_password($username, $password) === false) {
$this->ssherror($this->data);
}
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
$this->_lastLoginHash = $this->_currentLoginHash;
return $this;
}
public function exists($path)
{
$this->sftp();
$sftp_wrap = "ssh2.sftp://{$this->_sftp}{$path}";
return @is_dir($sftp_wrap) || @file_exists($sftp_wrap);
}
public function scanFilesystem($remote_file)
{
if (!$this->exists($remote_file)) {
return [];
}
$sftp = $this->_sftp;
$dir = "ssh2.sftp://$sftp$remote_file";
$tempArray = [];
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file == '.' || $file == '..') {
continue;
}
$filetype = filetype("$dir/$file");
if ($filetype == 'dir') {
$tmp = $this->scanFilesystem("$remote_file/$file/");
foreach ($tmp as $t) {
$tempArray[] = "$remote_file/$file/$t";
}
} else {
$tempArray[] = "$remote_file/$file";
}
}
closedir($dh);
}
}
ob_start();
var_dump($tempArray);
$contents = ob_get_contents();
ob_end_clean();
error_log($contents);
return $tempArray;
}
}
$ssh = new SSH();
$ssh->host = '10.20.0.250';
$ssh->username = 'test';
$ssh->password = 'testpassword';
$ssh->connect();
$files = $ssh->scanFilesystem('/images/test');
?>Resulted in this output - as I'm outputting to errorLog:
array()
But I expected this output instead:
[18-Aug-2024 13:53:04 UTC] array(2) {
[0]=>
string(21) "/images/test/d1p1.img"
[1]=>
string(21) "/images/test/d1p2.img"
}
More Information:
Directory from user->shell:
/images/test$ ls
d1p1.img d1p2.img
Installing php:remi-8.3.9-1 all works.
Installing php:remi-8.3.10-1 same exact file fails.
PHP Version
PHP 8.3.10
Operating System
Fedora 40, Rocky 9, CentOS Stream 9
darksidemilk and Jp01887