summaryrefslogtreecommitdiff
path: root/src/Connection.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Connection.php')
-rw-r--r--src/Connection.php78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/Connection.php b/src/Connection.php
new file mode 100644
index 0000000..2052cd1
--- /dev/null
+++ b/src/Connection.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace PHPIAC;
+
+use PHPIAC\Support\SingletonTraitWithArguments;
+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 enablePty()
+ * @method static disablePty()
+ */
+class Connection
+{
+ use SingletonTraitWithArguments;
+
+ private SSH2 $ssh;
+ private SFTP $sftp;
+
+ /**
+ * Connection constructor.
+ *
+ * @param string $host
+ * @param string $user
+ * @param string $key
+ *
+ * @throws \Exception
+ */
+ public function __construct(string $host, string $user, string $key)
+ {
+ $this->ssh = new SSH2($host);
+ $key = PublicKeyLoader::load(file_get_contents($key));
+ if (! $this->ssh->login($user, $key)) {
+ throw new \Exception('SSH Login failed');
+ }
+
+ $this->sftp = new SFTP($host);
+ if (! $this->sftp->login($user, $key)) {
+ throw new \Exception('SFTP Login failed');
+ }
+ }
+
+ /**
+ * Calls SSH2 methods statically
+ *
+ * @param string $name
+ * @param array $arguments
+ *
+ * @return mixed
+ */
+ public static function __callStatic(string $name, array $arguments): mixed
+ {
+ $self = self::getInstance();
+
+ 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
+ {
+ $tmp = bin2hex(random_bytes(10)); # work around sftp sudo put restrictions
+
+ return
+ self::getInstance()->sftp->put("/tmp/$tmp", $data, $mode, $start, $local_start, $progressCallback) &&
+ self::getInstance()->ssh->exec("sudo mv /tmp/$tmp $remote_file");
+ }
+}