-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimpleSFTP.class.php
313 lines (289 loc) · 10.8 KB
/
simpleSFTP.class.php
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
<?php
/**
* This file contains a single class to make it easy to move files
* between servers, delete files from remote servers and create new
* directories on remote servers
*
* PHP Version 7.2
*
* @category SFTP
* @package SFTP
* @author Evan Wills <evan.i.wills@gmail.com>
* @license GPL2 <https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html>
* @link https://github.com/evanwills/php-utils
*/
/**
* SimpleSFTP aims make it easy to move files between servers,
* delete files from remote servers and create new directories
* on remote servers
*
* @category SFTP
* @package SFTP
* @author Evan Wills <evan.i.wills@gmail.com>
* @license GPL2 <https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html>
* @link https://github.com/evanwills/php-utils
*/
class SimpleSFTP
{
private $_connection = false;
public $sftpConnection = false;
public $last_error = "";
private $_sshFuncs = [
'ssh2_connect', 'ssh2_auth_password', 'ssh2_auth_pubkey_file',
'ssh2_sftp', 'ssh2_disconnect', 'ssh2_scp_send',
'ssh2_scp_recv', 'ssh2_sftp_unlink', 'ssh2_sftp_unlink'
];
/**
* Initialise an SSH/SFTP connection to a remote server
*
* @param string $host Host name (or IP address) for server
* to connect to
* @param string $user Username for authenticating once
* connected to the server
* @param string $password Password for authenticating once
* connected to the server
* @param string $publicKey Path to public key file for SSH key
* authentication
* @param string $privateKey Path to public key file for SSH key
* authentication
*/
function __construct(
string $host, string $user, string $password,
$publicKey = false, $privateKey = false
) {
// Check that we have SSH functions on the server
for ($a = 0; $a < count($this->_sshFuncs); $a += 1) {
if (!function_exists($this->_sshFuncs[$a])) {
throw new Exception(
'SimpleSFTP requires all of the following '.
'functions to be installed: '.
implode('(), ', $this->_sshFuncs).' '.
$this->_sshFuncs[$a].'() does not exist on '.
'this server'
);
}
}
if (!is_string($host) || empty(trim($host))) {
throw new Exception(
'SimpleSFTP expects first parameter $host to be '.
'a non-empty string'
);
}
if (!is_string($user) || empty(trim($user))) {
throw new Exception(
'SimpleSFTP expects second parameter $user to '.
'be a non-empty string'
);
}
$this->_connection = ssh2_connect($host, 22);
if (is_resource($this->_connection)) {
$ok = false;
if ($publicKey === false) {
if (!is_string($password) && empty(trim($password))) {
// This is a coding error so we'll throw an exception
throw new Exception(
'SimpleSFTP expects third parameter '.
'$password to be non-empty string when '.
'connecting using username & password'
);
} else {
$loginResult = ssh2_auth_password(
$this->_connection, $user, $password
);
if (!$loginResult) {
$this->last_error = 'Username/password '.
'authentication failed '.
"($user@$host)";
} else {
$ok = true;
}
}
} else {
if (!is_string($publicKey) || !is_file($publicKey)
|| !is_string($privateKey) || !is_file($privateKey)
) {
// This is a coding error so we'll throw an exception
throw new Exception(
'SimpleSFTP expects both $publicKey and '.
'$privateKey to be strings pointing to SSH '.
'public & private key files'
);
} else {
$password = (is_string($password))
? $password
: '';
$loginResult = ssh2_auth_pubkey_file(
$this->_connection, $user,
$publicKey, $privateKey, $password
);
if (!$loginResult) {
$this->last_error = 'SSH Key '.
'authentication failed '.
"($user@$host)";
} else {
$ok = true;
}
}
}
if ($ok === true) {
$this->sftpConnection = ssh2_sftp($this->_connection);
if (!$this->sftpConnection) {
$this->last_error = "SFTP connection failed";
}
}
} else {
$this->last_error = "SSH connection refused";
}
}
/**
* Close SFTP connection
*
* @return void
*/
public function disconnect()
{
if (is_resource($this->_connection)) {
$this->sftpConnection = false;
$this->_connection = ssh2_disconnect($this->_connection);
}
}
/**
* Upload a single file from the local file system to the
* remote file system
*
* @param string $localPath Path to file in local file system
* @param string $remotePath Remote file system path to place
* the file
* @param integer $mode Unix file permissions value
*
* @return boolean TRUE if file was successfully sent.
* FALSE otherwise
*/
public function upload(
string $localPath, string $remotePath, int $mode = 0664
) : bool {
if ($this->sftpConnection === false) {
throw new Exception(
'SimpleSFTP\'s has no SFTP connection! Either the '.
'connetion has already been closed or no '.
'connection was made'
);
}
if (!is_string($localPath) || !is_file($localPath)
|| !is_readable($localPath)
) {
throw new Exception(
'SimpleSFTP::upload() expects first parameter '.
'$localPath to be a string pointing to a file '.
'in the local file system.'
);
}
if (!is_string($remotePath) || !empty(trim($remotePath))) {
throw new Exception(
'SimpleSFTP::upload() expects second parameter '.
'$remotePath to be a string pointing to a file '.
'in the local file system.'
);
}
return ssh2_scp_send(
$this->_connection, $localPath, $remotePath, $mode
);
}
/**
* Download a single file from the local file system to the
* remote file system
*
* @param string $remotePath Remote file system path to place
* the file
* @param string $localPath Path to file in local file system
*
* @return boolean TRUE if file was successfully received.
* FALSE otherwise
*/
public function download(string $remotePath, string $localPath) : bool
{
if ($this->sftpConnection === false) {
throw new Exception(
'SimpleSFTP\'s has no SFTP connection! Either the '.
'connetion has already been closed or no '.
'connection was made'
);
}
if (!is_string($remotePath) || !empty(trim($remotePath))) {
throw new Exception(
'SimpleSFTP::download() expects first parameter '.
'$remotePath to be a string pointing to a file '.
'in the local file system.'
);
}
if (!is_string($localPath) || !is_writable($localPath)) {
throw new Exception(
'SimpleSFTP::download() expects second parameter '.
'$localPath to be a string pointing to a writable '.
'file/directory in the local file system.'
);
}
return ssh2_scp_recv(
$this->_connection, $remotePath, $localPath
);
}
/**
* Delete a single file from the remote file system
*
* @param string $remotePath Remote file system path to place
* the file
*
* @return boolean TRUE if file was successfully deleted.
* FALSE otherwise
*/
public function delete(string $remotePath) : bool
{
if ($this->sftpConnection === false) {
throw new Exception(
'SimpleSFTP\'s has no SFTP connection! Either the '.
'connetion has already been closed or no '.
'connection was made'
);
}
if (!is_string($remotePath) || !empty(trim($remotePath))) {
throw new Exception(
'SimpleSFTP::download() expects first parameter '.
'$remotePath to be a string pointing to a file '.
'in the local file system.'
);
}
return ssh2_sftp_unlink(
$this->_connection, $remotePath
);
}
/**
* Delete a single file from the remote file system
*
* @param string $remotePath Remote file system path to place
* the file
* @param integer $mode Unix file permissions value
*
* @return boolean TRUE if file was successfully deleted.
* FALSE otherwise
*/
public function mkdir(string $remotePath, int $mode = 0664) : bool
{
if ($this->sftpConnection === false) {
throw new Exception(
'SimpleSFTP\'s has no SFTP connection! Either the '.
'connetion has already been closed or no '.
'connection was made'
);
}
if (!is_string($remotePath) || !empty(trim($remotePath))) {
throw new Exception(
'SimpleSFTP::download() expects first parameter '.
'$remotePath to be a string pointing to a file '.
'in the local file system.'
);
}
return ssh2_sftp_unlink(
$this->_connection, $remotePath
);
}
}