Version Description
2018/Dec/14 =
TWEAK: Replaced the deprecated 'var' visibility indicator
TWEAK: Add various sanity checks to return error codes instead of causing fatal errors if another component calls the WP_Filesystem API incorrectly
TWEAK: Add an extra sanity check that should prevent a fatal error if a component directly requests the 'direct' filesystem method but WP won't let it have it
Download this release
Release Info
Developer | DavidAnderson |
Plugin | SSH SFTP Updater Support |
Version | 0.8.0 |
Comparing to | |
See all releases |
Code changes from version 0.7.6 to 0.8.0
- class-wp-filesystem-ssh2.php +376 -350
- phpseclib/Crypt/Base.php +4 -4
- phpseclib/Crypt/Hash.php +20 -78
- phpseclib/File/ASN1.php +0 -12
- phpseclib/File/X509.php +8 -14
- phpseclib/Math/BigInteger.php +1 -0
- phpseclib/Net/SFTP.php +1 -11
- phpseclib/Net/SSH2.php +22 -177
- phpseclib/System/SSH/Agent.php +0 -14
- readme.txt +10 -2
- sftp.php +3 -3
class-wp-filesystem-ssh2.php
CHANGED
@@ -1,350 +1,376 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WordPress SSH2 Filesystem.
|
4 |
-
*
|
5 |
-
* @package WordPress
|
6 |
-
* @subpackage Filesystem
|
7 |
-
*/
|
8 |
-
|
9 |
-
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/phpseclib/');
|
10 |
-
|
11 |
-
require_once('Net/SFTP.php');
|
12 |
-
require_once('Crypt/RSA.php');
|
13 |
-
|
14 |
-
/**
|
15 |
-
* WordPress Filesystem Class for implementing SSH2.
|
16 |
-
*
|
17 |
-
* @since 2.7
|
18 |
-
* @package WordPress
|
19 |
-
* @subpackage Filesystem
|
20 |
-
* @uses WP_Filesystem_Base Extends class
|
21 |
-
*/
|
22 |
-
|
23 |
-
class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
public function __construct($opt='') {
|
33 |
-
$this->method = 'ssh2';
|
34 |
-
$this->errors = new WP_Error();
|
35 |
-
|
36 |
-
if ( !function_exists('stream_get_contents') ) {
|
37 |
-
$this->errors->add('ssh2_php_requirement', __('We require the PHP5 function <code>stream_get_contents()</code>'));
|
38 |
-
return false;
|
39 |
-
}
|
40 |
-
|
41 |
-
// Set defaults:
|
42 |
-
if ( empty($opt['port']) )
|
43 |
-
$this->options['port'] = 22;
|
44 |
-
else
|
45 |
-
$this->options['port'] = $opt['port'];
|
46 |
-
|
47 |
-
if ( empty($opt['hostname']) )
|
48 |
-
$this->errors->add('empty_hostname', __('SSH2 hostname is required'));
|
49 |
-
else
|
50 |
-
$this->options['hostname'] = $opt['hostname'];
|
51 |
-
|
52 |
-
if ( ! empty($opt['base']) )
|
53 |
-
$this->wp_base = $opt['base'];
|
54 |
-
|
55 |
-
if ( !empty ($opt['private_key']) ) {
|
56 |
-
$this->options['private_key'] = $opt['private_key'];
|
57 |
-
|
58 |
-
$this->keys = true;
|
59 |
-
} elseif ( empty ($opt['username']) ) {
|
60 |
-
$this->errors->add('empty_username', __('SSH2 username is required'));
|
61 |
-
}
|
62 |
-
|
63 |
-
if ( !empty($opt['username']) )
|
64 |
-
$this->options['username'] = $opt['username'];
|
65 |
-
|
66 |
-
if ( empty ($opt['password']) ) {
|
67 |
-
if ( !$this->keys ) //password can be blank if we are using keys
|
68 |
-
$this->errors->add('empty_password', __('SSH2 password is required'));
|
69 |
-
} else {
|
70 |
-
$this->options['password'] = $opt['password'];
|
71 |
-
|
72 |
-
$this->password = true;
|
73 |
-
}
|
74 |
-
}
|
75 |
-
|
76 |
-
public function connect() {
|
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 |
-
return
|
145 |
-
}
|
146 |
-
|
147 |
-
public function
|
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 |
-
if ( ! $
|
186 |
-
return false;
|
187 |
-
if ( !
|
188 |
-
return $
|
189 |
-
$
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
$
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
return $
|
211 |
-
}
|
212 |
-
|
213 |
-
public function
|
214 |
-
if (
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
if (
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
return $this->
|
236 |
-
}
|
237 |
-
|
238 |
-
public function
|
239 |
-
|
240 |
-
return $
|
241 |
-
}
|
242 |
-
|
243 |
-
public function
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
return
|
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 |
-
if (
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
if (
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
return $
|
296 |
-
}
|
297 |
-
|
298 |
-
public function
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
$
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
$
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WordPress SSH2 Filesystem.
|
4 |
+
*
|
5 |
+
* @package WordPress
|
6 |
+
* @subpackage Filesystem
|
7 |
+
*/
|
8 |
+
|
9 |
+
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/phpseclib/');
|
10 |
+
|
11 |
+
require_once('Net/SFTP.php');
|
12 |
+
require_once('Crypt/RSA.php');
|
13 |
+
|
14 |
+
/**
|
15 |
+
* WordPress Filesystem Class for implementing SSH2.
|
16 |
+
*
|
17 |
+
* @since 2.7
|
18 |
+
* @package WordPress
|
19 |
+
* @subpackage Filesystem
|
20 |
+
* @uses WP_Filesystem_Base Extends class
|
21 |
+
*/
|
22 |
+
|
23 |
+
class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
|
24 |
+
|
25 |
+
public $link = false;
|
26 |
+
public $sftp_link = false;
|
27 |
+
public $keys = false;
|
28 |
+
public $password = false;
|
29 |
+
public $errors = array();
|
30 |
+
public $options = array();
|
31 |
+
|
32 |
+
public function __construct($opt='') {
|
33 |
+
$this->method = 'ssh2';
|
34 |
+
$this->errors = new WP_Error();
|
35 |
+
|
36 |
+
if ( !function_exists('stream_get_contents') ) {
|
37 |
+
$this->errors->add('ssh2_php_requirement', __('We require the PHP5 function <code>stream_get_contents()</code>'));
|
38 |
+
return false;
|
39 |
+
}
|
40 |
+
|
41 |
+
// Set defaults:
|
42 |
+
if ( empty($opt['port']) )
|
43 |
+
$this->options['port'] = 22;
|
44 |
+
else
|
45 |
+
$this->options['port'] = $opt['port'];
|
46 |
+
|
47 |
+
if ( empty($opt['hostname']) )
|
48 |
+
$this->errors->add('empty_hostname', __('SSH2 hostname is required'));
|
49 |
+
else
|
50 |
+
$this->options['hostname'] = $opt['hostname'];
|
51 |
+
|
52 |
+
if ( ! empty($opt['base']) )
|
53 |
+
$this->wp_base = $opt['base'];
|
54 |
+
|
55 |
+
if ( !empty ($opt['private_key']) ) {
|
56 |
+
$this->options['private_key'] = $opt['private_key'];
|
57 |
+
|
58 |
+
$this->keys = true;
|
59 |
+
} elseif ( empty ($opt['username']) ) {
|
60 |
+
$this->errors->add('empty_username', __('SSH2 username is required'));
|
61 |
+
}
|
62 |
+
|
63 |
+
if ( !empty($opt['username']) )
|
64 |
+
$this->options['username'] = $opt['username'];
|
65 |
+
|
66 |
+
if ( empty ($opt['password']) ) {
|
67 |
+
if ( !$this->keys ) //password can be blank if we are using keys
|
68 |
+
$this->errors->add('empty_password', __('SSH2 password is required'));
|
69 |
+
} else {
|
70 |
+
$this->options['password'] = $opt['password'];
|
71 |
+
|
72 |
+
$this->password = true;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
public function connect() {
|
77 |
+
|
78 |
+
if (empty($this->options['hostname']) || empty($this->options['username'])) {
|
79 |
+
$this->errors->add('auth', sprintf(__('No connection credentials available'), $this->options));
|
80 |
+
return false;
|
81 |
+
}
|
82 |
+
|
83 |
+
$this->link = new Net_SFTP($this->options['hostname'], $this->options['port']);
|
84 |
+
|
85 |
+
if ( !$this->keys ) {
|
86 |
+
if ( ! $this->link->login($this->options['username'], $this->options['password']) ) {
|
87 |
+
if ( $this->handle_connect_error() )
|
88 |
+
return false;
|
89 |
+
$this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
|
90 |
+
return false;
|
91 |
+
}
|
92 |
+
} else {
|
93 |
+
$rsa = new Crypt_RSA();
|
94 |
+
if ( $this->password ) {
|
95 |
+
$rsa->setPassword($this->options['password']);
|
96 |
+
}
|
97 |
+
$rsa->loadKey($this->options['private_key']);
|
98 |
+
if ( ! $this->link->login($this->options['username'], $rsa ) ) {
|
99 |
+
if ( $this->handle_connect_error() )
|
100 |
+
return false;
|
101 |
+
$this->errors->add('auth', sprintf(__('Private key incorrect for %s'), $this->options['username']));
|
102 |
+
$this->errors->add('auth', __('Make sure that the key you are using is an RSA key and not a DSA key'));
|
103 |
+
return false;
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
return true;
|
108 |
+
}
|
109 |
+
|
110 |
+
public function handle_connect_error() {
|
111 |
+
if ( ! $this->link->isConnected() ) {
|
112 |
+
$this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
|
113 |
+
$this->errors->add('connect2', __('If SELinux is installed check to make sure that <code>httpd_can_network_connect</code> is set to 1'));
|
114 |
+
return true;
|
115 |
+
}
|
116 |
+
|
117 |
+
return false;
|
118 |
+
}
|
119 |
+
|
120 |
+
public function run_command( $command, $returnbool = false) {
|
121 |
+
|
122 |
+
if ( ! $this->link )
|
123 |
+
return false;
|
124 |
+
|
125 |
+
$data = $this->link->exec($command);
|
126 |
+
|
127 |
+
if ( $returnbool )
|
128 |
+
return ( $data === false ) ? false : '' != trim($data);
|
129 |
+
else
|
130 |
+
return $data;
|
131 |
+
}
|
132 |
+
|
133 |
+
public function get_contents($file, $type = '', $resumepos = 0 ) {
|
134 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
135 |
+
return $this->link->get($file);
|
136 |
+
}
|
137 |
+
|
138 |
+
public function get_contents_array($file) {
|
139 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
140 |
+
$lines = preg_split('#(\r\n|\r|\n)#', $this->link->get($file), -1, PREG_SPLIT_DELIM_CAPTURE);
|
141 |
+
$newLines = array();
|
142 |
+
for ($i = 0; $i < count($lines); $i+= 2)
|
143 |
+
$newLines[] = $lines[$i] . $lines[$i + 1];
|
144 |
+
return $newLines;
|
145 |
+
}
|
146 |
+
|
147 |
+
public function put_contents($file, $contents, $mode = false ) {
|
148 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
149 |
+
$ret = $this->link->put($file, $contents);
|
150 |
+
|
151 |
+
$this->chmod($file, $mode);
|
152 |
+
|
153 |
+
return false !== $ret;
|
154 |
+
}
|
155 |
+
|
156 |
+
public function cwd() {
|
157 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
158 |
+
$cwd = $this->run_command('pwd');
|
159 |
+
if ( $cwd )
|
160 |
+
$cwd = trailingslashit($cwd);
|
161 |
+
return $cwd;
|
162 |
+
}
|
163 |
+
|
164 |
+
public function chdir($dir) {
|
165 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
166 |
+
$this->list->chdir($dir);
|
167 |
+
return $this->run_command('cd ' . $dir, true);
|
168 |
+
}
|
169 |
+
|
170 |
+
public function chgrp($file, $group, $recursive = false ) {
|
171 |
+
if ( ! $this->exists($file) )
|
172 |
+
return false;
|
173 |
+
if ( ! $recursive || ! $this->is_dir($file) )
|
174 |
+
return $this->run_command(sprintf('chgrp %o %s', $mode, escapeshellarg($file)), true);
|
175 |
+
return $this->run_command(sprintf('chgrp -R %o %s', $mode, escapeshellarg($file)), true);
|
176 |
+
}
|
177 |
+
|
178 |
+
public function chmod($file, $mode = false, $recursive = false) {
|
179 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
180 |
+
return $mode === false ? false : $this->link->chmod($mode, $file, $recursive);
|
181 |
+
}
|
182 |
+
|
183 |
+
public function chown($file, $owner, $recursive = false ) {
|
184 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
185 |
+
if ( ! $this->exists($file) )
|
186 |
+
return false;
|
187 |
+
if ( ! $recursive || ! $this->is_dir($file) )
|
188 |
+
return $this->run_command(sprintf('chown %o %s', $mode, escapeshellarg($file)), true);
|
189 |
+
return $this->run_command(sprintf('chown -R %o %s', $mode, escapeshellarg($file)), true);
|
190 |
+
}
|
191 |
+
|
192 |
+
public function owner($file, $owneruid = false) {
|
193 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
194 |
+
if ($owneruid === false) {
|
195 |
+
$result = $this->link->stat($file);
|
196 |
+
$owneruid = $result['uid'];
|
197 |
+
}
|
198 |
+
|
199 |
+
if ( ! $owneruid )
|
200 |
+
return false;
|
201 |
+
if ( ! function_exists('posix_getpwuid') )
|
202 |
+
return $owneruid;
|
203 |
+
$ownerarray = posix_getpwuid($owneruid);
|
204 |
+
return $ownerarray['name'];
|
205 |
+
}
|
206 |
+
|
207 |
+
public function getchmod($file) {
|
208 |
+
$result = $this->link->stat($file);
|
209 |
+
|
210 |
+
return substr(decoct($result['permissions']),3);
|
211 |
+
}
|
212 |
+
|
213 |
+
public function group($file, $gid = false) {
|
214 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
215 |
+
if ($gid === false) {
|
216 |
+
$result = $this->link->stat($file);
|
217 |
+
$gid = $result['gid'];
|
218 |
+
}
|
219 |
+
|
220 |
+
if ( ! $gid )
|
221 |
+
return false;
|
222 |
+
if ( ! function_exists('posix_getgrgid') )
|
223 |
+
return $gid;
|
224 |
+
$grouparray = posix_getgrgid($gid);
|
225 |
+
return $grouparray['name'];
|
226 |
+
}
|
227 |
+
|
228 |
+
public function copy($source, $destination, $overwrite = false, $mode = false) {
|
229 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
230 |
+
if ( ! $overwrite && $this->exists($destination) )
|
231 |
+
return false;
|
232 |
+
$content = $this->get_contents($source);
|
233 |
+
if ( false === $content)
|
234 |
+
return false;
|
235 |
+
return $this->put_contents($destination, $content, $mode);
|
236 |
+
}
|
237 |
+
|
238 |
+
public function move($source, $destination, $overwrite = false) {
|
239 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
240 |
+
return $this->link->rename($source, $destination);
|
241 |
+
}
|
242 |
+
|
243 |
+
public function delete($file, $recursive = false, $type = false) {
|
244 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
245 |
+
if ( 'f' == $type || $this->is_file($file) )
|
246 |
+
return $this->link->delete($file);
|
247 |
+
if ( ! $recursive )
|
248 |
+
return $this->link->rmdir($file);
|
249 |
+
return $this->link->delete($file, $recursive);
|
250 |
+
}
|
251 |
+
|
252 |
+
public function exists($file) {
|
253 |
+
return $this->link->stat($file) !== false;
|
254 |
+
}
|
255 |
+
|
256 |
+
public function is_file($file) {
|
257 |
+
$result = $this->link->stat($file);
|
258 |
+
return $result['type'] == NET_SFTP_TYPE_REGULAR;
|
259 |
+
}
|
260 |
+
|
261 |
+
public function is_dir($path) {
|
262 |
+
$result = $this->link->stat($path);
|
263 |
+
return $result['type'] == NET_SFTP_TYPE_DIRECTORY;
|
264 |
+
}
|
265 |
+
|
266 |
+
public function is_readable($file) {
|
267 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
268 |
+
return true;
|
269 |
+
|
270 |
+
return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
|
271 |
+
}
|
272 |
+
|
273 |
+
public function is_writable($file) {
|
274 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
275 |
+
return true;
|
276 |
+
|
277 |
+
return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
|
278 |
+
}
|
279 |
+
|
280 |
+
public function atime($file) {
|
281 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
282 |
+
$result = $this->link->stat($file);
|
283 |
+
return $result['atime'];
|
284 |
+
}
|
285 |
+
|
286 |
+
public function mtime($file) {
|
287 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
288 |
+
$result = $this->link->stat($file);
|
289 |
+
return $result['mtime'];
|
290 |
+
}
|
291 |
+
|
292 |
+
public function size($file) {
|
293 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
294 |
+
$result = $this->link->stat($file);
|
295 |
+
return $result['size'];
|
296 |
+
}
|
297 |
+
|
298 |
+
public function touch($file, $time = 0, $atime = 0) {
|
299 |
+
//Not implmented.
|
300 |
+
}
|
301 |
+
|
302 |
+
public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
|
303 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
304 |
+
$path = untrailingslashit($path);
|
305 |
+
if ( ! $chmod )
|
306 |
+
$chmod = FS_CHMOD_DIR;
|
307 |
+
//if ( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) )
|
308 |
+
// return false;
|
309 |
+
if ( ! $this->link->mkdir($path) && $this->link->chmod($chmod, $path) )
|
310 |
+
return false;
|
311 |
+
if ( $chown )
|
312 |
+
$this->chown($path, $chown);
|
313 |
+
if ( $chgrp )
|
314 |
+
$this->chgrp($path, $chgrp);
|
315 |
+
return true;
|
316 |
+
}
|
317 |
+
|
318 |
+
public function rmdir($path, $recursive = false) {
|
319 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
320 |
+
return $this->delete($path, $recursive);
|
321 |
+
}
|
322 |
+
|
323 |
+
public function dirlist($path, $include_hidden = true, $recursive = false) {
|
324 |
+
if (!is_a($this->link, 'Net_SFTP')) return false;
|
325 |
+
if ( $this->is_file($path) ) {
|
326 |
+
$limit_file = basename($path);
|
327 |
+
$path = dirname($path);
|
328 |
+
} else {
|
329 |
+
$limit_file = false;
|
330 |
+
}
|
331 |
+
|
332 |
+
if ( ! $this->is_dir($path) )
|
333 |
+
return false;
|
334 |
+
|
335 |
+
$ret = array();
|
336 |
+
$entries = $this->link->rawlist($path);
|
337 |
+
|
338 |
+
if ( $entries === false )
|
339 |
+
return false;
|
340 |
+
|
341 |
+
foreach ($entries as $name => $entry) {
|
342 |
+
$struc = array();
|
343 |
+
$struc['name'] = $name;
|
344 |
+
|
345 |
+
if ( '.' == $struc['name'] || '..' == $struc['name'] )
|
346 |
+
continue; //Do not care about these folders.
|
347 |
+
|
348 |
+
if ( ! $include_hidden && '.' == $struc['name'][0] )
|
349 |
+
continue;
|
350 |
+
|
351 |
+
if ( $limit_file && $struc['name'] != $limit_file )
|
352 |
+
continue;
|
353 |
+
|
354 |
+
$struc['perms'] = $entry['permissions'];
|
355 |
+
$struc['permsn'] = $this->getnumchmodfromh($struc['perms']);
|
356 |
+
$struc['number'] = false;
|
357 |
+
$struc['owner'] = $this->owner($path.'/'.$name, $entry['uid']);
|
358 |
+
$struc['group'] = $this->group($path.'/'.$name, $entry['gid']);
|
359 |
+
$struc['size'] = $entry['size'];//$this->size($path.'/'.$entry);
|
360 |
+
$struc['lastmodunix']= $entry['mtime'];//$this->mtime($path.'/'.$entry);
|
361 |
+
$struc['lastmod'] = date('M j',$struc['lastmodunix']);
|
362 |
+
$struc['time'] = date('h:i:s',$struc['lastmodunix']);
|
363 |
+
$struc['type'] = $entry['type'] == NET_SFTP_TYPE_DIRECTORY ? 'd' : 'f';
|
364 |
+
|
365 |
+
if ( 'd' == $struc['type'] ) {
|
366 |
+
if ( $recursive )
|
367 |
+
$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
|
368 |
+
else
|
369 |
+
$struc['files'] = array();
|
370 |
+
}
|
371 |
+
|
372 |
+
$ret[ $struc['name'] ] = $struc;
|
373 |
+
}
|
374 |
+
return $ret;
|
375 |
+
}
|
376 |
+
}
|
phpseclib/Crypt/Base.php
CHANGED
@@ -661,7 +661,7 @@ class Crypt_Base
|
|
661 |
$count = isset($func_args[4]) ? $func_args[4] : 1000;
|
662 |
|
663 |
// Keylength
|
664 |
-
if (isset($func_args[5])
|
665 |
$dkLen = $func_args[5];
|
666 |
} else {
|
667 |
$dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
|
@@ -696,10 +696,10 @@ class Crypt_Base
|
|
696 |
include_once 'Crypt/Hash.php';
|
697 |
}
|
698 |
$i = 1;
|
699 |
-
$hmac = new Crypt_Hash();
|
700 |
-
$hmac->setHash($hash);
|
701 |
-
$hmac->setKey($password);
|
702 |
while (strlen($key) < $dkLen) {
|
|
|
|
|
|
|
703 |
$f = $u = $hmac->hash($salt . pack('N', $i++));
|
704 |
for ($j = 2; $j <= $count; ++$j) {
|
705 |
$u = $hmac->hash($u);
|
661 |
$count = isset($func_args[4]) ? $func_args[4] : 1000;
|
662 |
|
663 |
// Keylength
|
664 |
+
if (isset($func_args[5])) {
|
665 |
$dkLen = $func_args[5];
|
666 |
} else {
|
667 |
$dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
|
696 |
include_once 'Crypt/Hash.php';
|
697 |
}
|
698 |
$i = 1;
|
|
|
|
|
|
|
699 |
while (strlen($key) < $dkLen) {
|
700 |
+
$hmac = new Crypt_Hash();
|
701 |
+
$hmac->setHash($hash);
|
702 |
+
$hmac->setKey($password);
|
703 |
$f = $u = $hmac->hash($salt . pack('N', $i++));
|
704 |
for ($j = 2; $j <= $count; ++$j) {
|
705 |
$u = $hmac->hash($u);
|
phpseclib/Crypt/Hash.php
CHANGED
@@ -126,15 +126,6 @@ class Crypt_Hash
|
|
126 |
*/
|
127 |
var $key = false;
|
128 |
|
129 |
-
/**
|
130 |
-
* Computed Key
|
131 |
-
*
|
132 |
-
* @see self::_computeKey()
|
133 |
-
* @var string
|
134 |
-
* @access private
|
135 |
-
*/
|
136 |
-
var $computedKey = false;
|
137 |
-
|
138 |
/**
|
139 |
* Outer XOR (Internal HMAC)
|
140 |
*
|
@@ -201,43 +192,6 @@ class Crypt_Hash
|
|
201 |
function setKey($key = false)
|
202 |
{
|
203 |
$this->key = $key;
|
204 |
-
$this->_computeKey();
|
205 |
-
}
|
206 |
-
|
207 |
-
/**
|
208 |
-
* Pre-compute the key used by the HMAC
|
209 |
-
*
|
210 |
-
* Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
|
211 |
-
* will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
|
212 |
-
*
|
213 |
-
* As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
|
214 |
-
* when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
|
215 |
-
* every call
|
216 |
-
*
|
217 |
-
* @access private
|
218 |
-
*/
|
219 |
-
function _computeKey()
|
220 |
-
{
|
221 |
-
if ($this->key === false) {
|
222 |
-
$this->computedKey = false;
|
223 |
-
return;
|
224 |
-
}
|
225 |
-
|
226 |
-
if (strlen($this->key) <= $this->b) {
|
227 |
-
$this->computedKey = $this->key;
|
228 |
-
return;
|
229 |
-
}
|
230 |
-
|
231 |
-
switch ($mode) {
|
232 |
-
case CRYPT_HASH_MODE_MHASH:
|
233 |
-
$this->computedKey = mhash($this->hash, $this->key);
|
234 |
-
break;
|
235 |
-
case CRYPT_HASH_MODE_HASH:
|
236 |
-
$this->computedKey = hash($this->hash, $this->key, true);
|
237 |
-
break;
|
238 |
-
case CRYPT_HASH_MODE_INTERNAL:
|
239 |
-
$this->computedKey = call_user_func($this->hash, $this->key);
|
240 |
-
}
|
241 |
}
|
242 |
|
243 |
/**
|
@@ -287,25 +241,6 @@ class Crypt_Hash
|
|
287 |
$this->l = 64;
|
288 |
}
|
289 |
|
290 |
-
switch ($hash) {
|
291 |
-
case 'md2-96':
|
292 |
-
case 'md2':
|
293 |
-
$this->b = 16;
|
294 |
-
case 'md5-96':
|
295 |
-
case 'sha1-96':
|
296 |
-
case 'sha224-96':
|
297 |
-
case 'sha256-96':
|
298 |
-
case 'md2':
|
299 |
-
case 'md5':
|
300 |
-
case 'sha1':
|
301 |
-
case 'sha224':
|
302 |
-
case 'sha256':
|
303 |
-
$this->b = 64;
|
304 |
-
break;
|
305 |
-
default:
|
306 |
-
$this->b = 128;
|
307 |
-
}
|
308 |
-
|
309 |
switch ($hash) {
|
310 |
case 'md2':
|
311 |
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
|
@@ -332,7 +267,6 @@ class Crypt_Hash
|
|
332 |
default:
|
333 |
$this->hash = MHASH_SHA1;
|
334 |
}
|
335 |
-
$this->_computeKey();
|
336 |
return;
|
337 |
case CRYPT_HASH_MODE_HASH:
|
338 |
switch ($hash) {
|
@@ -349,33 +283,35 @@ class Crypt_Hash
|
|
349 |
default:
|
350 |
$this->hash = 'sha1';
|
351 |
}
|
352 |
-
$this->_computeKey();
|
353 |
return;
|
354 |
}
|
355 |
|
356 |
switch ($hash) {
|
357 |
case 'md2':
|
|
|
358 |
$this->hash = array($this, '_md2');
|
359 |
break;
|
360 |
case 'md5':
|
|
|
361 |
$this->hash = array($this, '_md5');
|
362 |
break;
|
363 |
case 'sha256':
|
|
|
364 |
$this->hash = array($this, '_sha256');
|
365 |
break;
|
366 |
case 'sha384':
|
367 |
case 'sha512':
|
|
|
368 |
$this->hash = array($this, '_sha512');
|
369 |
break;
|
370 |
case 'sha1':
|
371 |
default:
|
|
|
372 |
$this->hash = array($this, '_sha1');
|
373 |
}
|
374 |
|
375 |
$this->ipad = str_repeat(chr(0x36), $this->b);
|
376 |
$this->opad = str_repeat(chr(0x5C), $this->b);
|
377 |
-
|
378 |
-
$this->_computeKey();
|
379 |
}
|
380 |
|
381 |
/**
|
@@ -392,19 +328,25 @@ class Crypt_Hash
|
|
392 |
if (!empty($this->key) || is_string($this->key)) {
|
393 |
switch ($mode) {
|
394 |
case CRYPT_HASH_MODE_MHASH:
|
395 |
-
$output = mhash($this->hash, $text, $this->
|
396 |
break;
|
397 |
case CRYPT_HASH_MODE_HASH:
|
398 |
-
$output = hash_hmac($this->hash, $text, $this->
|
399 |
break;
|
400 |
case CRYPT_HASH_MODE_INTERNAL:
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
$
|
406 |
-
|
407 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
}
|
409 |
} else {
|
410 |
switch ($mode) {
|
126 |
*/
|
127 |
var $key = false;
|
128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
/**
|
130 |
* Outer XOR (Internal HMAC)
|
131 |
*
|
192 |
function setKey($key = false)
|
193 |
{
|
194 |
$this->key = $key;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
}
|
196 |
|
197 |
/**
|
241 |
$this->l = 64;
|
242 |
}
|
243 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
244 |
switch ($hash) {
|
245 |
case 'md2':
|
246 |
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
|
267 |
default:
|
268 |
$this->hash = MHASH_SHA1;
|
269 |
}
|
|
|
270 |
return;
|
271 |
case CRYPT_HASH_MODE_HASH:
|
272 |
switch ($hash) {
|
283 |
default:
|
284 |
$this->hash = 'sha1';
|
285 |
}
|
|
|
286 |
return;
|
287 |
}
|
288 |
|
289 |
switch ($hash) {
|
290 |
case 'md2':
|
291 |
+
$this->b = 16;
|
292 |
$this->hash = array($this, '_md2');
|
293 |
break;
|
294 |
case 'md5':
|
295 |
+
$this->b = 64;
|
296 |
$this->hash = array($this, '_md5');
|
297 |
break;
|
298 |
case 'sha256':
|
299 |
+
$this->b = 64;
|
300 |
$this->hash = array($this, '_sha256');
|
301 |
break;
|
302 |
case 'sha384':
|
303 |
case 'sha512':
|
304 |
+
$this->b = 128;
|
305 |
$this->hash = array($this, '_sha512');
|
306 |
break;
|
307 |
case 'sha1':
|
308 |
default:
|
309 |
+
$this->b = 64;
|
310 |
$this->hash = array($this, '_sha1');
|
311 |
}
|
312 |
|
313 |
$this->ipad = str_repeat(chr(0x36), $this->b);
|
314 |
$this->opad = str_repeat(chr(0x5C), $this->b);
|
|
|
|
|
315 |
}
|
316 |
|
317 |
/**
|
328 |
if (!empty($this->key) || is_string($this->key)) {
|
329 |
switch ($mode) {
|
330 |
case CRYPT_HASH_MODE_MHASH:
|
331 |
+
$output = mhash($this->hash, $text, $this->key);
|
332 |
break;
|
333 |
case CRYPT_HASH_MODE_HASH:
|
334 |
+
$output = hash_hmac($this->hash, $text, $this->key, true);
|
335 |
break;
|
336 |
case CRYPT_HASH_MODE_INTERNAL:
|
337 |
+
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
338 |
+
resultant L byte string as the actual key to HMAC."
|
339 |
+
|
340 |
+
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
341 |
+
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
|
342 |
+
|
343 |
+
$key = str_pad($key, $this->b, chr(0)); // step 1
|
344 |
+
$temp = $this->ipad ^ $key; // step 2
|
345 |
+
$temp .= $text; // step 3
|
346 |
+
$temp = call_user_func($this->hash, $temp); // step 4
|
347 |
+
$output = $this->opad ^ $key; // step 5
|
348 |
+
$output.= $temp; // step 6
|
349 |
+
$output = call_user_func($this->hash, $output); // step 7
|
350 |
}
|
351 |
} else {
|
352 |
switch ($mode) {
|
phpseclib/File/ASN1.php
CHANGED
@@ -390,9 +390,6 @@ class File_ASN1
|
|
390 |
$remainingLength = $length;
|
391 |
while ($remainingLength > 0) {
|
392 |
$temp = $this->_decode_ber($content, $start, $content_pos);
|
393 |
-
if ($temp === false) {
|
394 |
-
break;
|
395 |
-
}
|
396 |
$length = $temp['length'];
|
397 |
// end-of-content octets - see paragraph 8.1.5
|
398 |
if (substr($content, $content_pos + $length, 2) == "\0\0") {
|
@@ -444,9 +441,6 @@ class File_ASN1
|
|
444 |
$current['content'] = substr($content, $content_pos);
|
445 |
} else {
|
446 |
$temp = $this->_decode_ber($content, $start, $content_pos);
|
447 |
-
if ($temp === false) {
|
448 |
-
return false;
|
449 |
-
}
|
450 |
$length-= (strlen($content) - $content_pos);
|
451 |
$last = count($temp) - 1;
|
452 |
for ($i = 0; $i < $last; $i++) {
|
@@ -471,9 +465,6 @@ class File_ASN1
|
|
471 |
$length = 0;
|
472 |
while (substr($content, $content_pos, 2) != "\0\0") {
|
473 |
$temp = $this->_decode_ber($content, $length + $start, $content_pos);
|
474 |
-
if ($temp === false) {
|
475 |
-
return false;
|
476 |
-
}
|
477 |
$content_pos += $temp['length'];
|
478 |
// all subtags should be octet strings
|
479 |
//if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
|
@@ -506,9 +497,6 @@ class File_ASN1
|
|
506 |
break 2;
|
507 |
}
|
508 |
$temp = $this->_decode_ber($content, $start + $offset, $content_pos);
|
509 |
-
if ($temp === false) {
|
510 |
-
return false;
|
511 |
-
}
|
512 |
$content_pos += $temp['length'];
|
513 |
$current['content'][] = $temp;
|
514 |
$offset+= $temp['length'];
|
390 |
$remainingLength = $length;
|
391 |
while ($remainingLength > 0) {
|
392 |
$temp = $this->_decode_ber($content, $start, $content_pos);
|
|
|
|
|
|
|
393 |
$length = $temp['length'];
|
394 |
// end-of-content octets - see paragraph 8.1.5
|
395 |
if (substr($content, $content_pos + $length, 2) == "\0\0") {
|
441 |
$current['content'] = substr($content, $content_pos);
|
442 |
} else {
|
443 |
$temp = $this->_decode_ber($content, $start, $content_pos);
|
|
|
|
|
|
|
444 |
$length-= (strlen($content) - $content_pos);
|
445 |
$last = count($temp) - 1;
|
446 |
for ($i = 0; $i < $last; $i++) {
|
465 |
$length = 0;
|
466 |
while (substr($content, $content_pos, 2) != "\0\0") {
|
467 |
$temp = $this->_decode_ber($content, $length + $start, $content_pos);
|
|
|
|
|
|
|
468 |
$content_pos += $temp['length'];
|
469 |
// all subtags should be octet strings
|
470 |
//if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) {
|
497 |
break 2;
|
498 |
}
|
499 |
$temp = $this->_decode_ber($content, $start + $offset, $content_pos);
|
|
|
|
|
|
|
500 |
$content_pos += $temp['length'];
|
501 |
$current['content'][] = $temp;
|
502 |
$offset+= $temp['length'];
|
phpseclib/File/X509.php
CHANGED
@@ -2122,7 +2122,7 @@ class File_X509
|
|
2122 |
*
|
2123 |
* If $date isn't defined it is assumed to be the current date.
|
2124 |
*
|
2125 |
-
* @param
|
2126 |
* @access public
|
2127 |
*/
|
2128 |
function validateDate($date = null)
|
@@ -2133,7 +2133,7 @@ class File_X509
|
|
2133 |
|
2134 |
if (!isset($date)) {
|
2135 |
$date = class_exists('DateTime') ?
|
2136 |
-
new DateTime(
|
2137 |
time();
|
2138 |
}
|
2139 |
|
@@ -2143,18 +2143,12 @@ class File_X509
|
|
2143 |
$notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
|
2144 |
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
|
2145 |
|
2146 |
-
|
2147 |
-
|
2148 |
-
|
2149 |
-
|
2150 |
-
|
2151 |
-
|
2152 |
-
break;
|
2153 |
-
case is_string($date):
|
2154 |
-
$date = @strtotime($date);
|
2155 |
-
default:
|
2156 |
-
$notBefore = @strtotime($notBefore);
|
2157 |
-
$notAfter = @strtotime($notAfter);
|
2158 |
}
|
2159 |
|
2160 |
switch (true) {
|
2122 |
*
|
2123 |
* If $date isn't defined it is assumed to be the current date.
|
2124 |
*
|
2125 |
+
* @param int $date optional
|
2126 |
* @access public
|
2127 |
*/
|
2128 |
function validateDate($date = null)
|
2133 |
|
2134 |
if (!isset($date)) {
|
2135 |
$date = class_exists('DateTime') ?
|
2136 |
+
new DateTime($date, new DateTimeZone(@date_default_timezone_get())) :
|
2137 |
time();
|
2138 |
}
|
2139 |
|
2143 |
$notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
|
2144 |
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
|
2145 |
|
2146 |
+
if (class_exists('DateTime')) {
|
2147 |
+
$notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
|
2148 |
+
$notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
|
2149 |
+
} else {
|
2150 |
+
$notBefore = @strtotime($notBefore);
|
2151 |
+
$notAfter = @strtotime($notAfter);
|
|
|
|
|
|
|
|
|
|
|
|
|
2152 |
}
|
2153 |
|
2154 |
switch (true) {
|
phpseclib/Math/BigInteger.php
CHANGED
@@ -65,6 +65,7 @@
|
|
65 |
* @author Jim Wigginton <terrafrost@php.net>
|
66 |
* @copyright 2006 Jim Wigginton
|
67 |
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
|
68 |
*/
|
69 |
|
70 |
/**#@+
|
65 |
* @author Jim Wigginton <terrafrost@php.net>
|
66 |
* @copyright 2006 Jim Wigginton
|
67 |
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
68 |
+
* @link http://pear.php.net/package/Math_BigInteger
|
69 |
*/
|
70 |
|
71 |
/**#@+
|
phpseclib/Net/SFTP.php
CHANGED
@@ -919,17 +919,7 @@ class Net_SFTP extends Net_SSH2
|
|
919 |
unset($files[$key]);
|
920 |
continue;
|
921 |
}
|
922 |
-
$
|
923 |
-
if ($key != '.' && $key != '..') {
|
924 |
-
if ($this->use_stat_cache) {
|
925 |
-
$is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)));
|
926 |
-
} else {
|
927 |
-
$stat = $this->lstat($dir . '/' . $key);
|
928 |
-
$is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY;
|
929 |
-
}
|
930 |
-
}
|
931 |
-
|
932 |
-
if ($is_directory) {
|
933 |
$depth++;
|
934 |
$files[$key] = $this->rawlist($dir . '/' . $key, true);
|
935 |
$depth--;
|
919 |
unset($files[$key]);
|
920 |
continue;
|
921 |
}
|
922 |
+
if ($key != '.' && $key != '..' && is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)))) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
923 |
$depth++;
|
924 |
$files[$key] = $this->rawlist($dir . '/' . $key, true);
|
925 |
$depth--;
|
phpseclib/Net/SSH2.php
CHANGED
@@ -923,22 +923,6 @@ class Net_SSH2
|
|
923 |
*/
|
924 |
var $binary_packet_buffer = false;
|
925 |
|
926 |
-
/**
|
927 |
-
* Preferred Signature Format
|
928 |
-
*
|
929 |
-
* @var string|false
|
930 |
-
* @access private
|
931 |
-
*/
|
932 |
-
var $preferred_signature_format = false;
|
933 |
-
|
934 |
-
/**
|
935 |
-
* Authentication Credentials
|
936 |
-
*
|
937 |
-
* @var array
|
938 |
-
* @access private
|
939 |
-
*/
|
940 |
-
var $auth = array();
|
941 |
-
|
942 |
/**
|
943 |
* Default Constructor.
|
944 |
*
|
@@ -1175,12 +1159,11 @@ class Net_SSH2
|
|
1175 |
}
|
1176 |
$elapsed = strtok(microtime(), ' ') + strtok('') - $start;
|
1177 |
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
}
|
1184 |
}
|
1185 |
}
|
1186 |
|
@@ -1229,7 +1212,6 @@ class Net_SSH2
|
|
1229 |
}
|
1230 |
|
1231 |
if (feof($this->fsock)) {
|
1232 |
-
$this->bitmap = 0;
|
1233 |
user_error('Connection closed by server');
|
1234 |
return false;
|
1235 |
}
|
@@ -1241,7 +1223,7 @@ class Net_SSH2
|
|
1241 |
|
1242 |
$this->server_identifier = trim($temp, "\r\n");
|
1243 |
if (strlen($extra)) {
|
1244 |
-
$this->errors[] = $extra;
|
1245 |
}
|
1246 |
|
1247 |
if (version_compare($matches[1], '1.99', '<')) {
|
@@ -1256,7 +1238,6 @@ class Net_SSH2
|
|
1256 |
if (!$this->send_kex_first) {
|
1257 |
$response = $this->_get_binary_packet();
|
1258 |
if ($response === false) {
|
1259 |
-
$this->bitmap = 0;
|
1260 |
user_error('Connection closed by server');
|
1261 |
return false;
|
1262 |
}
|
@@ -1328,8 +1309,6 @@ class Net_SSH2
|
|
1328 |
);
|
1329 |
|
1330 |
static $server_host_key_algorithms = array(
|
1331 |
-
'rsa-sha2-256', // RFC 8332
|
1332 |
-
'rsa-sha2-512', // RFC 8332
|
1333 |
'ssh-rsa', // RECOMMENDED sign Raw RSA Key
|
1334 |
'ssh-dss' // REQUIRED sign Raw DSS Key
|
1335 |
);
|
@@ -1489,7 +1468,6 @@ class Net_SSH2
|
|
1489 |
|
1490 |
$kexinit_payload_server = $this->_get_binary_packet();
|
1491 |
if ($kexinit_payload_server === false) {
|
1492 |
-
$this->bitmap = 0;
|
1493 |
user_error('Connection closed by server');
|
1494 |
return false;
|
1495 |
}
|
@@ -1617,7 +1595,6 @@ class Net_SSH2
|
|
1617 |
|
1618 |
$response = $this->_get_binary_packet();
|
1619 |
if ($response === false) {
|
1620 |
-
$this->bitmap = 0;
|
1621 |
user_error('Connection closed by server');
|
1622 |
return false;
|
1623 |
}
|
@@ -1713,14 +1690,12 @@ class Net_SSH2
|
|
1713 |
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
|
1714 |
|
1715 |
if (!$this->_send_binary_packet($data)) {
|
1716 |
-
$this->bitmap = 0;
|
1717 |
user_error('Connection closed by server');
|
1718 |
return false;
|
1719 |
}
|
1720 |
|
1721 |
$response = $this->_get_binary_packet();
|
1722 |
if ($response === false) {
|
1723 |
-
$this->bitmap = 0;
|
1724 |
user_error('Connection closed by server');
|
1725 |
return false;
|
1726 |
}
|
@@ -1801,18 +1776,7 @@ class Net_SSH2
|
|
1801 |
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1802 |
}
|
1803 |
|
1804 |
-
|
1805 |
-
case 'ssh-dss':
|
1806 |
-
$expected_key_format = 'ssh-dss';
|
1807 |
-
break;
|
1808 |
-
//case 'rsa-sha2-256':
|
1809 |
-
//case 'rsa-sha2-512':
|
1810 |
-
//case 'ssh-rsa':
|
1811 |
-
default:
|
1812 |
-
$expected_key_format = 'ssh-rsa';
|
1813 |
-
}
|
1814 |
-
|
1815 |
-
if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) {
|
1816 |
user_error('Server Host Key Algorithm Mismatch');
|
1817 |
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1818 |
}
|
@@ -1829,7 +1793,6 @@ class Net_SSH2
|
|
1829 |
$response = $this->_get_binary_packet();
|
1830 |
|
1831 |
if ($response === false) {
|
1832 |
-
$this->bitmap = 0;
|
1833 |
user_error('Connection closed by server');
|
1834 |
return false;
|
1835 |
}
|
@@ -2004,7 +1967,7 @@ class Net_SSH2
|
|
2004 |
|
2005 |
if ($this->encrypt) {
|
2006 |
if ($this->crypto_engine) {
|
2007 |
-
$this->encrypt->
|
2008 |
}
|
2009 |
$this->encrypt->enableContinuousBuffer();
|
2010 |
$this->encrypt->disablePadding();
|
@@ -2024,7 +1987,7 @@ class Net_SSH2
|
|
2024 |
|
2025 |
if ($this->decrypt) {
|
2026 |
if ($this->crypto_engine) {
|
2027 |
-
$this->decrypt->
|
2028 |
}
|
2029 |
$this->decrypt->enableContinuousBuffer();
|
2030 |
$this->decrypt->disablePadding();
|
@@ -2228,7 +2191,6 @@ class Net_SSH2
|
|
2228 |
function login($username)
|
2229 |
{
|
2230 |
$args = func_get_args();
|
2231 |
-
$this->auth[] = $args;
|
2232 |
return call_user_func_array(array(&$this, '_login'), $args);
|
2233 |
}
|
2234 |
|
@@ -2300,7 +2262,6 @@ class Net_SSH2
|
|
2300 |
}
|
2301 |
return $this->_login_helper($username, $password);
|
2302 |
}
|
2303 |
-
$this->bitmap = 0;
|
2304 |
user_error('Connection closed by server');
|
2305 |
return false;
|
2306 |
}
|
@@ -2357,7 +2318,6 @@ class Net_SSH2
|
|
2357 |
|
2358 |
$response = $this->_get_binary_packet();
|
2359 |
if ($response === false) {
|
2360 |
-
$this->bitmap = 0;
|
2361 |
user_error('Connection closed by server');
|
2362 |
return false;
|
2363 |
}
|
@@ -2416,7 +2376,6 @@ class Net_SSH2
|
|
2416 |
|
2417 |
$response = $this->_get_binary_packet();
|
2418 |
if ($response === false) {
|
2419 |
-
$this->bitmap = 0;
|
2420 |
user_error('Connection closed by server');
|
2421 |
return false;
|
2422 |
}
|
@@ -2435,7 +2394,7 @@ class Net_SSH2
|
|
2435 |
return false;
|
2436 |
}
|
2437 |
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
2438 |
-
$this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $this->_string_shift($response, $length);
|
2439 |
return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
|
2440 |
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
2441 |
// can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
|
@@ -2517,7 +2476,6 @@ class Net_SSH2
|
|
2517 |
} else {
|
2518 |
$orig = $response = $this->_get_binary_packet();
|
2519 |
if ($response === false) {
|
2520 |
-
$this->bitmap = 0;
|
2521 |
user_error('Connection closed by server');
|
2522 |
return false;
|
2523 |
}
|
@@ -2706,7 +2664,6 @@ class Net_SSH2
|
|
2706 |
|
2707 |
$response = $this->_get_binary_packet();
|
2708 |
if ($response === false) {
|
2709 |
-
$this->bitmap = 0;
|
2710 |
user_error('Connection closed by server');
|
2711 |
return false;
|
2712 |
}
|
@@ -2738,23 +2695,8 @@ class Net_SSH2
|
|
2738 |
|
2739 |
$packet = $part1 . chr(1) . $part2;
|
2740 |
$privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
2741 |
-
switch ($this->signature_format) {
|
2742 |
-
case 'rsa-sha2-512':
|
2743 |
-
$hash = 'sha512';
|
2744 |
-
$type = 'rsa-sha2-512';
|
2745 |
-
break;
|
2746 |
-
case 'rsa-sha2-256':
|
2747 |
-
$hash = 'sha256';
|
2748 |
-
$type = 'rsa-sha2-256';
|
2749 |
-
break;
|
2750 |
-
//case 'ssh-rsa':
|
2751 |
-
default:
|
2752 |
-
$hash = 'sha1';
|
2753 |
-
$type = 'ssh-rsa';
|
2754 |
-
}
|
2755 |
-
$privatekey->setHash($hash);
|
2756 |
$signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
|
2757 |
-
$signature = pack('Na*Na*', strlen(
|
2758 |
$packet.= pack('Na*', strlen($signature), $signature);
|
2759 |
|
2760 |
if (!$this->_send_binary_packet($packet)) {
|
@@ -2763,7 +2705,6 @@ class Net_SSH2
|
|
2763 |
|
2764 |
$response = $this->_get_binary_packet();
|
2765 |
if ($response === false) {
|
2766 |
-
$this->bitmap = 0;
|
2767 |
user_error('Connection closed by server');
|
2768 |
return false;
|
2769 |
}
|
@@ -2890,7 +2831,6 @@ class Net_SSH2
|
|
2890 |
|
2891 |
$response = $this->_get_binary_packet();
|
2892 |
if ($response === false) {
|
2893 |
-
$this->bitmap = 0;
|
2894 |
user_error('Connection closed by server');
|
2895 |
return false;
|
2896 |
}
|
@@ -3031,7 +2971,6 @@ class Net_SSH2
|
|
3031 |
|
3032 |
$response = $this->_get_binary_packet();
|
3033 |
if ($response === false) {
|
3034 |
-
$this->bitmap = 0;
|
3035 |
user_error('Connection closed by server');
|
3036 |
return false;
|
3037 |
}
|
@@ -3346,66 +3285,6 @@ class Net_SSH2
|
|
3346 |
return (bool) ($this->bitmap & NET_SSH2_MASK_LOGIN);
|
3347 |
}
|
3348 |
|
3349 |
-
/**
|
3350 |
-
* Pings a server connection, or tries to reconnect if the connection has gone down
|
3351 |
-
*
|
3352 |
-
* Inspired by http://php.net/manual/en/mysqli.ping.php
|
3353 |
-
*
|
3354 |
-
* @return bool
|
3355 |
-
* @access public
|
3356 |
-
*/
|
3357 |
-
function ping()
|
3358 |
-
{
|
3359 |
-
if (!$this->isAuthenticated()) {
|
3360 |
-
return false;
|
3361 |
-
}
|
3362 |
-
|
3363 |
-
$this->window_size_server_to_client[NET_SSH2_CHANNEL_KEEP_ALIVE] = $this->window_size;
|
3364 |
-
$packet_size = 0x4000;
|
3365 |
-
$packet = pack(
|
3366 |
-
'CNa*N3',
|
3367 |
-
NET_SSH2_MSG_CHANNEL_OPEN,
|
3368 |
-
strlen('session'),
|
3369 |
-
'session',
|
3370 |
-
NET_SSH2_CHANNEL_KEEP_ALIVE,
|
3371 |
-
$this->window_size_server_to_client[NET_SSH2_CHANNEL_KEEP_ALIVE],
|
3372 |
-
$packet_size
|
3373 |
-
);
|
3374 |
-
|
3375 |
-
if (!@$this->_send_binary_packet($packet)) {
|
3376 |
-
return $this->_reconnect();
|
3377 |
-
}
|
3378 |
-
|
3379 |
-
$this->channel_status[NET_SSH2_CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN;
|
3380 |
-
|
3381 |
-
$response = @$this->_get_channel_packet(NET_SSH2_CHANNEL_KEEP_ALIVE);
|
3382 |
-
if ($response !== false) {
|
3383 |
-
$this->_close_channel(NET_SSH2_CHANNEL_KEEP_ALIVE);
|
3384 |
-
return true;
|
3385 |
-
}
|
3386 |
-
|
3387 |
-
return $this->_reconnect();
|
3388 |
-
}
|
3389 |
-
|
3390 |
-
/**
|
3391 |
-
* In situ reconnect method
|
3392 |
-
*
|
3393 |
-
* @return boolean
|
3394 |
-
* @access private
|
3395 |
-
*/
|
3396 |
-
function _reconnect()
|
3397 |
-
{
|
3398 |
-
$this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
|
3399 |
-
$this->retry_connect = true;
|
3400 |
-
if (!$this->_connect()) {
|
3401 |
-
return false;
|
3402 |
-
}
|
3403 |
-
foreach ($this->auth as $auth) {
|
3404 |
-
$result = call_user_func_array(array(&$this, 'parent::login'), $auth);
|
3405 |
-
}
|
3406 |
-
return $result;
|
3407 |
-
}
|
3408 |
-
|
3409 |
/**
|
3410 |
* Resets a connection for re-use
|
3411 |
*
|
@@ -3436,8 +3315,8 @@ class Net_SSH2
|
|
3436 |
function _get_binary_packet($skip_channel_filter = false)
|
3437 |
{
|
3438 |
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
3439 |
-
$this->bitmap = 0;
|
3440 |
user_error('Connection closed prematurely');
|
|
|
3441 |
return false;
|
3442 |
}
|
3443 |
|
@@ -3480,8 +3359,8 @@ class Net_SSH2
|
|
3480 |
while ($remaining_length > 0) {
|
3481 |
$temp = fread($this->fsock, $remaining_length);
|
3482 |
if ($temp === false || feof($this->fsock)) {
|
3483 |
-
$this->bitmap = 0;
|
3484 |
user_error('Error reading from socket');
|
|
|
3485 |
return false;
|
3486 |
}
|
3487 |
$buffer.= $temp;
|
@@ -3499,8 +3378,8 @@ class Net_SSH2
|
|
3499 |
if ($this->hmac_check !== false) {
|
3500 |
$hmac = fread($this->fsock, $this->hmac_size);
|
3501 |
if ($hmac === false || strlen($hmac) != $this->hmac_size) {
|
3502 |
-
$this->bitmap = 0;
|
3503 |
user_error('Error reading socket');
|
|
|
3504 |
return false;
|
3505 |
} elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
|
3506 |
user_error('Invalid HMAC');
|
@@ -3544,7 +3423,7 @@ class Net_SSH2
|
|
3544 |
return false;
|
3545 |
}
|
3546 |
extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
|
3547 |
-
$this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . $this->_string_shift($payload, $length);
|
3548 |
$this->bitmap = 0;
|
3549 |
return false;
|
3550 |
case NET_SSH2_MSG_IGNORE:
|
@@ -3556,7 +3435,7 @@ class Net_SSH2
|
|
3556 |
return false;
|
3557 |
}
|
3558 |
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
3559 |
-
$this->errors[] = 'SSH_MSG_DEBUG: ' . $this->_string_shift($payload, $length);
|
3560 |
$payload = $this->_get_binary_packet($skip_channel_filter);
|
3561 |
break;
|
3562 |
case NET_SSH2_MSG_UNIMPLEMENTED:
|
@@ -3579,7 +3458,7 @@ class Net_SSH2
|
|
3579 |
return false;
|
3580 |
}
|
3581 |
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
3582 |
-
$this->banner_message = $this->_string_shift($payload, $length);
|
3583 |
$payload = $this->_get_binary_packet();
|
3584 |
}
|
3585 |
|
@@ -3808,7 +3687,6 @@ class Net_SSH2
|
|
3808 |
|
3809 |
$response = $this->_get_binary_packet(true);
|
3810 |
if ($response === false) {
|
3811 |
-
$this->bitmap = 0;
|
3812 |
user_error('Connection closed by server');
|
3813 |
return false;
|
3814 |
}
|
@@ -3817,6 +3695,10 @@ class Net_SSH2
|
|
3817 |
if ($client_channel == -1 && $response === true) {
|
3818 |
return true;
|
3819 |
}
|
|
|
|
|
|
|
|
|
3820 |
if (!strlen($response)) {
|
3821 |
return false;
|
3822 |
}
|
@@ -4701,8 +4583,6 @@ class Net_SSH2
|
|
4701 |
|
4702 |
break;
|
4703 |
case 'ssh-rsa':
|
4704 |
-
case 'rsa-sha2-256':
|
4705 |
-
case 'rsa-sha2-512':
|
4706 |
if (strlen($server_public_host_key) < 4) {
|
4707 |
return false;
|
4708 |
}
|
@@ -4729,18 +4609,6 @@ class Net_SSH2
|
|
4729 |
}
|
4730 |
|
4731 |
$rsa = new Crypt_RSA();
|
4732 |
-
switch ($this->signature_format) {
|
4733 |
-
case 'rsa-sha2-512':
|
4734 |
-
$hash = 'sha512';
|
4735 |
-
break;
|
4736 |
-
case 'rsa-sha2-256':
|
4737 |
-
$hash = 'sha256';
|
4738 |
-
break;
|
4739 |
-
//case 'ssh-rsa':
|
4740 |
-
default:
|
4741 |
-
$hash = 'sha1';
|
4742 |
-
}
|
4743 |
-
$rsa->setHash($hash);
|
4744 |
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
4745 |
$rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
|
4746 |
if (!$rsa->verify($this->exchange_hash, $signature)) {
|
@@ -4769,30 +4637,7 @@ class Net_SSH2
|
|
4769 |
$s = $s->modPow($e, $n);
|
4770 |
$s = $s->toBytes();
|
4771 |
|
4772 |
-
|
4773 |
-
case 'rsa-sha2-512':
|
4774 |
-
$hash = 'sha512';
|
4775 |
-
break;
|
4776 |
-
case 'rsa-sha2-256':
|
4777 |
-
$hash = 'sha256';
|
4778 |
-
break;
|
4779 |
-
//case 'ssh-rsa':
|
4780 |
-
default:
|
4781 |
-
$hash = 'sha1';
|
4782 |
-
}
|
4783 |
-
$hashObj = new Crypt_Hash($hash);
|
4784 |
-
switch ($this->signature_format) {
|
4785 |
-
case 'rsa-sha2-512':
|
4786 |
-
$h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash));
|
4787 |
-
break;
|
4788 |
-
case 'rsa-sha2-256':
|
4789 |
-
$h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash));
|
4790 |
-
break;
|
4791 |
-
//case 'ssh-rsa':
|
4792 |
-
default:
|
4793 |
-
$hash = 'sha1';
|
4794 |
-
$h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash));
|
4795 |
-
}
|
4796 |
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
|
4797 |
|
4798 |
if ($s != $h) {
|
923 |
*/
|
924 |
var $binary_packet_buffer = false;
|
925 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
926 |
/**
|
927 |
* Default Constructor.
|
928 |
*
|
1159 |
}
|
1160 |
$elapsed = strtok(microtime(), ' ') + strtok('') - $start;
|
1161 |
|
1162 |
+
$this->curTimeout-= $elapsed;
|
1163 |
+
|
1164 |
+
if ($this->curTimeout <= 0) {
|
1165 |
+
$this->is_timeout = true;
|
1166 |
+
return false;
|
|
|
1167 |
}
|
1168 |
}
|
1169 |
|
1212 |
}
|
1213 |
|
1214 |
if (feof($this->fsock)) {
|
|
|
1215 |
user_error('Connection closed by server');
|
1216 |
return false;
|
1217 |
}
|
1223 |
|
1224 |
$this->server_identifier = trim($temp, "\r\n");
|
1225 |
if (strlen($extra)) {
|
1226 |
+
$this->errors[] = utf8_decode($extra);
|
1227 |
}
|
1228 |
|
1229 |
if (version_compare($matches[1], '1.99', '<')) {
|
1238 |
if (!$this->send_kex_first) {
|
1239 |
$response = $this->_get_binary_packet();
|
1240 |
if ($response === false) {
|
|
|
1241 |
user_error('Connection closed by server');
|
1242 |
return false;
|
1243 |
}
|
1309 |
);
|
1310 |
|
1311 |
static $server_host_key_algorithms = array(
|
|
|
|
|
1312 |
'ssh-rsa', // RECOMMENDED sign Raw RSA Key
|
1313 |
'ssh-dss' // REQUIRED sign Raw DSS Key
|
1314 |
);
|
1468 |
|
1469 |
$kexinit_payload_server = $this->_get_binary_packet();
|
1470 |
if ($kexinit_payload_server === false) {
|
|
|
1471 |
user_error('Connection closed by server');
|
1472 |
return false;
|
1473 |
}
|
1595 |
|
1596 |
$response = $this->_get_binary_packet();
|
1597 |
if ($response === false) {
|
|
|
1598 |
user_error('Connection closed by server');
|
1599 |
return false;
|
1600 |
}
|
1690 |
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
|
1691 |
|
1692 |
if (!$this->_send_binary_packet($data)) {
|
|
|
1693 |
user_error('Connection closed by server');
|
1694 |
return false;
|
1695 |
}
|
1696 |
|
1697 |
$response = $this->_get_binary_packet();
|
1698 |
if ($response === false) {
|
|
|
1699 |
user_error('Connection closed by server');
|
1700 |
return false;
|
1701 |
}
|
1776 |
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1777 |
}
|
1778 |
|
1779 |
+
if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1780 |
user_error('Server Host Key Algorithm Mismatch');
|
1781 |
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1782 |
}
|
1793 |
$response = $this->_get_binary_packet();
|
1794 |
|
1795 |
if ($response === false) {
|
|
|
1796 |
user_error('Connection closed by server');
|
1797 |
return false;
|
1798 |
}
|
1967 |
|
1968 |
if ($this->encrypt) {
|
1969 |
if ($this->crypto_engine) {
|
1970 |
+
$this->encrypt->setEngine($this->crypto_engine);
|
1971 |
}
|
1972 |
$this->encrypt->enableContinuousBuffer();
|
1973 |
$this->encrypt->disablePadding();
|
1987 |
|
1988 |
if ($this->decrypt) {
|
1989 |
if ($this->crypto_engine) {
|
1990 |
+
$this->decrypt->setEngine($this->crypto_engine);
|
1991 |
}
|
1992 |
$this->decrypt->enableContinuousBuffer();
|
1993 |
$this->decrypt->disablePadding();
|
2191 |
function login($username)
|
2192 |
{
|
2193 |
$args = func_get_args();
|
|
|
2194 |
return call_user_func_array(array(&$this, '_login'), $args);
|
2195 |
}
|
2196 |
|
2262 |
}
|
2263 |
return $this->_login_helper($username, $password);
|
2264 |
}
|
|
|
2265 |
user_error('Connection closed by server');
|
2266 |
return false;
|
2267 |
}
|
2318 |
|
2319 |
$response = $this->_get_binary_packet();
|
2320 |
if ($response === false) {
|
|
|
2321 |
user_error('Connection closed by server');
|
2322 |
return false;
|
2323 |
}
|
2376 |
|
2377 |
$response = $this->_get_binary_packet();
|
2378 |
if ($response === false) {
|
|
|
2379 |
user_error('Connection closed by server');
|
2380 |
return false;
|
2381 |
}
|
2394 |
return false;
|
2395 |
}
|
2396 |
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
2397 |
+
$this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . utf8_decode($this->_string_shift($response, $length));
|
2398 |
return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
|
2399 |
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
2400 |
// can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
|
2476 |
} else {
|
2477 |
$orig = $response = $this->_get_binary_packet();
|
2478 |
if ($response === false) {
|
|
|
2479 |
user_error('Connection closed by server');
|
2480 |
return false;
|
2481 |
}
|
2664 |
|
2665 |
$response = $this->_get_binary_packet();
|
2666 |
if ($response === false) {
|
|
|
2667 |
user_error('Connection closed by server');
|
2668 |
return false;
|
2669 |
}
|
2695 |
|
2696 |
$packet = $part1 . chr(1) . $part2;
|
2697 |
$privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2698 |
$signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
|
2699 |
+
$signature = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($signature), $signature);
|
2700 |
$packet.= pack('Na*', strlen($signature), $signature);
|
2701 |
|
2702 |
if (!$this->_send_binary_packet($packet)) {
|
2705 |
|
2706 |
$response = $this->_get_binary_packet();
|
2707 |
if ($response === false) {
|
|
|
2708 |
user_error('Connection closed by server');
|
2709 |
return false;
|
2710 |
}
|
2831 |
|
2832 |
$response = $this->_get_binary_packet();
|
2833 |
if ($response === false) {
|
|
|
2834 |
user_error('Connection closed by server');
|
2835 |
return false;
|
2836 |
}
|
2971 |
|
2972 |
$response = $this->_get_binary_packet();
|
2973 |
if ($response === false) {
|
|
|
2974 |
user_error('Connection closed by server');
|
2975 |
return false;
|
2976 |
}
|
3285 |
return (bool) ($this->bitmap & NET_SSH2_MASK_LOGIN);
|
3286 |
}
|
3287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3288 |
/**
|
3289 |
* Resets a connection for re-use
|
3290 |
*
|
3315 |
function _get_binary_packet($skip_channel_filter = false)
|
3316 |
{
|
3317 |
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
|
|
3318 |
user_error('Connection closed prematurely');
|
3319 |
+
$this->bitmap = 0;
|
3320 |
return false;
|
3321 |
}
|
3322 |
|
3359 |
while ($remaining_length > 0) {
|
3360 |
$temp = fread($this->fsock, $remaining_length);
|
3361 |
if ($temp === false || feof($this->fsock)) {
|
|
|
3362 |
user_error('Error reading from socket');
|
3363 |
+
$this->bitmap = 0;
|
3364 |
return false;
|
3365 |
}
|
3366 |
$buffer.= $temp;
|
3378 |
if ($this->hmac_check !== false) {
|
3379 |
$hmac = fread($this->fsock, $this->hmac_size);
|
3380 |
if ($hmac === false || strlen($hmac) != $this->hmac_size) {
|
|
|
3381 |
user_error('Error reading socket');
|
3382 |
+
$this->bitmap = 0;
|
3383 |
return false;
|
3384 |
} elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
|
3385 |
user_error('Invalid HMAC');
|
3423 |
return false;
|
3424 |
}
|
3425 |
extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
|
3426 |
+
$this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode($this->_string_shift($payload, $length));
|
3427 |
$this->bitmap = 0;
|
3428 |
return false;
|
3429 |
case NET_SSH2_MSG_IGNORE:
|
3435 |
return false;
|
3436 |
}
|
3437 |
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
3438 |
+
$this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode($this->_string_shift($payload, $length));
|
3439 |
$payload = $this->_get_binary_packet($skip_channel_filter);
|
3440 |
break;
|
3441 |
case NET_SSH2_MSG_UNIMPLEMENTED:
|
3458 |
return false;
|
3459 |
}
|
3460 |
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
3461 |
+
$this->banner_message = utf8_decode($this->_string_shift($payload, $length));
|
3462 |
$payload = $this->_get_binary_packet();
|
3463 |
}
|
3464 |
|
3687 |
|
3688 |
$response = $this->_get_binary_packet(true);
|
3689 |
if ($response === false) {
|
|
|
3690 |
user_error('Connection closed by server');
|
3691 |
return false;
|
3692 |
}
|
3695 |
if ($client_channel == -1 && $response === true) {
|
3696 |
return true;
|
3697 |
}
|
3698 |
+
if (!strlen($response)) {
|
3699 |
+
return '';
|
3700 |
+
}
|
3701 |
+
|
3702 |
if (!strlen($response)) {
|
3703 |
return false;
|
3704 |
}
|
4583 |
|
4584 |
break;
|
4585 |
case 'ssh-rsa':
|
|
|
|
|
4586 |
if (strlen($server_public_host_key) < 4) {
|
4587 |
return false;
|
4588 |
}
|
4609 |
}
|
4610 |
|
4611 |
$rsa = new Crypt_RSA();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4612 |
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
4613 |
$rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
|
4614 |
if (!$rsa->verify($this->exchange_hash, $signature)) {
|
4637 |
$s = $s->modPow($e, $n);
|
4638 |
$s = $s->toBytes();
|
4639 |
|
4640 |
+
$h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->exchange_hash));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4641 |
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
|
4642 |
|
4643 |
if ($s != $h) {
|
phpseclib/System/SSH/Agent.php
CHANGED
@@ -202,18 +202,6 @@ class System_SSH_Agent_Identity
|
|
202 |
{
|
203 |
}
|
204 |
|
205 |
-
/**
|
206 |
-
* Set Hash
|
207 |
-
*
|
208 |
-
* ssh-agent doesn't support using hashes for RSA other than SHA1
|
209 |
-
*
|
210 |
-
* @param string $hash
|
211 |
-
* @access public
|
212 |
-
*/
|
213 |
-
function setHash($hash)
|
214 |
-
{
|
215 |
-
}
|
216 |
-
|
217 |
/**
|
218 |
* Create a signature
|
219 |
*
|
@@ -342,14 +330,12 @@ class System_SSH_Agent
|
|
342 |
$packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
|
343 |
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
344 |
user_error('Connection closed while requesting identities');
|
345 |
-
return array();
|
346 |
}
|
347 |
|
348 |
$length = current(unpack('N', fread($this->fsock, 4)));
|
349 |
$type = ord(fread($this->fsock, 1));
|
350 |
if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
|
351 |
user_error('Unable to request identities');
|
352 |
-
return array();
|
353 |
}
|
354 |
|
355 |
$identities = array();
|
202 |
{
|
203 |
}
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
/**
|
206 |
* Create a signature
|
207 |
*
|
330 |
$packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
|
331 |
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
332 |
user_error('Connection closed while requesting identities');
|
|
|
333 |
}
|
334 |
|
335 |
$length = current(unpack('N', fread($this->fsock, 4)));
|
336 |
$type = ord(fread($this->fsock, 1));
|
337 |
if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
|
338 |
user_error('Unable to request identities');
|
|
|
339 |
}
|
340 |
|
341 |
$identities = array();
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: http://sourceforge.net/donate/index.php?group_id=198487
|
|
4 |
Tags: ssh, sftp
|
5 |
Requires at least: 3.1
|
6 |
Tested up to: 5.0
|
7 |
-
Stable tag: 0.
|
8 |
|
9 |
"SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
|
10 |
|
@@ -41,6 +41,14 @@ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPres
|
|
41 |
|
42 |
== Changelog ==
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
* TWEAK: Clarify the installation instructions
|
45 |
* TWEAK: Add function visibility markers throughout WP_Filesystem_SSH2
|
46 |
|
@@ -100,4 +108,4 @@ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPres
|
|
100 |
* Initial Release
|
101 |
|
102 |
== Upgrade Notice ==
|
103 |
-
* 0.
|
4 |
Tags: ssh, sftp
|
5 |
Requires at least: 3.1
|
6 |
Tested up to: 5.0
|
7 |
+
Stable tag: 0.8.0
|
8 |
|
9 |
"SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
|
10 |
|
41 |
|
42 |
== Changelog ==
|
43 |
|
44 |
+
= 0.8.0 - 2018/Dec/14 =
|
45 |
+
|
46 |
+
* TWEAK: Replaced the deprecated 'var' visibility indicator
|
47 |
+
* TWEAK: Add various sanity checks to return error codes instead of causing fatal errors if another component calls the WP_Filesystem API incorrectly
|
48 |
+
* TWEAK: Add an extra sanity check that should prevent a fatal error if a component directly requests the 'direct' filesystem method but WP won't let it have it
|
49 |
+
|
50 |
+
= 0.7.6 - 2018/Nov/26 =
|
51 |
+
|
52 |
* TWEAK: Clarify the installation instructions
|
53 |
* TWEAK: Add function visibility markers throughout WP_Filesystem_SSH2
|
54 |
|
108 |
* Initial Release
|
109 |
|
110 |
== Upgrade Notice ==
|
111 |
+
* 0.8.0 : Better handle calls from other plugins (etc.) that don't check for error conditions
|
sftp.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: SSH SFTP Updater Support
|
4 |
Plugin URI: https://wordpress.org/plugins/ssh-sftp-updater-support/
|
5 |
Description: Update your WordPress blog / plugins via SFTP without libssh2
|
6 |
-
Version: 0.
|
7 |
Author: TerraFrost, David Anderson + Team Updraft
|
8 |
Author URI: https://updraftplus.com/
|
9 |
*/
|
@@ -12,7 +12,7 @@ if (!defined('ABSPATH')) die('No direct access allowed');
|
|
12 |
|
13 |
define('SSH_SFTP_UPDATER_SUPPORT_MAIN_PATH', plugin_dir_path(__FILE__));
|
14 |
define('SSH_SFTP_UPDATER_SUPPORT_BASENAME', plugin_basename(__FILE__));
|
15 |
-
define('SSH_SFTP_UPDATER_SUPPORT_VERSION', '0.
|
16 |
define('SSH_SFTP_UPDATER_SUPPORT_URL', plugin_dir_url(__FILE__));
|
17 |
// see http://adambrown.info/p/wp_hooks/hook/<filter name>
|
18 |
add_filter('filesystem_method', 'phpseclib_filesystem_method', 10, 2); // since 2.6 - WordPress will ignore the ssh option if the php ssh extension is not loaded
|
@@ -57,7 +57,7 @@ function phpseclib_request_filesystem_credentials($value, $form_post, $type = ''
|
|
57 |
$type = get_filesystem_method(array(), $context, $allow_relaxed_file_ownership);
|
58 |
|
59 |
if ( 'direct' == $type )
|
60 |
-
return
|
61 |
|
62 |
if ( is_null( $extra_fields ) )
|
63 |
$extra_fields = array( 'version', 'locale' );
|
3 |
Plugin Name: SSH SFTP Updater Support
|
4 |
Plugin URI: https://wordpress.org/plugins/ssh-sftp-updater-support/
|
5 |
Description: Update your WordPress blog / plugins via SFTP without libssh2
|
6 |
+
Version: 0.8.0
|
7 |
Author: TerraFrost, David Anderson + Team Updraft
|
8 |
Author URI: https://updraftplus.com/
|
9 |
*/
|
12 |
|
13 |
define('SSH_SFTP_UPDATER_SUPPORT_MAIN_PATH', plugin_dir_path(__FILE__));
|
14 |
define('SSH_SFTP_UPDATER_SUPPORT_BASENAME', plugin_basename(__FILE__));
|
15 |
+
define('SSH_SFTP_UPDATER_SUPPORT_VERSION', '0.8.0');
|
16 |
define('SSH_SFTP_UPDATER_SUPPORT_URL', plugin_dir_url(__FILE__));
|
17 |
// see http://adambrown.info/p/wp_hooks/hook/<filter name>
|
18 |
add_filter('filesystem_method', 'phpseclib_filesystem_method', 10, 2); // since 2.6 - WordPress will ignore the ssh option if the php ssh extension is not loaded
|
57 |
$type = get_filesystem_method(array(), $context, $allow_relaxed_file_ownership);
|
58 |
|
59 |
if ( 'direct' == $type )
|
60 |
+
return $value;
|
61 |
|
62 |
if ( is_null( $extra_fields ) )
|
63 |
$extra_fields = array( 'version', 'locale' );
|