1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
<?php
namespace PHPIAC;
use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Net\SFTP;
use phpseclib3\Net\SSH2;
/**
* Class Connection
*
* @method static string exec(string $command, callback $callback = null)
* @method static string|bool|null read(string $expect = '', int $read = 1)
* @method static bool write(string $cmd)
* @method static enablePty()
* @method static disablePty()
*/
class Connection
{
private static SSH2 $ssh;
private static SFTP $sftp;
private static string $host;
private static string $user;
private static mixed $key;
/**
* Connection constructor.
*
* @param string $host
* @param string $user
* @param string $keyFile
*
* @throws \Exception
*/
public static function initialize(string $host, string $user, string $keyFile)
{
self::$host = $host;
self::$user = $user;
self::$key = PublicKeyLoader::load(file_get_contents($keyFile));
self::connect();
}
/**
* @throws \Exception
*/
private static function connect()
{
self::$ssh = new SSH2(self::$host);
if (! self::$ssh->login(self::$user, self::$key)) {
throw new \Exception('SSH Login failed');
}
self::$sftp = new SFTP(self::$host);
if (! self::$sftp->login(self::$user, self::$key)) {
throw new \Exception('SFTP Login failed');
}
}
/**
* @throws \Exception
*/
private static function ensureConnection()
{
if (! self::$ssh->isConnected() ||
! self::$sftp->isConnected()) {
self::connect();
}
}
/**
* Calls SSH2 methods statically
*
* @param string $name
* @param array $arguments
*
* @return mixed
*/
public static function __callStatic(string $name, array $arguments): mixed
{
self::ensureConnection();
if (! method_exists(self::$ssh, $name)) {
return self::$sftp->$name(...$arguments);
}
return self::$ssh->$name(...$arguments);
}
/**
* @see SFTP::put
*/
public static function put($remote_file, $data, $mode = SFTP::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null): bool
{
self::ensureConnection();
$tmp = bin2hex(random_bytes(10)); # work around sftp sudo put restrictions
return
self::$sftp->put("/tmp/$tmp", $data, $mode, $start, $local_start, $progressCallback) &&
self::$ssh->exec("sudo mv /tmp/$tmp $remote_file");
}
}
|