33namespace DivineOmega \SSHConnection ;
44
55use InvalidArgumentException ;
6+ use phpseclib \Crypt \RSA ;
7+ use phpseclib \Net \SCP ;
8+ use phpseclib \Net \SSH2 ;
69use RuntimeException ;
710
811class SSHConnection
@@ -11,10 +14,9 @@ class SSHConnection
1114 private $ port = 22 ;
1215 private $ username ;
1316 private $ password ;
14- private $ publicKeyPath ;
1517 private $ privateKeyPath ;
1618 private $ connected = false ;
17- private $ resource ;
19+ private $ ssh ;
1820
1921 public function to (string $ hostname ): self
2022 {
@@ -40,9 +42,8 @@ public function withPassword(string $password): self
4042 return $ this ;
4143 }
4244
43- public function withKeyPair ( string $ publicKeyPath , string $ privateKeyPath ): self
45+ public function withPrivateKey ( string $ privateKeyPath ): self
4446 {
45- $ this ->publicKeyPath = $ publicKeyPath ;
4647 $ this ->privateKeyPath = $ privateKeyPath ;
4748 return $ this ;
4849 }
@@ -57,30 +58,32 @@ private function sanityCheck()
5758 throw new InvalidArgumentException ('Username not specified. ' );
5859 }
5960
60- if (!$ this ->password && (!$ this ->publicKeyPath || ! $ this -> privateKeyPath )) {
61- throw new InvalidArgumentException ('No password or public- private key pair specified. ' );
61+ if (!$ this ->password && (!$ this ->privateKeyPath )) {
62+ throw new InvalidArgumentException ('No password or private key path specified. ' );
6263 }
6364 }
6465
6566 public function connect (): self
6667 {
6768 $ this ->sanityCheck ();
6869
69- $ this ->resource = ssh2_connect ($ this ->hostname , $ this -> port );
70+ $ this ->ssh = new SSH2 ($ this ->hostname );
7071
71- if (!$ this ->resource ) {
72+ if (!$ this ->ssh ) {
7273 throw new RuntimeException ('Error connecting to server. ' );
7374 }
7475
75- if ($ this ->publicKeyPath || $ this ->privateKeyPath ) {
76- $ authenticated = ssh2_auth_pubkey_file ($ this ->resource , $ this ->username , $ this ->publicKeyPath , $ this ->privateKeyPath );
76+ if ($ this ->privateKeyPath ) {
77+ $ key = new RSA ();
78+ $ key ->loadKey (file_get_contents ($ this ->privateKeyPath ));
79+ $ authenticated = $ this ->ssh ->login ($ this ->username , $ key );
7780 if (!$ authenticated ) {
7881 throw new RuntimeException ('Error authenticating with public-private key pair. ' );
7982 }
8083 }
8184
8285 if ($ this ->password ) {
83- $ authenticated = ssh2_auth_password ( $ this ->resource , $ this ->username , $ this ->password );
86+ $ authenticated = $ this ->ssh -> login ( $ this ->username , $ this ->password );
8487 if (!$ authenticated ) {
8588 throw new RuntimeException ('Error authenticating with password. ' );
8689 }
@@ -97,7 +100,7 @@ public function disconnect(): void
97100 throw new RuntimeException ('Unable to disconnect. Not yet connected. ' );
98101 }
99102
100- ssh2_disconnect ( $ this ->resource );
103+ $ this ->ssh -> disconnect ( );
101104 }
102105
103106 public function run (string $ command ): SSHCommand
@@ -106,7 +109,7 @@ public function run(string $command): SSHCommand
106109 throw new RuntimeException ('Unable to run commands when not connected. ' );
107110 }
108111
109- return new SSHCommand ($ this ->resource , $ command );
112+ return new SSHCommand ($ this ->ssh , $ command );
110113 }
111114
112115 public function upload (string $ localPath , string $ remotePath ): bool
@@ -119,7 +122,7 @@ public function upload(string $localPath, string $remotePath): bool
119122 throw new InvalidArgumentException ('The local file does not exist. ' );
120123 }
121124
122- return ssh2_scp_send ( $ this ->resource , $ localPath , $ remotePath );
125+ return ( new SCP ( $ this ->ssh ))-> put ( $ remotePath , $ localPath , SCP :: SOURCE_LOCAL_FILE );
123126 }
124127
125128 public function download (string $ remotePath , string $ localPath ): bool
@@ -128,7 +131,7 @@ public function download(string $remotePath, string $localPath): bool
128131 throw new RuntimeException ('Unable to download file when not connected. ' );
129132 }
130133
131- return ssh2_scp_recv ( $ this ->resource , $ remotePath , $ localPath );
134+ return ( new SCP ( $ this ->ssh ))-> get ( $ remotePath , $ localPath );
132135 }
133136
134137 public function isConnected (): bool
0 commit comments