Version Description
2019/Apr/13 =
TWEAK: Don't require phpseclib classes if they already exist
Download this release
Release Info
Developer | DavidAnderson |
Plugin | SSH SFTP Updater Support |
Version | 0.8.1 |
Comparing to | |
See all releases |
Code changes from version 0.8.0 to 0.8.1
- class-wp-filesystem-ssh2.php +2 -2
- phpseclib/Crypt/Base.php +10 -10
- phpseclib/Crypt/Hash.php +93 -28
- phpseclib/Crypt/RSA.php +23 -10
- phpseclib/File/ASN1.php +12 -0
- phpseclib/File/X509.php +18 -9
- phpseclib/Math/BigInteger.php +0 -1
- phpseclib/Net/SCP.php +5 -0
- phpseclib/Net/SFTP.php +49 -13
- phpseclib/Net/SSH2.php +197 -30
- phpseclib/System/SSH/Agent.php +94 -19
- readme.txt +7 -3
- sftp.php +2 -2
class-wp-filesystem-ssh2.php
CHANGED
@@ -8,8 +8,8 @@
|
|
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.
|
8 |
|
9 |
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/phpseclib/');
|
10 |
|
11 |
+
if (!class_exists('Net_SFTP')) require_once('Net/SFTP.php');
|
12 |
+
if (!class_exists('Crypt_RSA')) require_once('Crypt/RSA.php');
|
13 |
|
14 |
/**
|
15 |
* WordPress Filesystem Class for implementing SSH2.
|
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 |
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);
|
@@ -754,7 +754,7 @@ class Crypt_Base
|
|
754 |
case CRYPT_MODE_STREAM:
|
755 |
return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
756 |
case CRYPT_MODE_ECB:
|
757 |
-
$result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
758 |
return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
759 |
case CRYPT_MODE_CBC:
|
760 |
$result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
|
@@ -1059,14 +1059,14 @@ class Crypt_Base
|
|
1059 |
break;
|
1060 |
case CRYPT_MODE_ECB:
|
1061 |
if (!defined('OPENSSL_RAW_DATA')) {
|
1062 |
-
$ciphertext.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
|
1063 |
}
|
1064 |
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
1065 |
break;
|
1066 |
case CRYPT_MODE_CBC:
|
1067 |
if (!defined('OPENSSL_RAW_DATA')) {
|
1068 |
$padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
|
1069 |
-
$ciphertext.= substr(openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
|
1070 |
$offset = 2 * $this->block_size;
|
1071 |
} else {
|
1072 |
$offset = $this->block_size;
|
@@ -1349,7 +1349,7 @@ class Crypt_Base
|
|
1349 |
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
1350 |
$block = substr($plaintext, $i, $block_size);
|
1351 |
if (strlen($block) > strlen($buffer['ciphertext'])) {
|
1352 |
-
$result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1353 |
$result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
1354 |
$buffer['ciphertext'].= $result;
|
1355 |
}
|
@@ -1360,7 +1360,7 @@ class Crypt_Base
|
|
1360 |
} else {
|
1361 |
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
1362 |
$block = substr($plaintext, $i, $block_size);
|
1363 |
-
$otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1364 |
$otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
|
1365 |
$this->_increment_str($xor);
|
1366 |
$ciphertext.= $block ^ $otp;
|
@@ -1404,7 +1404,7 @@ class Crypt_Base
|
|
1404 |
}
|
1405 |
if ($this->continuousBuffer) {
|
1406 |
if (!defined('OPENSSL_RAW_DATA')) {
|
1407 |
-
$encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1408 |
}
|
1409 |
$encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1410 |
if ($overflow) {
|
661 |
$count = isset($func_args[4]) ? $func_args[4] : 1000;
|
662 |
|
663 |
// Keylength
|
664 |
+
if (isset($func_args[5]) && $func_args[5] > 0) {
|
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 |
+
$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);
|
754 |
case CRYPT_MODE_STREAM:
|
755 |
return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
756 |
case CRYPT_MODE_ECB:
|
757 |
+
$result = @openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
758 |
return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
759 |
case CRYPT_MODE_CBC:
|
760 |
$result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
|
1059 |
break;
|
1060 |
case CRYPT_MODE_ECB:
|
1061 |
if (!defined('OPENSSL_RAW_DATA')) {
|
1062 |
+
$ciphertext.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
|
1063 |
}
|
1064 |
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
1065 |
break;
|
1066 |
case CRYPT_MODE_CBC:
|
1067 |
if (!defined('OPENSSL_RAW_DATA')) {
|
1068 |
$padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
|
1069 |
+
$ciphertext.= substr(@openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
|
1070 |
$offset = 2 * $this->block_size;
|
1071 |
} else {
|
1072 |
$offset = $this->block_size;
|
1349 |
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
1350 |
$block = substr($plaintext, $i, $block_size);
|
1351 |
if (strlen($block) > strlen($buffer['ciphertext'])) {
|
1352 |
+
$result = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1353 |
$result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
1354 |
$buffer['ciphertext'].= $result;
|
1355 |
}
|
1360 |
} else {
|
1361 |
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
1362 |
$block = substr($plaintext, $i, $block_size);
|
1363 |
+
$otp = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1364 |
$otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
|
1365 |
$this->_increment_str($xor);
|
1366 |
$ciphertext.= $block ^ $otp;
|
1404 |
}
|
1405 |
if ($this->continuousBuffer) {
|
1406 |
if (!defined('OPENSSL_RAW_DATA')) {
|
1407 |
+
$encryptIV.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1408 |
}
|
1409 |
$encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1410 |
if ($overflow) {
|
phpseclib/Crypt/Hash.php
CHANGED
@@ -126,6 +126,15 @@ class Crypt_Hash
|
|
126 |
*/
|
127 |
var $key = false;
|
128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
/**
|
130 |
* Outer XOR (Internal HMAC)
|
131 |
*
|
@@ -144,6 +153,15 @@ class Crypt_Hash
|
|
144 |
*/
|
145 |
var $ipad;
|
146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
/**
|
148 |
* Default Constructor.
|
149 |
*
|
@@ -192,6 +210,43 @@ class Crypt_Hash
|
|
192 |
function setKey($key = false)
|
193 |
{
|
194 |
$this->key = $key;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
}
|
196 |
|
197 |
/**
|
@@ -242,19 +297,38 @@ class Crypt_Hash
|
|
242 |
}
|
243 |
|
244 |
switch ($hash) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
case 'md2':
|
246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
|
248 |
break;
|
249 |
case 'sha384':
|
250 |
case 'sha512':
|
251 |
-
$
|
252 |
break;
|
253 |
default:
|
254 |
-
$
|
255 |
}
|
256 |
|
257 |
-
switch ($
|
258 |
case CRYPT_HASH_MODE_MHASH:
|
259 |
switch ($hash) {
|
260 |
case 'md5':
|
@@ -267,6 +341,7 @@ class Crypt_Hash
|
|
267 |
default:
|
268 |
$this->hash = MHASH_SHA1;
|
269 |
}
|
|
|
270 |
return;
|
271 |
case CRYPT_HASH_MODE_HASH:
|
272 |
switch ($hash) {
|
@@ -283,35 +358,33 @@ class Crypt_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 |
/**
|
@@ -323,33 +396,25 @@ class Crypt_Hash
|
|
323 |
*/
|
324 |
function hash($text)
|
325 |
{
|
326 |
-
$mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
327 |
-
|
328 |
if (!empty($this->key) || is_string($this->key)) {
|
329 |
-
switch ($
|
330 |
case CRYPT_HASH_MODE_MHASH:
|
331 |
-
$output = mhash($this->hash, $text, $this->
|
332 |
break;
|
333 |
case CRYPT_HASH_MODE_HASH:
|
334 |
-
$output = hash_hmac($this->hash, $text, $this->
|
335 |
break;
|
336 |
case CRYPT_HASH_MODE_INTERNAL:
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
$
|
342 |
-
|
343 |
-
$
|
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 ($
|
353 |
case CRYPT_HASH_MODE_MHASH:
|
354 |
$output = mhash($this->hash, $text);
|
355 |
break;
|
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 |
*
|
153 |
*/
|
154 |
var $ipad;
|
155 |
|
156 |
+
/**
|
157 |
+
* Engine
|
158 |
+
*
|
159 |
+
* @see self::setHash()
|
160 |
+
* @var string
|
161 |
+
* @access private
|
162 |
+
*/
|
163 |
+
var $engine;
|
164 |
+
|
165 |
/**
|
166 |
* Default Constructor.
|
167 |
*
|
210 |
function setKey($key = false)
|
211 |
{
|
212 |
$this->key = $key;
|
213 |
+
$this->_computeKey();
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Pre-compute the key used by the HMAC
|
218 |
+
*
|
219 |
+
* Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
|
220 |
+
* will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
|
221 |
+
*
|
222 |
+
* As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
|
223 |
+
* when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
|
224 |
+
* every call
|
225 |
+
*
|
226 |
+
* @access private
|
227 |
+
*/
|
228 |
+
function _computeKey()
|
229 |
+
{
|
230 |
+
if ($this->key === false) {
|
231 |
+
$this->computedKey = false;
|
232 |
+
return;
|
233 |
+
}
|
234 |
+
|
235 |
+
if (strlen($this->key) <= $this->b) {
|
236 |
+
$this->computedKey = $this->key;
|
237 |
+
return;
|
238 |
+
}
|
239 |
+
|
240 |
+
switch ($this->engine) {
|
241 |
+
case CRYPT_HASH_MODE_MHASH:
|
242 |
+
$this->computedKey = mhash($this->hash, $this->key);
|
243 |
+
break;
|
244 |
+
case CRYPT_HASH_MODE_HASH:
|
245 |
+
$this->computedKey = hash($this->hash, $this->key, true);
|
246 |
+
break;
|
247 |
+
case CRYPT_HASH_MODE_INTERNAL:
|
248 |
+
$this->computedKey = call_user_func($this->hash, $this->key);
|
249 |
+
}
|
250 |
}
|
251 |
|
252 |
/**
|
297 |
}
|
298 |
|
299 |
switch ($hash) {
|
300 |
+
case 'md2-96':
|
301 |
+
case 'md2':
|
302 |
+
$this->b = 16;
|
303 |
+
case 'md5-96':
|
304 |
+
case 'sha1-96':
|
305 |
+
case 'sha224-96':
|
306 |
+
case 'sha256-96':
|
307 |
case 'md2':
|
308 |
+
case 'md5':
|
309 |
+
case 'sha1':
|
310 |
+
case 'sha224':
|
311 |
+
case 'sha256':
|
312 |
+
$this->b = 64;
|
313 |
+
break;
|
314 |
+
default:
|
315 |
+
$this->b = 128;
|
316 |
+
}
|
317 |
+
|
318 |
+
switch ($hash) {
|
319 |
+
case 'md2':
|
320 |
+
$this->engine = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
|
321 |
CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
|
322 |
break;
|
323 |
case 'sha384':
|
324 |
case 'sha512':
|
325 |
+
$this->engine = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
326 |
break;
|
327 |
default:
|
328 |
+
$this->engine = CRYPT_HASH_MODE;
|
329 |
}
|
330 |
|
331 |
+
switch ($this->engine) {
|
332 |
case CRYPT_HASH_MODE_MHASH:
|
333 |
switch ($hash) {
|
334 |
case 'md5':
|
341 |
default:
|
342 |
$this->hash = MHASH_SHA1;
|
343 |
}
|
344 |
+
$this->_computeKey();
|
345 |
return;
|
346 |
case CRYPT_HASH_MODE_HASH:
|
347 |
switch ($hash) {
|
358 |
default:
|
359 |
$this->hash = 'sha1';
|
360 |
}
|
361 |
+
$this->_computeKey();
|
362 |
return;
|
363 |
}
|
364 |
|
365 |
switch ($hash) {
|
366 |
case 'md2':
|
|
|
367 |
$this->hash = array($this, '_md2');
|
368 |
break;
|
369 |
case 'md5':
|
|
|
370 |
$this->hash = array($this, '_md5');
|
371 |
break;
|
372 |
case 'sha256':
|
|
|
373 |
$this->hash = array($this, '_sha256');
|
374 |
break;
|
375 |
case 'sha384':
|
376 |
case 'sha512':
|
|
|
377 |
$this->hash = array($this, '_sha512');
|
378 |
break;
|
379 |
case 'sha1':
|
380 |
default:
|
|
|
381 |
$this->hash = array($this, '_sha1');
|
382 |
}
|
383 |
|
384 |
$this->ipad = str_repeat(chr(0x36), $this->b);
|
385 |
$this->opad = str_repeat(chr(0x5C), $this->b);
|
386 |
+
|
387 |
+
$this->_computeKey();
|
388 |
}
|
389 |
|
390 |
/**
|
396 |
*/
|
397 |
function hash($text)
|
398 |
{
|
|
|
|
|
399 |
if (!empty($this->key) || is_string($this->key)) {
|
400 |
+
switch ($this->engine) {
|
401 |
case CRYPT_HASH_MODE_MHASH:
|
402 |
+
$output = mhash($this->hash, $text, $this->computedKey);
|
403 |
break;
|
404 |
case CRYPT_HASH_MODE_HASH:
|
405 |
+
$output = hash_hmac($this->hash, $text, $this->computedKey, true);
|
406 |
break;
|
407 |
case CRYPT_HASH_MODE_INTERNAL:
|
408 |
+
$key = str_pad($this->computedKey, $this->b, chr(0)); // step 1
|
409 |
+
$temp = $this->ipad ^ $key; // step 2
|
410 |
+
$temp .= $text; // step 3
|
411 |
+
$temp = call_user_func($this->hash, $temp); // step 4
|
412 |
+
$output = $this->opad ^ $key; // step 5
|
413 |
+
$output.= $temp; // step 6
|
414 |
+
$output = call_user_func($this->hash, $output); // step 7
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
}
|
416 |
} else {
|
417 |
+
switch ($this->engine) {
|
418 |
case CRYPT_HASH_MODE_MHASH:
|
419 |
$output = mhash($this->hash, $text);
|
420 |
break;
|
phpseclib/Crypt/RSA.php
CHANGED
@@ -1415,9 +1415,14 @@ class Crypt_RSA
|
|
1415 |
xml_set_character_data_handler($xml, '_data_handler');
|
1416 |
// add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
|
1417 |
if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
|
|
|
|
|
1418 |
return false;
|
1419 |
}
|
1420 |
|
|
|
|
|
|
|
1421 |
return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
|
1422 |
// from PuTTY's SSHPUBK.C
|
1423 |
case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
|
@@ -2300,12 +2305,13 @@ class Crypt_RSA
|
|
2300 |
return false;
|
2301 |
}
|
2302 |
|
2303 |
-
$result = 0;
|
|
|
2304 |
for ($i = 0; $i < strlen($x); $i++) {
|
2305 |
-
$result
|
2306 |
}
|
2307 |
|
2308 |
-
return $result
|
2309 |
}
|
2310 |
|
2311 |
/**
|
@@ -2512,19 +2518,26 @@ class Crypt_RSA
|
|
2512 |
$db = $maskedDB ^ $dbMask;
|
2513 |
$lHash2 = substr($db, 0, $this->hLen);
|
2514 |
$m = substr($db, $this->hLen);
|
2515 |
-
|
2516 |
-
|
2517 |
-
|
2518 |
-
|
2519 |
-
$
|
2520 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2521 |
user_error('Decryption error');
|
2522 |
return false;
|
2523 |
}
|
2524 |
|
2525 |
// Output the message M
|
2526 |
|
2527 |
-
return substr($m, 1);
|
2528 |
}
|
2529 |
|
2530 |
/**
|
1415 |
xml_set_character_data_handler($xml, '_data_handler');
|
1416 |
// add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
|
1417 |
if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
|
1418 |
+
xml_parser_free($xml);
|
1419 |
+
unset($xml);
|
1420 |
return false;
|
1421 |
}
|
1422 |
|
1423 |
+
xml_parser_free($xml);
|
1424 |
+
unset($xml);
|
1425 |
+
|
1426 |
return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
|
1427 |
// from PuTTY's SSHPUBK.C
|
1428 |
case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
|
2305 |
return false;
|
2306 |
}
|
2307 |
|
2308 |
+
$result = "\0";
|
2309 |
+
$x^= $y;
|
2310 |
for ($i = 0; $i < strlen($x); $i++) {
|
2311 |
+
$result|= $x[$i];
|
2312 |
}
|
2313 |
|
2314 |
+
return $result === "\0";
|
2315 |
}
|
2316 |
|
2317 |
/**
|
2518 |
$db = $maskedDB ^ $dbMask;
|
2519 |
$lHash2 = substr($db, 0, $this->hLen);
|
2520 |
$m = substr($db, $this->hLen);
|
2521 |
+
$hashesMatch = $this->_equals($lHash, $lHash2);
|
2522 |
+
$leadingZeros = 1;
|
2523 |
+
$patternMatch = 0;
|
2524 |
+
$offset = 0;
|
2525 |
+
for ($i = 0; $i < strlen($m); $i++) {
|
2526 |
+
$patternMatch|= $leadingZeros & ($m[$i] === "\1");
|
2527 |
+
$leadingZeros&= $m[$i] === "\0";
|
2528 |
+
$offset+= $patternMatch ? 0 : 1;
|
2529 |
+
}
|
2530 |
+
|
2531 |
+
// we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation
|
2532 |
+
// to protect against timing attacks
|
2533 |
+
if (!$hashesMatch & !$patternMatch) {
|
2534 |
user_error('Decryption error');
|
2535 |
return false;
|
2536 |
}
|
2537 |
|
2538 |
// Output the message M
|
2539 |
|
2540 |
+
return substr($m, $offset + 1);
|
2541 |
}
|
2542 |
|
2543 |
/**
|
phpseclib/File/ASN1.php
CHANGED
@@ -390,6 +390,9 @@ class File_ASN1
|
|
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,6 +444,9 @@ class File_ASN1
|
|
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,6 +471,9 @@ class File_ASN1
|
|
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,6 +506,9 @@ class File_ASN1
|
|
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'];
|
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 |
$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 |
$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 |
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'];
|
phpseclib/File/X509.php
CHANGED
@@ -1958,6 +1958,9 @@ class File_X509
|
|
1958 |
// "Certificate Transparency"
|
1959 |
// https://tools.ietf.org/html/rfc6962
|
1960 |
case '1.3.6.1.4.1.11129.2.4.2':
|
|
|
|
|
|
|
1961 |
return true;
|
1962 |
|
1963 |
// CSR attributes
|
@@ -2122,7 +2125,7 @@ class File_X509
|
|
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,7 +2136,7 @@ class File_X509
|
|
2133 |
|
2134 |
if (!isset($date)) {
|
2135 |
$date = class_exists('DateTime') ?
|
2136 |
-
new DateTime(
|
2137 |
time();
|
2138 |
}
|
2139 |
|
@@ -2143,12 +2146,18 @@ 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 |
}
|
2153 |
|
2154 |
switch (true) {
|
@@ -2968,7 +2977,7 @@ class File_X509
|
|
2968 |
}
|
2969 |
$output.= $desc . '=' . $value;
|
2970 |
$result[$desc] = isset($result[$desc]) ?
|
2971 |
-
array_merge((array) $
|
2972 |
$value;
|
2973 |
$start = false;
|
2974 |
}
|
1958 |
// "Certificate Transparency"
|
1959 |
// https://tools.ietf.org/html/rfc6962
|
1960 |
case '1.3.6.1.4.1.11129.2.4.2':
|
1961 |
+
// "Qualified Certificate statements"
|
1962 |
+
// https://tools.ietf.org/html/rfc3739#section-3.2.6
|
1963 |
+
case '1.3.6.1.5.5.7.1.3':
|
1964 |
return true;
|
1965 |
|
1966 |
// CSR attributes
|
2125 |
*
|
2126 |
* If $date isn't defined it is assumed to be the current date.
|
2127 |
*
|
2128 |
+
* @param \DateTime|int|string $date optional
|
2129 |
* @access public
|
2130 |
*/
|
2131 |
function validateDate($date = null)
|
2136 |
|
2137 |
if (!isset($date)) {
|
2138 |
$date = class_exists('DateTime') ?
|
2139 |
+
new DateTime(null, new DateTimeZone(@date_default_timezone_get())) :
|
2140 |
time();
|
2141 |
}
|
2142 |
|
2146 |
$notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
|
2147 |
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
|
2148 |
|
2149 |
+
switch (true) {
|
2150 |
+
case is_string($date) && class_exists('DateTime'):
|
2151 |
+
$date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
|
2152 |
+
case is_object($date) && strtolower(get_class($date)) == 'datetime':
|
2153 |
+
$notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
|
2154 |
+
$notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
|
2155 |
+
break;
|
2156 |
+
case is_string($date):
|
2157 |
+
$date = @strtotime($date);
|
2158 |
+
default:
|
2159 |
+
$notBefore = @strtotime($notBefore);
|
2160 |
+
$notAfter = @strtotime($notAfter);
|
2161 |
}
|
2162 |
|
2163 |
switch (true) {
|
2977 |
}
|
2978 |
$output.= $desc . '=' . $value;
|
2979 |
$result[$desc] = isset($result[$desc]) ?
|
2980 |
+
array_merge((array) $result[$desc], array($value)) :
|
2981 |
$value;
|
2982 |
$start = false;
|
2983 |
}
|
phpseclib/Math/BigInteger.php
CHANGED
@@ -65,7 +65,6 @@
|
|
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 |
/**#@+
|
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 |
/**#@+
|
phpseclib/Net/SCP.php
CHANGED
@@ -180,6 +180,11 @@ class Net_SCP
|
|
180 |
return false;
|
181 |
}
|
182 |
|
|
|
|
|
|
|
|
|
|
|
183 |
if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
|
184 |
return false;
|
185 |
}
|
180 |
return false;
|
181 |
}
|
182 |
|
183 |
+
if (empty($remote_file)) {
|
184 |
+
user_error('remote_file cannot be blank', E_USER_NOTICE);
|
185 |
+
return false;
|
186 |
+
}
|
187 |
+
|
188 |
if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
|
189 |
return false;
|
190 |
}
|
phpseclib/Net/SFTP.php
CHANGED
@@ -150,11 +150,11 @@ class Net_SFTP extends Net_SSH2
|
|
150 |
* The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
|
151 |
* concurrent actions, so it's somewhat academic, here.
|
152 |
*
|
153 |
-
* @var
|
154 |
* @see self::_send_sftp_packet()
|
155 |
* @access private
|
156 |
*/
|
157 |
-
var $
|
158 |
|
159 |
/**
|
160 |
* The Packet Type
|
@@ -291,6 +291,15 @@ class Net_SFTP extends Net_SSH2
|
|
291 |
*/
|
292 |
var $canonicalize_paths = true;
|
293 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
/**
|
295 |
* Default Constructor.
|
296 |
*
|
@@ -574,7 +583,7 @@ class Net_SFTP extends Net_SSH2
|
|
574 |
}
|
575 |
*/
|
576 |
|
577 |
-
$this->
|
578 |
|
579 |
/*
|
580 |
A Note on SFTPv4/5/6 support:
|
@@ -919,7 +928,17 @@ class Net_SFTP extends Net_SSH2
|
|
919 |
unset($files[$key]);
|
920 |
continue;
|
921 |
}
|
922 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
923 |
$depth++;
|
924 |
$files[$key] = $this->rawlist($dir . '/' . $key, true);
|
925 |
$depth--;
|
@@ -2246,7 +2265,7 @@ class Net_SFTP extends Net_SSH2
|
|
2246 |
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
|
2247 |
|
2248 |
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
|
2249 |
-
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
|
2250 |
if ($fclose_check) {
|
2251 |
fclose($fp);
|
2252 |
}
|
@@ -2261,15 +2280,17 @@ class Net_SFTP extends Net_SSH2
|
|
2261 |
break;
|
2262 |
}
|
2263 |
|
|
|
|
|
2264 |
$clear_responses = false;
|
2265 |
while ($i > 0) {
|
2266 |
$i--;
|
2267 |
|
2268 |
if ($clear_responses) {
|
2269 |
-
$this->_get_sftp_packet();
|
2270 |
continue;
|
2271 |
} else {
|
2272 |
-
$response = $this->_get_sftp_packet();
|
2273 |
}
|
2274 |
|
2275 |
switch ($this->packet_type) {
|
@@ -2978,10 +2999,10 @@ class Net_SFTP extends Net_SSH2
|
|
2978 |
* @return bool
|
2979 |
* @access private
|
2980 |
*/
|
2981 |
-
function _send_sftp_packet($type, $data)
|
2982 |
{
|
2983 |
-
$packet = $this->
|
2984 |
-
pack('NCNa*', strlen($data) + 5, $type, $
|
2985 |
pack('NCa*', strlen($data) + 1, $type, $data);
|
2986 |
|
2987 |
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
@@ -3019,8 +3040,15 @@ class Net_SFTP extends Net_SSH2
|
|
3019 |
* @return string
|
3020 |
* @access private
|
3021 |
*/
|
3022 |
-
function _get_sftp_packet()
|
3023 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3024 |
$this->curTimeout = false;
|
3025 |
|
3026 |
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
@@ -3058,8 +3086,8 @@ class Net_SFTP extends Net_SSH2
|
|
3058 |
|
3059 |
$this->packet_type = ord($this->_string_shift($this->packet_buffer));
|
3060 |
|
3061 |
-
if ($this->
|
3062 |
-
$this->_string_shift($this->packet_buffer, 4); // remove the request id
|
3063 |
$length-= 5; // account for the request id and the packet type
|
3064 |
} else {
|
3065 |
$length-= 1; // account for the packet type
|
@@ -3082,6 +3110,14 @@ class Net_SFTP extends Net_SSH2
|
|
3082 |
}
|
3083 |
}
|
3084 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3085 |
return $packet;
|
3086 |
}
|
3087 |
|
150 |
* The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
|
151 |
* concurrent actions, so it's somewhat academic, here.
|
152 |
*
|
153 |
+
* @var boolean
|
154 |
* @see self::_send_sftp_packet()
|
155 |
* @access private
|
156 |
*/
|
157 |
+
var $use_request_id = false;
|
158 |
|
159 |
/**
|
160 |
* The Packet Type
|
291 |
*/
|
292 |
var $canonicalize_paths = true;
|
293 |
|
294 |
+
/**
|
295 |
+
* Request Buffers
|
296 |
+
*
|
297 |
+
* @see self::_get_sftp_packet()
|
298 |
+
* @var array
|
299 |
+
* @access private
|
300 |
+
*/
|
301 |
+
var $requestBuffer = array();
|
302 |
+
|
303 |
/**
|
304 |
* Default Constructor.
|
305 |
*
|
583 |
}
|
584 |
*/
|
585 |
|
586 |
+
$this->use_request_id = true;
|
587 |
|
588 |
/*
|
589 |
A Note on SFTPv4/5/6 support:
|
928 |
unset($files[$key]);
|
929 |
continue;
|
930 |
}
|
931 |
+
$is_directory = false;
|
932 |
+
if ($key != '.' && $key != '..') {
|
933 |
+
if ($this->use_stat_cache) {
|
934 |
+
$is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)));
|
935 |
+
} else {
|
936 |
+
$stat = $this->lstat($dir . '/' . $key);
|
937 |
+
$is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY;
|
938 |
+
}
|
939 |
+
}
|
940 |
+
|
941 |
+
if ($is_directory) {
|
942 |
$depth++;
|
943 |
$files[$key] = $this->rawlist($dir . '/' . $key, true);
|
944 |
$depth--;
|
2265 |
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
|
2266 |
|
2267 |
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
|
2268 |
+
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet, $i)) {
|
2269 |
if ($fclose_check) {
|
2270 |
fclose($fp);
|
2271 |
}
|
2280 |
break;
|
2281 |
}
|
2282 |
|
2283 |
+
$packets_sent = $i - 1;
|
2284 |
+
|
2285 |
$clear_responses = false;
|
2286 |
while ($i > 0) {
|
2287 |
$i--;
|
2288 |
|
2289 |
if ($clear_responses) {
|
2290 |
+
$this->_get_sftp_packet($packets_sent - $i);
|
2291 |
continue;
|
2292 |
} else {
|
2293 |
+
$response = $this->_get_sftp_packet($packets_sent - $i);
|
2294 |
}
|
2295 |
|
2296 |
switch ($this->packet_type) {
|
2999 |
* @return bool
|
3000 |
* @access private
|
3001 |
*/
|
3002 |
+
function _send_sftp_packet($type, $data, $request_id = 1)
|
3003 |
{
|
3004 |
+
$packet = $this->use_request_id ?
|
3005 |
+
pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) :
|
3006 |
pack('NCa*', strlen($data) + 1, $type, $data);
|
3007 |
|
3008 |
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
3040 |
* @return string
|
3041 |
* @access private
|
3042 |
*/
|
3043 |
+
function _get_sftp_packet($request_id = null)
|
3044 |
{
|
3045 |
+
if (isset($request_id) && isset($this->requestBuffer[$request_id])) {
|
3046 |
+
$this->packet_type = $this->requestBuffer[$request_id]['packet_type'];
|
3047 |
+
$temp = $this->requestBuffer[$request_id]['packet'];
|
3048 |
+
unset($this->requestBuffer[$request_id]);
|
3049 |
+
return $temp;
|
3050 |
+
}
|
3051 |
+
|
3052 |
$this->curTimeout = false;
|
3053 |
|
3054 |
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
3086 |
|
3087 |
$this->packet_type = ord($this->_string_shift($this->packet_buffer));
|
3088 |
|
3089 |
+
if ($this->use_request_id) {
|
3090 |
+
extract(unpack('Npacket_id', $this->_string_shift($this->packet_buffer, 4))); // remove the request id
|
3091 |
$length-= 5; // account for the request id and the packet type
|
3092 |
} else {
|
3093 |
$length-= 1; // account for the packet type
|
3110 |
}
|
3111 |
}
|
3112 |
|
3113 |
+
if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) {
|
3114 |
+
$this->requestBuffer[$packet_id] = array(
|
3115 |
+
'packet_type' => $this->packet_type,
|
3116 |
+
'packet' => $packet
|
3117 |
+
);
|
3118 |
+
return $this->_get_sftp_packet($request_id);
|
3119 |
+
}
|
3120 |
+
|
3121 |
return $packet;
|
3122 |
}
|
3123 |
|
phpseclib/Net/SSH2.php
CHANGED
@@ -96,10 +96,11 @@ define('NET_SSH2_MASK_WINDOW_ADJUST', 0x00000020);
|
|
96 |
* @see self::_get_channel_packet()
|
97 |
* @access private
|
98 |
*/
|
99 |
-
define('NET_SSH2_CHANNEL_EXEC',
|
100 |
-
define('NET_SSH2_CHANNEL_SHELL',
|
101 |
-
define('NET_SSH2_CHANNEL_SUBSYSTEM',
|
102 |
define('NET_SSH2_CHANNEL_AGENT_FORWARD', 4);
|
|
|
103 |
/**#@-*/
|
104 |
|
105 |
/**#@+
|
@@ -923,6 +924,22 @@ class Net_SSH2
|
|
923 |
*/
|
924 |
var $binary_packet_buffer = false;
|
925 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
926 |
/**
|
927 |
* Default Constructor.
|
928 |
*
|
@@ -1159,11 +1176,12 @@ class Net_SSH2
|
|
1159 |
}
|
1160 |
$elapsed = strtok(microtime(), ' ') + strtok('') - $start;
|
1161 |
|
1162 |
-
$this->curTimeout
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
|
|
1167 |
}
|
1168 |
}
|
1169 |
|
@@ -1212,6 +1230,7 @@ class Net_SSH2
|
|
1212 |
}
|
1213 |
|
1214 |
if (feof($this->fsock)) {
|
|
|
1215 |
user_error('Connection closed by server');
|
1216 |
return false;
|
1217 |
}
|
@@ -1223,7 +1242,7 @@ class Net_SSH2
|
|
1223 |
|
1224 |
$this->server_identifier = trim($temp, "\r\n");
|
1225 |
if (strlen($extra)) {
|
1226 |
-
$this->errors[] =
|
1227 |
}
|
1228 |
|
1229 |
if (version_compare($matches[1], '1.99', '<')) {
|
@@ -1238,6 +1257,7 @@ class Net_SSH2
|
|
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,6 +1329,8 @@ class Net_SSH2
|
|
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,6 +1490,7 @@ class Net_SSH2
|
|
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,6 +1618,7 @@ class Net_SSH2
|
|
1595 |
|
1596 |
$response = $this->_get_binary_packet();
|
1597 |
if ($response === false) {
|
|
|
1598 |
user_error('Connection closed by server');
|
1599 |
return false;
|
1600 |
}
|
@@ -1690,12 +1714,14 @@ class Net_SSH2
|
|
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,9 +1802,25 @@ class Net_SSH2
|
|
1776 |
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1777 |
}
|
1778 |
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1782 |
}
|
1783 |
|
1784 |
$packet = pack(
|
@@ -1793,6 +1835,7 @@ class Net_SSH2
|
|
1793 |
$response = $this->_get_binary_packet();
|
1794 |
|
1795 |
if ($response === false) {
|
|
|
1796 |
user_error('Connection closed by server');
|
1797 |
return false;
|
1798 |
}
|
@@ -1967,7 +2010,7 @@ class Net_SSH2
|
|
1967 |
|
1968 |
if ($this->encrypt) {
|
1969 |
if ($this->crypto_engine) {
|
1970 |
-
$this->encrypt->
|
1971 |
}
|
1972 |
$this->encrypt->enableContinuousBuffer();
|
1973 |
$this->encrypt->disablePadding();
|
@@ -1987,7 +2030,7 @@ class Net_SSH2
|
|
1987 |
|
1988 |
if ($this->decrypt) {
|
1989 |
if ($this->crypto_engine) {
|
1990 |
-
$this->decrypt->
|
1991 |
}
|
1992 |
$this->decrypt->enableContinuousBuffer();
|
1993 |
$this->decrypt->disablePadding();
|
@@ -2191,6 +2234,7 @@ class Net_SSH2
|
|
2191 |
function login($username)
|
2192 |
{
|
2193 |
$args = func_get_args();
|
|
|
2194 |
return call_user_func_array(array(&$this, '_login'), $args);
|
2195 |
}
|
2196 |
|
@@ -2262,6 +2306,7 @@ class Net_SSH2
|
|
2262 |
}
|
2263 |
return $this->_login_helper($username, $password);
|
2264 |
}
|
|
|
2265 |
user_error('Connection closed by server');
|
2266 |
return false;
|
2267 |
}
|
@@ -2318,6 +2363,7 @@ class Net_SSH2
|
|
2318 |
|
2319 |
$response = $this->_get_binary_packet();
|
2320 |
if ($response === false) {
|
|
|
2321 |
user_error('Connection closed by server');
|
2322 |
return false;
|
2323 |
}
|
@@ -2376,6 +2422,7 @@ class Net_SSH2
|
|
2376 |
|
2377 |
$response = $this->_get_binary_packet();
|
2378 |
if ($response === false) {
|
|
|
2379 |
user_error('Connection closed by server');
|
2380 |
return false;
|
2381 |
}
|
@@ -2394,7 +2441,7 @@ class Net_SSH2
|
|
2394 |
return false;
|
2395 |
}
|
2396 |
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
2397 |
-
$this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' .
|
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,6 +2523,7 @@ class Net_SSH2
|
|
2476 |
} else {
|
2477 |
$orig = $response = $this->_get_binary_packet();
|
2478 |
if ($response === false) {
|
|
|
2479 |
user_error('Connection closed by server');
|
2480 |
return false;
|
2481 |
}
|
@@ -2645,6 +2693,21 @@ class Net_SSH2
|
|
2645 |
$publickey['n']
|
2646 |
);
|
2647 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2648 |
$part1 = pack(
|
2649 |
'CNa*Na*Na*',
|
2650 |
NET_SSH2_MSG_USERAUTH_REQUEST,
|
@@ -2655,7 +2718,7 @@ class Net_SSH2
|
|
2655 |
strlen('publickey'),
|
2656 |
'publickey'
|
2657 |
);
|
2658 |
-
$part2 = pack('Na*Na*', strlen(
|
2659 |
|
2660 |
$packet = $part1 . chr(0) . $part2;
|
2661 |
if (!$this->_send_binary_packet($packet)) {
|
@@ -2664,6 +2727,7 @@ class Net_SSH2
|
|
2664 |
|
2665 |
$response = $this->_get_binary_packet();
|
2666 |
if ($response === false) {
|
|
|
2667 |
user_error('Connection closed by server');
|
2668 |
return false;
|
2669 |
}
|
@@ -2695,8 +2759,9 @@ class Net_SSH2
|
|
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(
|
2700 |
$packet.= pack('Na*', strlen($signature), $signature);
|
2701 |
|
2702 |
if (!$this->_send_binary_packet($packet)) {
|
@@ -2705,6 +2770,7 @@ class Net_SSH2
|
|
2705 |
|
2706 |
$response = $this->_get_binary_packet();
|
2707 |
if ($response === false) {
|
|
|
2708 |
user_error('Connection closed by server');
|
2709 |
return false;
|
2710 |
}
|
@@ -2831,6 +2897,7 @@ class Net_SSH2
|
|
2831 |
|
2832 |
$response = $this->_get_binary_packet();
|
2833 |
if ($response === false) {
|
|
|
2834 |
user_error('Connection closed by server');
|
2835 |
return false;
|
2836 |
}
|
@@ -2971,6 +3038,7 @@ class Net_SSH2
|
|
2971 |
|
2972 |
$response = $this->_get_binary_packet();
|
2973 |
if ($response === false) {
|
|
|
2974 |
user_error('Connection closed by server');
|
2975 |
return false;
|
2976 |
}
|
@@ -3285,6 +3353,66 @@ class Net_SSH2
|
|
3285 |
return (bool) ($this->bitmap & NET_SSH2_MASK_LOGIN);
|
3286 |
}
|
3287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3288 |
/**
|
3289 |
* Resets a connection for re-use
|
3290 |
*
|
@@ -3315,8 +3443,8 @@ class Net_SSH2
|
|
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,8 +3487,8 @@ class Net_SSH2
|
|
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,8 +3506,8 @@ class Net_SSH2
|
|
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,7 +3551,7 @@ class Net_SSH2
|
|
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" .
|
3427 |
$this->bitmap = 0;
|
3428 |
return false;
|
3429 |
case NET_SSH2_MSG_IGNORE:
|
@@ -3435,7 +3563,7 @@ class Net_SSH2
|
|
3435 |
return false;
|
3436 |
}
|
3437 |
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
3438 |
-
$this->errors[] = 'SSH_MSG_DEBUG: ' .
|
3439 |
$payload = $this->_get_binary_packet($skip_channel_filter);
|
3440 |
break;
|
3441 |
case NET_SSH2_MSG_UNIMPLEMENTED:
|
@@ -3458,7 +3586,7 @@ class Net_SSH2
|
|
3458 |
return false;
|
3459 |
}
|
3460 |
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
3461 |
-
$this->banner_message =
|
3462 |
$payload = $this->_get_binary_packet();
|
3463 |
}
|
3464 |
|
@@ -3664,7 +3792,12 @@ class Net_SSH2
|
|
3664 |
$response = $this->binary_packet_buffer;
|
3665 |
$this->binary_packet_buffer = false;
|
3666 |
} else {
|
3667 |
-
|
|
|
|
|
|
|
|
|
|
|
3668 |
if ($this->curTimeout < 0) {
|
3669 |
$this->is_timeout = true;
|
3670 |
return true;
|
@@ -3687,6 +3820,7 @@ class Net_SSH2
|
|
3687 |
|
3688 |
$response = $this->_get_binary_packet(true);
|
3689 |
if ($response === false) {
|
|
|
3690 |
user_error('Connection closed by server');
|
3691 |
return false;
|
3692 |
}
|
@@ -3695,10 +3829,6 @@ class Net_SSH2
|
|
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 |
}
|
@@ -3921,8 +4051,8 @@ class Net_SSH2
|
|
3921 |
function _send_binary_packet($data, $logged = null)
|
3922 |
{
|
3923 |
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
3924 |
-
user_error('Connection closed prematurely');
|
3925 |
$this->bitmap = 0;
|
|
|
3926 |
return false;
|
3927 |
}
|
3928 |
|
@@ -4583,6 +4713,8 @@ class Net_SSH2
|
|
4583 |
|
4584 |
break;
|
4585 |
case 'ssh-rsa':
|
|
|
|
|
4586 |
if (strlen($server_public_host_key) < 4) {
|
4587 |
return false;
|
4588 |
}
|
@@ -4609,6 +4741,18 @@ class Net_SSH2
|
|
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,7 +4781,30 @@ class Net_SSH2
|
|
4637 |
$s = $s->modPow($e, $n);
|
4638 |
$s = $s->toBytes();
|
4639 |
|
4640 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4641 |
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
|
4642 |
|
4643 |
if ($s != $h) {
|
96 |
* @see self::_get_channel_packet()
|
97 |
* @access private
|
98 |
*/
|
99 |
+
define('NET_SSH2_CHANNEL_EXEC', 1); // PuTTy uses 0x100
|
100 |
+
define('NET_SSH2_CHANNEL_SHELL', 2);
|
101 |
+
define('NET_SSH2_CHANNEL_SUBSYSTEM', 3);
|
102 |
define('NET_SSH2_CHANNEL_AGENT_FORWARD', 4);
|
103 |
+
define('NET_SSH2_CHANNEL_KEEP_ALIVE', 5);
|
104 |
/**#@-*/
|
105 |
|
106 |
/**#@+
|
924 |
*/
|
925 |
var $binary_packet_buffer = false;
|
926 |
|
927 |
+
/**
|
928 |
+
* Preferred Signature Format
|
929 |
+
*
|
930 |
+
* @var string|false
|
931 |
+
* @access private
|
932 |
+
*/
|
933 |
+
var $preferred_signature_format = false;
|
934 |
+
|
935 |
+
/**
|
936 |
+
* Authentication Credentials
|
937 |
+
*
|
938 |
+
* @var array
|
939 |
+
* @access private
|
940 |
+
*/
|
941 |
+
var $auth = array();
|
942 |
+
|
943 |
/**
|
944 |
* Default Constructor.
|
945 |
*
|
1176 |
}
|
1177 |
$elapsed = strtok(microtime(), ' ') + strtok('') - $start;
|
1178 |
|
1179 |
+
if ($this->curTimeout) {
|
1180 |
+
$this->curTimeout-= $elapsed;
|
1181 |
+
if ($this->curTimeout < 0) {
|
1182 |
+
$this->is_timeout = true;
|
1183 |
+
return false;
|
1184 |
+
}
|
1185 |
}
|
1186 |
}
|
1187 |
|
1230 |
}
|
1231 |
|
1232 |
if (feof($this->fsock)) {
|
1233 |
+
$this->bitmap = 0;
|
1234 |
user_error('Connection closed by server');
|
1235 |
return false;
|
1236 |
}
|
1242 |
|
1243 |
$this->server_identifier = trim($temp, "\r\n");
|
1244 |
if (strlen($extra)) {
|
1245 |
+
$this->errors[] = $extra;
|
1246 |
}
|
1247 |
|
1248 |
if (version_compare($matches[1], '1.99', '<')) {
|
1257 |
if (!$this->send_kex_first) {
|
1258 |
$response = $this->_get_binary_packet();
|
1259 |
if ($response === false) {
|
1260 |
+
$this->bitmap = 0;
|
1261 |
user_error('Connection closed by server');
|
1262 |
return false;
|
1263 |
}
|
1329 |
);
|
1330 |
|
1331 |
static $server_host_key_algorithms = array(
|
1332 |
+
'rsa-sha2-256', // RFC 8332
|
1333 |
+
'rsa-sha2-512', // RFC 8332
|
1334 |
'ssh-rsa', // RECOMMENDED sign Raw RSA Key
|
1335 |
'ssh-dss' // REQUIRED sign Raw DSS Key
|
1336 |
);
|
1490 |
|
1491 |
$kexinit_payload_server = $this->_get_binary_packet();
|
1492 |
if ($kexinit_payload_server === false) {
|
1493 |
+
$this->bitmap = 0;
|
1494 |
user_error('Connection closed by server');
|
1495 |
return false;
|
1496 |
}
|
1618 |
|
1619 |
$response = $this->_get_binary_packet();
|
1620 |
if ($response === false) {
|
1621 |
+
$this->bitmap = 0;
|
1622 |
user_error('Connection closed by server');
|
1623 |
return false;
|
1624 |
}
|
1714 |
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
|
1715 |
|
1716 |
if (!$this->_send_binary_packet($data)) {
|
1717 |
+
$this->bitmap = 0;
|
1718 |
user_error('Connection closed by server');
|
1719 |
return false;
|
1720 |
}
|
1721 |
|
1722 |
$response = $this->_get_binary_packet();
|
1723 |
if ($response === false) {
|
1724 |
+
$this->bitmap = 0;
|
1725 |
user_error('Connection closed by server');
|
1726 |
return false;
|
1727 |
}
|
1802 |
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1803 |
}
|
1804 |
|
1805 |
+
switch ($server_host_key_algorithm) {
|
1806 |
+
case 'ssh-dss':
|
1807 |
+
$expected_key_format = 'ssh-dss';
|
1808 |
+
break;
|
1809 |
+
//case 'rsa-sha2-256':
|
1810 |
+
//case 'rsa-sha2-512':
|
1811 |
+
//case 'ssh-rsa':
|
1812 |
+
default:
|
1813 |
+
$expected_key_format = 'ssh-rsa';
|
1814 |
+
}
|
1815 |
+
|
1816 |
+
if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) {
|
1817 |
+
switch (true) {
|
1818 |
+
case $this->signature_format == $server_host_key_algorithm:
|
1819 |
+
case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512':
|
1820 |
+
case $this->signature_format != 'ssh-rsa':
|
1821 |
+
user_error('Server Host Key Algorithm Mismatch');
|
1822 |
+
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
1823 |
+
}
|
1824 |
}
|
1825 |
|
1826 |
$packet = pack(
|
1835 |
$response = $this->_get_binary_packet();
|
1836 |
|
1837 |
if ($response === false) {
|
1838 |
+
$this->bitmap = 0;
|
1839 |
user_error('Connection closed by server');
|
1840 |
return false;
|
1841 |
}
|
2010 |
|
2011 |
if ($this->encrypt) {
|
2012 |
if ($this->crypto_engine) {
|
2013 |
+
$this->encrypt->setPreferredEngine($this->crypto_engine);
|
2014 |
}
|
2015 |
$this->encrypt->enableContinuousBuffer();
|
2016 |
$this->encrypt->disablePadding();
|
2030 |
|
2031 |
if ($this->decrypt) {
|
2032 |
if ($this->crypto_engine) {
|
2033 |
+
$this->decrypt->setPreferredEngine($this->crypto_engine);
|
2034 |
}
|
2035 |
$this->decrypt->enableContinuousBuffer();
|
2036 |
$this->decrypt->disablePadding();
|
2234 |
function login($username)
|
2235 |
{
|
2236 |
$args = func_get_args();
|
2237 |
+
$this->auth[] = $args;
|
2238 |
return call_user_func_array(array(&$this, '_login'), $args);
|
2239 |
}
|
2240 |
|
2306 |
}
|
2307 |
return $this->_login_helper($username, $password);
|
2308 |
}
|
2309 |
+
$this->bitmap = 0;
|
2310 |
user_error('Connection closed by server');
|
2311 |
return false;
|
2312 |
}
|
2363 |
|
2364 |
$response = $this->_get_binary_packet();
|
2365 |
if ($response === false) {
|
2366 |
+
$this->bitmap = 0;
|
2367 |
user_error('Connection closed by server');
|
2368 |
return false;
|
2369 |
}
|
2422 |
|
2423 |
$response = $this->_get_binary_packet();
|
2424 |
if ($response === false) {
|
2425 |
+
$this->bitmap = 0;
|
2426 |
user_error('Connection closed by server');
|
2427 |
return false;
|
2428 |
}
|
2441 |
return false;
|
2442 |
}
|
2443 |
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
2444 |
+
$this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $this->_string_shift($response, $length);
|
2445 |
return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
|
2446 |
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
2447 |
// can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
|
2523 |
} else {
|
2524 |
$orig = $response = $this->_get_binary_packet();
|
2525 |
if ($response === false) {
|
2526 |
+
$this->bitmap = 0;
|
2527 |
user_error('Connection closed by server');
|
2528 |
return false;
|
2529 |
}
|
2693 |
$publickey['n']
|
2694 |
);
|
2695 |
|
2696 |
+
switch ($this->signature_format) {
|
2697 |
+
case 'rsa-sha2-512':
|
2698 |
+
$hash = 'sha512';
|
2699 |
+
$signatureType = 'rsa-sha2-512';
|
2700 |
+
break;
|
2701 |
+
case 'rsa-sha2-256':
|
2702 |
+
$hash = 'sha256';
|
2703 |
+
$signatureType = 'rsa-sha2-256';
|
2704 |
+
break;
|
2705 |
+
//case 'ssh-rsa':
|
2706 |
+
default:
|
2707 |
+
$hash = 'sha1';
|
2708 |
+
$signatureType = 'ssh-rsa';
|
2709 |
+
}
|
2710 |
+
|
2711 |
$part1 = pack(
|
2712 |
'CNa*Na*Na*',
|
2713 |
NET_SSH2_MSG_USERAUTH_REQUEST,
|
2718 |
strlen('publickey'),
|
2719 |
'publickey'
|
2720 |
);
|
2721 |
+
$part2 = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($publickey), $publickey);
|
2722 |
|
2723 |
$packet = $part1 . chr(0) . $part2;
|
2724 |
if (!$this->_send_binary_packet($packet)) {
|
2727 |
|
2728 |
$response = $this->_get_binary_packet();
|
2729 |
if ($response === false) {
|
2730 |
+
$this->bitmap = 0;
|
2731 |
user_error('Connection closed by server');
|
2732 |
return false;
|
2733 |
}
|
2759 |
|
2760 |
$packet = $part1 . chr(1) . $part2;
|
2761 |
$privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
2762 |
+
$privatekey->setHash($hash);
|
2763 |
$signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
|
2764 |
+
$signature = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($signature), $signature);
|
2765 |
$packet.= pack('Na*', strlen($signature), $signature);
|
2766 |
|
2767 |
if (!$this->_send_binary_packet($packet)) {
|
2770 |
|
2771 |
$response = $this->_get_binary_packet();
|
2772 |
if ($response === false) {
|
2773 |
+
$this->bitmap = 0;
|
2774 |
user_error('Connection closed by server');
|
2775 |
return false;
|
2776 |
}
|
2897 |
|
2898 |
$response = $this->_get_binary_packet();
|
2899 |
if ($response === false) {
|
2900 |
+
$this->bitmap = 0;
|
2901 |
user_error('Connection closed by server');
|
2902 |
return false;
|
2903 |
}
|
3038 |
|
3039 |
$response = $this->_get_binary_packet();
|
3040 |
if ($response === false) {
|
3041 |
+
$this->bitmap = 0;
|
3042 |
user_error('Connection closed by server');
|
3043 |
return false;
|
3044 |
}
|
3353 |
return (bool) ($this->bitmap & NET_SSH2_MASK_LOGIN);
|
3354 |
}
|
3355 |
|
3356 |
+
/**
|
3357 |
+
* Pings a server connection, or tries to reconnect if the connection has gone down
|
3358 |
+
*
|
3359 |
+
* Inspired by http://php.net/manual/en/mysqli.ping.php
|
3360 |
+
*
|
3361 |
+
* @return bool
|
3362 |
+
* @access public
|
3363 |
+
*/
|
3364 |
+
function ping()
|
3365 |
+
{
|
3366 |
+
if (!$this->isAuthenticated()) {
|
3367 |
+
return false;
|
3368 |
+
}
|
3369 |
+
|
3370 |
+
$this->window_size_server_to_client[NET_SSH2_CHANNEL_KEEP_ALIVE] = $this->window_size;
|
3371 |
+
$packet_size = 0x4000;
|
3372 |
+
$packet = pack(
|
3373 |
+
'CNa*N3',
|
3374 |
+
NET_SSH2_MSG_CHANNEL_OPEN,
|
3375 |
+
strlen('session'),
|
3376 |
+
'session',
|
3377 |
+
NET_SSH2_CHANNEL_KEEP_ALIVE,
|
3378 |
+
$this->window_size_server_to_client[NET_SSH2_CHANNEL_KEEP_ALIVE],
|
3379 |
+
$packet_size
|
3380 |
+
);
|
3381 |
+
|
3382 |
+
if (!@$this->_send_binary_packet($packet)) {
|
3383 |
+
return $this->_reconnect();
|
3384 |
+
}
|
3385 |
+
|
3386 |
+
$this->channel_status[NET_SSH2_CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN;
|
3387 |
+
|
3388 |
+
$response = @$this->_get_channel_packet(NET_SSH2_CHANNEL_KEEP_ALIVE);
|
3389 |
+
if ($response !== false) {
|
3390 |
+
$this->_close_channel(NET_SSH2_CHANNEL_KEEP_ALIVE);
|
3391 |
+
return true;
|
3392 |
+
}
|
3393 |
+
|
3394 |
+
return $this->_reconnect();
|
3395 |
+
}
|
3396 |
+
|
3397 |
+
/**
|
3398 |
+
* In situ reconnect method
|
3399 |
+
*
|
3400 |
+
* @return boolean
|
3401 |
+
* @access private
|
3402 |
+
*/
|
3403 |
+
function _reconnect()
|
3404 |
+
{
|
3405 |
+
$this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
|
3406 |
+
$this->retry_connect = true;
|
3407 |
+
if (!$this->_connect()) {
|
3408 |
+
return false;
|
3409 |
+
}
|
3410 |
+
foreach ($this->auth as $auth) {
|
3411 |
+
$result = call_user_func_array(array(&$this, 'parent::login'), $auth);
|
3412 |
+
}
|
3413 |
+
return $result;
|
3414 |
+
}
|
3415 |
+
|
3416 |
/**
|
3417 |
* Resets a connection for re-use
|
3418 |
*
|
3443 |
function _get_binary_packet($skip_channel_filter = false)
|
3444 |
{
|
3445 |
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
|
|
3446 |
$this->bitmap = 0;
|
3447 |
+
user_error('Connection closed prematurely');
|
3448 |
return false;
|
3449 |
}
|
3450 |
|
3487 |
while ($remaining_length > 0) {
|
3488 |
$temp = fread($this->fsock, $remaining_length);
|
3489 |
if ($temp === false || feof($this->fsock)) {
|
|
|
3490 |
$this->bitmap = 0;
|
3491 |
+
user_error('Error reading from socket');
|
3492 |
return false;
|
3493 |
}
|
3494 |
$buffer.= $temp;
|
3506 |
if ($this->hmac_check !== false) {
|
3507 |
$hmac = fread($this->fsock, $this->hmac_size);
|
3508 |
if ($hmac === false || strlen($hmac) != $this->hmac_size) {
|
|
|
3509 |
$this->bitmap = 0;
|
3510 |
+
user_error('Error reading socket');
|
3511 |
return false;
|
3512 |
} elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
|
3513 |
user_error('Invalid HMAC');
|
3551 |
return false;
|
3552 |
}
|
3553 |
extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
|
3554 |
+
$this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . $this->_string_shift($payload, $length);
|
3555 |
$this->bitmap = 0;
|
3556 |
return false;
|
3557 |
case NET_SSH2_MSG_IGNORE:
|
3563 |
return false;
|
3564 |
}
|
3565 |
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
3566 |
+
$this->errors[] = 'SSH_MSG_DEBUG: ' . $this->_string_shift($payload, $length);
|
3567 |
$payload = $this->_get_binary_packet($skip_channel_filter);
|
3568 |
break;
|
3569 |
case NET_SSH2_MSG_UNIMPLEMENTED:
|
3586 |
return false;
|
3587 |
}
|
3588 |
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
3589 |
+
$this->banner_message = $this->_string_shift($payload, $length);
|
3590 |
$payload = $this->_get_binary_packet();
|
3591 |
}
|
3592 |
|
3792 |
$response = $this->binary_packet_buffer;
|
3793 |
$this->binary_packet_buffer = false;
|
3794 |
} else {
|
3795 |
+
$read = array($this->fsock);
|
3796 |
+
$write = $except = null;
|
3797 |
+
|
3798 |
+
if (!$this->curTimeout) {
|
3799 |
+
@stream_select($read, $write, $except, null);
|
3800 |
+
} else {
|
3801 |
if ($this->curTimeout < 0) {
|
3802 |
$this->is_timeout = true;
|
3803 |
return true;
|
3820 |
|
3821 |
$response = $this->_get_binary_packet(true);
|
3822 |
if ($response === false) {
|
3823 |
+
$this->bitmap = 0;
|
3824 |
user_error('Connection closed by server');
|
3825 |
return false;
|
3826 |
}
|
3829 |
if ($client_channel == -1 && $response === true) {
|
3830 |
return true;
|
3831 |
}
|
|
|
|
|
|
|
|
|
3832 |
if (!strlen($response)) {
|
3833 |
return false;
|
3834 |
}
|
4051 |
function _send_binary_packet($data, $logged = null)
|
4052 |
{
|
4053 |
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
|
|
4054 |
$this->bitmap = 0;
|
4055 |
+
user_error('Connection closed prematurely');
|
4056 |
return false;
|
4057 |
}
|
4058 |
|
4713 |
|
4714 |
break;
|
4715 |
case 'ssh-rsa':
|
4716 |
+
case 'rsa-sha2-256':
|
4717 |
+
case 'rsa-sha2-512':
|
4718 |
if (strlen($server_public_host_key) < 4) {
|
4719 |
return false;
|
4720 |
}
|
4741 |
}
|
4742 |
|
4743 |
$rsa = new Crypt_RSA();
|
4744 |
+
switch ($this->signature_format) {
|
4745 |
+
case 'rsa-sha2-512':
|
4746 |
+
$hash = 'sha512';
|
4747 |
+
break;
|
4748 |
+
case 'rsa-sha2-256':
|
4749 |
+
$hash = 'sha256';
|
4750 |
+
break;
|
4751 |
+
//case 'ssh-rsa':
|
4752 |
+
default:
|
4753 |
+
$hash = 'sha1';
|
4754 |
+
}
|
4755 |
+
$rsa->setHash($hash);
|
4756 |
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
4757 |
$rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
|
4758 |
if (!$rsa->verify($this->exchange_hash, $signature)) {
|
4781 |
$s = $s->modPow($e, $n);
|
4782 |
$s = $s->toBytes();
|
4783 |
|
4784 |
+
switch ($this->signature_format) {
|
4785 |
+
case 'rsa-sha2-512':
|
4786 |
+
$hash = 'sha512';
|
4787 |
+
break;
|
4788 |
+
case 'rsa-sha2-256':
|
4789 |
+
$hash = 'sha256';
|
4790 |
+
break;
|
4791 |
+
//case 'ssh-rsa':
|
4792 |
+
default:
|
4793 |
+
$hash = 'sha1';
|
4794 |
+
}
|
4795 |
+
$hashObj = new Crypt_Hash($hash);
|
4796 |
+
switch ($this->signature_format) {
|
4797 |
+
case 'rsa-sha2-512':
|
4798 |
+
$h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash));
|
4799 |
+
break;
|
4800 |
+
case 'rsa-sha2-256':
|
4801 |
+
$h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash));
|
4802 |
+
break;
|
4803 |
+
//case 'ssh-rsa':
|
4804 |
+
default:
|
4805 |
+
$hash = 'sha1';
|
4806 |
+
$h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash));
|
4807 |
+
}
|
4808 |
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
|
4809 |
|
4810 |
if ($s != $h) {
|
phpseclib/System/SSH/Agent.php
CHANGED
@@ -64,7 +64,7 @@ define('SYSTEM_SSH_AGENT_FAILURE', 5);
|
|
64 |
define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
|
65 |
// the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
|
66 |
define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
|
67 |
-
|
68 |
|
69 |
/**@+
|
70 |
* Agent forwarding status
|
@@ -77,7 +77,17 @@ define('SYSTEM_SSH_AGENT_FORWARD_NONE', 0);
|
|
77 |
define('SYSTEM_SSH_AGENT_FORWARD_REQUEST', 1);
|
78 |
// forwarding has been request and is active
|
79 |
define('SYSTEM_SSH_AGENT_FORWARD_ACTIVE', 2);
|
|
|
80 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
/**#@-*/
|
82 |
|
83 |
/**
|
@@ -123,6 +133,16 @@ class System_SSH_Agent_Identity
|
|
123 |
*/
|
124 |
var $fsock;
|
125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
/**
|
127 |
* Default Constructor.
|
128 |
*
|
@@ -202,6 +222,31 @@ class System_SSH_Agent_Identity
|
|
202 |
{
|
203 |
}
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
/**
|
206 |
* Create a signature
|
207 |
*
|
@@ -214,7 +259,7 @@ class System_SSH_Agent_Identity
|
|
214 |
function sign($message)
|
215 |
{
|
216 |
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
|
217 |
-
$packet = pack('CNa*Na*N', SYSTEM_SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message,
|
218 |
$packet = pack('Na*', strlen($packet), $packet);
|
219 |
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
220 |
user_error('Connection closed during signing');
|
@@ -227,9 +272,35 @@ class System_SSH_Agent_Identity
|
|
227 |
}
|
228 |
|
229 |
$signature_blob = fread($this->fsock, $length - 1);
|
230 |
-
|
231 |
-
|
232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
}
|
234 |
}
|
235 |
|
@@ -240,7 +311,7 @@ class System_SSH_Agent_Identity
|
|
240 |
*
|
241 |
* @package System_SSH_Agent
|
242 |
* @author Jim Wigginton <terrafrost@php.net>
|
243 |
-
* @access
|
244 |
*/
|
245 |
class System_SSH_Agent
|
246 |
{
|
@@ -281,18 +352,20 @@ class System_SSH_Agent
|
|
281 |
* @return System_SSH_Agent
|
282 |
* @access public
|
283 |
*/
|
284 |
-
function __construct()
|
285 |
{
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
|
|
|
|
296 |
}
|
297 |
|
298 |
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
@@ -307,9 +380,9 @@ class System_SSH_Agent
|
|
307 |
* @see self::__construct()
|
308 |
* @access public
|
309 |
*/
|
310 |
-
function System_SSH_Agent()
|
311 |
{
|
312 |
-
$this->__construct();
|
313 |
}
|
314 |
|
315 |
/**
|
@@ -330,12 +403,14 @@ class System_SSH_Agent
|
|
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();
|
64 |
define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
|
65 |
// the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
|
66 |
define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
|
67 |
+
/**#@-*/
|
68 |
|
69 |
/**@+
|
70 |
* Agent forwarding status
|
77 |
define('SYSTEM_SSH_AGENT_FORWARD_REQUEST', 1);
|
78 |
// forwarding has been request and is active
|
79 |
define('SYSTEM_SSH_AGENT_FORWARD_ACTIVE', 2);
|
80 |
+
/**#@-*/
|
81 |
|
82 |
+
/**@+
|
83 |
+
* Signature Flags
|
84 |
+
*
|
85 |
+
* See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3
|
86 |
+
*
|
87 |
+
* @access private
|
88 |
+
*/
|
89 |
+
define('SYSTEM_SSH_AGENT_RSA2_256', 2);
|
90 |
+
define('SYSTEM_SSH_AGENT_RSA2_512', 4);
|
91 |
/**#@-*/
|
92 |
|
93 |
/**
|
133 |
*/
|
134 |
var $fsock;
|
135 |
|
136 |
+
/**
|
137 |
+
* Signature flags
|
138 |
+
*
|
139 |
+
* @var int
|
140 |
+
* @access private
|
141 |
+
* @see self::sign()
|
142 |
+
* @see self::setHash()
|
143 |
+
*/
|
144 |
+
var $flags = 0;
|
145 |
+
|
146 |
/**
|
147 |
* Default Constructor.
|
148 |
*
|
222 |
{
|
223 |
}
|
224 |
|
225 |
+
/**
|
226 |
+
* Set Hash
|
227 |
+
*
|
228 |
+
* ssh-agent doesn't support using hashes for RSA other than SHA1
|
229 |
+
*
|
230 |
+
* @param string $hash
|
231 |
+
* @access public
|
232 |
+
*/
|
233 |
+
function setHash($hash)
|
234 |
+
{
|
235 |
+
$this->flags = 0;
|
236 |
+
switch ($hash) {
|
237 |
+
case 'sha1':
|
238 |
+
break;
|
239 |
+
case 'sha256':
|
240 |
+
$this->flags = SYSTEM_SSH_AGENT_RSA2_256;
|
241 |
+
break;
|
242 |
+
case 'sha512':
|
243 |
+
$this->flags = SYSTEM_SSH_AGENT_RSA2_512;
|
244 |
+
break;
|
245 |
+
default:
|
246 |
+
user_error('The only supported hashes for RSA are sha1, sha256 and sha512');
|
247 |
+
}
|
248 |
+
}
|
249 |
+
|
250 |
/**
|
251 |
* Create a signature
|
252 |
*
|
259 |
function sign($message)
|
260 |
{
|
261 |
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
|
262 |
+
$packet = pack('CNa*Na*N', SYSTEM_SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags);
|
263 |
$packet = pack('Na*', strlen($packet), $packet);
|
264 |
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
265 |
user_error('Connection closed during signing');
|
272 |
}
|
273 |
|
274 |
$signature_blob = fread($this->fsock, $length - 1);
|
275 |
+
$length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
|
276 |
+
if ($length != strlen($signature_blob)) {
|
277 |
+
user_error('Malformed signature blob');
|
278 |
+
}
|
279 |
+
$length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
|
280 |
+
if ($length > strlen($signature_blob) + 4) {
|
281 |
+
user_error('Malformed signature blob');
|
282 |
+
}
|
283 |
+
$type = $this->_string_shift($signature_blob, $length);
|
284 |
+
$this->_string_shift($signature_blob, 4);
|
285 |
+
|
286 |
+
return $signature_blob;
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* String Shift
|
291 |
+
*
|
292 |
+
* Inspired by array_shift
|
293 |
+
*
|
294 |
+
* @param string $string
|
295 |
+
* @param int $index
|
296 |
+
* @return string
|
297 |
+
* @access private
|
298 |
+
*/
|
299 |
+
function _string_shift(&$string, $index = 1)
|
300 |
+
{
|
301 |
+
$substr = substr($string, 0, $index);
|
302 |
+
$string = substr($string, $index);
|
303 |
+
return $substr;
|
304 |
}
|
305 |
}
|
306 |
|
311 |
*
|
312 |
* @package System_SSH_Agent
|
313 |
* @author Jim Wigginton <terrafrost@php.net>
|
314 |
+
* @access public
|
315 |
*/
|
316 |
class System_SSH_Agent
|
317 |
{
|
352 |
* @return System_SSH_Agent
|
353 |
* @access public
|
354 |
*/
|
355 |
+
function __construct($address = null)
|
356 |
{
|
357 |
+
if (!$address) {
|
358 |
+
switch (true) {
|
359 |
+
case isset($_SERVER['SSH_AUTH_SOCK']):
|
360 |
+
$address = $_SERVER['SSH_AUTH_SOCK'];
|
361 |
+
break;
|
362 |
+
case isset($_ENV['SSH_AUTH_SOCK']):
|
363 |
+
$address = $_ENV['SSH_AUTH_SOCK'];
|
364 |
+
break;
|
365 |
+
default:
|
366 |
+
user_error('SSH_AUTH_SOCK not found');
|
367 |
+
return false;
|
368 |
+
}
|
369 |
}
|
370 |
|
371 |
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
380 |
* @see self::__construct()
|
381 |
* @access public
|
382 |
*/
|
383 |
+
function System_SSH_Agent($address = null)
|
384 |
{
|
385 |
+
$this->__construct($address);
|
386 |
}
|
387 |
|
388 |
/**
|
403 |
$packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
|
404 |
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
405 |
user_error('Connection closed while requesting identities');
|
406 |
+
return array();
|
407 |
}
|
408 |
|
409 |
$length = current(unpack('N', fread($this->fsock, 4)));
|
410 |
$type = ord(fread($this->fsock, 1));
|
411 |
if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
|
412 |
user_error('Unable to request identities');
|
413 |
+
return array();
|
414 |
}
|
415 |
|
416 |
$identities = array();
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: DavidAnderson, TerraFrost, pmbaldha
|
|
3 |
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.
|
7 |
-
Stable tag: 0.8.
|
8 |
|
9 |
"SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
|
10 |
|
@@ -41,6 +41,10 @@ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPres
|
|
41 |
|
42 |
== Changelog ==
|
43 |
|
|
|
|
|
|
|
|
|
44 |
= 0.8.0 - 2018/Dec/14 =
|
45 |
|
46 |
* TWEAK: Replaced the deprecated 'var' visibility indicator
|
@@ -108,4 +112,4 @@ b) Others as <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPres
|
|
108 |
* Initial Release
|
109 |
|
110 |
== Upgrade Notice ==
|
111 |
-
* 0.8.
|
3 |
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.2
|
7 |
+
Stable tag: 0.8.1
|
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.1 - 2019/Apr/13 =
|
45 |
+
|
46 |
+
* TWEAK: Don't require phpseclib classes if they already exist
|
47 |
+
|
48 |
= 0.8.0 - 2018/Dec/14 =
|
49 |
|
50 |
* TWEAK: Replaced the deprecated 'var' visibility indicator
|
112 |
* Initial Release
|
113 |
|
114 |
== Upgrade Notice ==
|
115 |
+
* 0.8.1 : Don't require phpseclib classes if they already exist
|
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.8.
|
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.8.
|
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
|
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.1
|
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.1');
|
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
|