summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/phpseclib-1.0.8/Crypt/AES.php (renamed from libs/phpseclib-1.0.7/Crypt/AES.php)0
-rw-r--r--libs/phpseclib-1.0.8/Crypt/Base.php (renamed from libs/phpseclib-1.0.7/Crypt/Base.php)9
-rw-r--r--libs/phpseclib-1.0.8/Crypt/Blowfish.php (renamed from libs/phpseclib-1.0.7/Crypt/Blowfish.php)0
-rw-r--r--libs/phpseclib-1.0.8/Crypt/DES.php (renamed from libs/phpseclib-1.0.7/Crypt/DES.php)0
-rw-r--r--libs/phpseclib-1.0.8/Crypt/Hash.php (renamed from libs/phpseclib-1.0.7/Crypt/Hash.php)0
-rw-r--r--libs/phpseclib-1.0.8/Crypt/RC2.php (renamed from libs/phpseclib-1.0.7/Crypt/RC2.php)0
-rw-r--r--libs/phpseclib-1.0.8/Crypt/RC4.php (renamed from libs/phpseclib-1.0.7/Crypt/RC4.php)2
-rw-r--r--libs/phpseclib-1.0.8/Crypt/RSA.php (renamed from libs/phpseclib-1.0.7/Crypt/RSA.php)2
-rw-r--r--libs/phpseclib-1.0.8/Crypt/Random.php (renamed from libs/phpseclib-1.0.7/Crypt/Random.php)0
-rw-r--r--libs/phpseclib-1.0.8/Crypt/Rijndael.php (renamed from libs/phpseclib-1.0.7/Crypt/Rijndael.php)0
-rw-r--r--libs/phpseclib-1.0.8/Crypt/TripleDES.php (renamed from libs/phpseclib-1.0.7/Crypt/TripleDES.php)0
-rw-r--r--libs/phpseclib-1.0.8/Crypt/Twofish.php (renamed from libs/phpseclib-1.0.7/Crypt/Twofish.php)0
-rw-r--r--libs/phpseclib-1.0.8/File/ANSI.php (renamed from libs/phpseclib-1.0.7/File/ANSI.php)5
-rw-r--r--libs/phpseclib-1.0.8/File/ASN1.php (renamed from libs/phpseclib-1.0.7/File/ASN1.php)80
-rw-r--r--libs/phpseclib-1.0.8/File/X509.php (renamed from libs/phpseclib-1.0.7/File/X509.php)68
-rw-r--r--libs/phpseclib-1.0.8/Math/BigInteger.php (renamed from libs/phpseclib-1.0.7/Math/BigInteger.php)20
-rw-r--r--libs/phpseclib-1.0.8/Net/SCP.php (renamed from libs/phpseclib-1.0.7/Net/SCP.php)0
-rw-r--r--libs/phpseclib-1.0.8/Net/SFTP.php (renamed from libs/phpseclib-1.0.7/Net/SFTP.php)53
-rw-r--r--libs/phpseclib-1.0.8/Net/SFTP/Stream.php (renamed from libs/phpseclib-1.0.7/Net/SFTP/Stream.php)0
-rw-r--r--libs/phpseclib-1.0.8/Net/SSH1.php (renamed from libs/phpseclib-1.0.7/Net/SSH1.php)0
-rw-r--r--libs/phpseclib-1.0.8/Net/SSH2.php (renamed from libs/phpseclib-1.0.7/Net/SSH2.php)369
-rw-r--r--libs/phpseclib-1.0.8/System/SSH/Agent.php (renamed from libs/phpseclib-1.0.7/System/SSH/Agent.php)0
-rw-r--r--libs/phpseclib-1.0.8/System/SSH_Agent.php (renamed from libs/phpseclib-1.0.7/System/SSH_Agent.php)0
-rw-r--r--libs/phpseclib-1.0.8/bootstrap.php (renamed from libs/phpseclib-1.0.7/bootstrap.php)0
-rw-r--r--libs/phpseclib-1.0.8/openssl.cnf (renamed from libs/phpseclib-1.0.7/openssl.cnf)0
25 files changed, 497 insertions, 111 deletions
diff --git a/libs/phpseclib-1.0.7/Crypt/AES.php b/libs/phpseclib-1.0.8/Crypt/AES.php
index 594011e..594011e 100644
--- a/libs/phpseclib-1.0.7/Crypt/AES.php
+++ b/libs/phpseclib-1.0.8/Crypt/AES.php
diff --git a/libs/phpseclib-1.0.7/Crypt/Base.php b/libs/phpseclib-1.0.8/Crypt/Base.php
index 91ebe59..d3db117 100644
--- a/libs/phpseclib-1.0.7/Crypt/Base.php
+++ b/libs/phpseclib-1.0.8/Crypt/Base.php
@@ -526,8 +526,8 @@ class Crypt_Base
$this->_setEngine();
// Determining whether inline crypting can be used by the cipher
- if ($this->use_inline_crypt !== false && function_exists('create_function')) {
- $this->use_inline_crypt = true;
+ if ($this->use_inline_crypt !== false) {
+ $this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function');
}
}
@@ -2550,6 +2550,11 @@ class Crypt_Base
}
// Create the $inline function and return its name as string. Ready to run!
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
+ eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };');
+ return $func;
+ }
+
return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
}
diff --git a/libs/phpseclib-1.0.7/Crypt/Blowfish.php b/libs/phpseclib-1.0.8/Crypt/Blowfish.php
index 17c8e7e..17c8e7e 100644
--- a/libs/phpseclib-1.0.7/Crypt/Blowfish.php
+++ b/libs/phpseclib-1.0.8/Crypt/Blowfish.php
diff --git a/libs/phpseclib-1.0.7/Crypt/DES.php b/libs/phpseclib-1.0.8/Crypt/DES.php
index 4c57401..4c57401 100644
--- a/libs/phpseclib-1.0.7/Crypt/DES.php
+++ b/libs/phpseclib-1.0.8/Crypt/DES.php
diff --git a/libs/phpseclib-1.0.7/Crypt/Hash.php b/libs/phpseclib-1.0.8/Crypt/Hash.php
index faa17c5..faa17c5 100644
--- a/libs/phpseclib-1.0.7/Crypt/Hash.php
+++ b/libs/phpseclib-1.0.8/Crypt/Hash.php
diff --git a/libs/phpseclib-1.0.7/Crypt/RC2.php b/libs/phpseclib-1.0.8/Crypt/RC2.php
index 97b4550..97b4550 100644
--- a/libs/phpseclib-1.0.7/Crypt/RC2.php
+++ b/libs/phpseclib-1.0.8/Crypt/RC2.php
diff --git a/libs/phpseclib-1.0.7/Crypt/RC4.php b/libs/phpseclib-1.0.8/Crypt/RC4.php
index 7cec2e7..8a59518 100644
--- a/libs/phpseclib-1.0.7/Crypt/RC4.php
+++ b/libs/phpseclib-1.0.8/Crypt/RC4.php
@@ -141,7 +141,7 @@ class Crypt_RC4 extends Crypt_Base
* @var string
* @access private
*/
- var $key = "\0";
+ var $key;
/**
* The Key Stream for decryption and encryption
diff --git a/libs/phpseclib-1.0.7/Crypt/RSA.php b/libs/phpseclib-1.0.8/Crypt/RSA.php
index b734c9f..0f7f8aa 100644
--- a/libs/phpseclib-1.0.7/Crypt/RSA.php
+++ b/libs/phpseclib-1.0.8/Crypt/RSA.php
@@ -2512,7 +2512,7 @@ class Crypt_RSA
$db = $maskedDB ^ $dbMask;
$lHash2 = substr($db, 0, $this->hLen);
$m = substr($db, $this->hLen);
- if ($lHash != $lHash2) {
+ if (!$this->_equals($lHash, $lHash2)) {
user_error('Decryption error');
return false;
}
diff --git a/libs/phpseclib-1.0.7/Crypt/Random.php b/libs/phpseclib-1.0.8/Crypt/Random.php
index 1803421..1803421 100644
--- a/libs/phpseclib-1.0.7/Crypt/Random.php
+++ b/libs/phpseclib-1.0.8/Crypt/Random.php
diff --git a/libs/phpseclib-1.0.7/Crypt/Rijndael.php b/libs/phpseclib-1.0.8/Crypt/Rijndael.php
index 56bc4e9..56bc4e9 100644
--- a/libs/phpseclib-1.0.7/Crypt/Rijndael.php
+++ b/libs/phpseclib-1.0.8/Crypt/Rijndael.php
diff --git a/libs/phpseclib-1.0.7/Crypt/TripleDES.php b/libs/phpseclib-1.0.8/Crypt/TripleDES.php
index 4c0b677..4c0b677 100644
--- a/libs/phpseclib-1.0.7/Crypt/TripleDES.php
+++ b/libs/phpseclib-1.0.8/Crypt/TripleDES.php
diff --git a/libs/phpseclib-1.0.7/Crypt/Twofish.php b/libs/phpseclib-1.0.8/Crypt/Twofish.php
index 7125f6a..7125f6a 100644
--- a/libs/phpseclib-1.0.7/Crypt/Twofish.php
+++ b/libs/phpseclib-1.0.8/Crypt/Twofish.php
diff --git a/libs/phpseclib-1.0.7/File/ANSI.php b/libs/phpseclib-1.0.8/File/ANSI.php
index 989537b..0cbed17 100644
--- a/libs/phpseclib-1.0.7/File/ANSI.php
+++ b/libs/phpseclib-1.0.8/File/ANSI.php
@@ -332,6 +332,9 @@ class File_ANSI
case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
$this->old_x = $this->x;
$this->x-= $match[1];
+ if ($this->x < 0) {
+ $this->x = 0;
+ }
break;
case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
break;
@@ -443,7 +446,7 @@ class File_ANSI
if ($this->x > $this->max_x) {
$this->x = 0;
- $this->y++;
+ $this->_newLine();
} else {
$this->x++;
}
diff --git a/libs/phpseclib-1.0.7/File/ASN1.php b/libs/phpseclib-1.0.8/File/ASN1.php
index 7ce28bd..732bd9c 100644
--- a/libs/phpseclib-1.0.7/File/ASN1.php
+++ b/libs/phpseclib-1.0.8/File/ASN1.php
@@ -554,7 +554,9 @@ class File_ASN1
break;
case FILE_ASN1_TYPE_UTC_TIME:
case FILE_ASN1_TYPE_GENERALIZED_TIME:
- $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag);
+ $current['content'] = class_exists('DateTime') ?
+ $this->_decodeDateTime(substr($content, $content_pos), $tag) :
+ $this->_decodeUnixTime(substr($content, $content_pos), $tag);
default:
}
@@ -788,10 +790,20 @@ class File_ASN1
return isset($this->oids[$decoded['content']]) ? $this->oids[$decoded['content']] : $decoded['content'];
case FILE_ASN1_TYPE_UTC_TIME:
case FILE_ASN1_TYPE_GENERALIZED_TIME:
- if (isset($mapping['implicit'])) {
- $decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
+ if (class_exists('DateTime')) {
+ if (isset($mapping['implicit'])) {
+ $decoded['content'] = $this->_decodeDateTime($decoded['content'], $decoded['type']);
+ }
+ if (!$decoded['content']) {
+ return false;
+ }
+ return $decoded['content']->format($this->format);
+ } else {
+ if (isset($mapping['implicit'])) {
+ $decoded['content'] = $this->_decodeUnixTime($decoded['content'], $decoded['type']);
+ }
+ return @date($this->format, $decoded['content']);
}
- return @date($this->format, $decoded['content']);
case FILE_ASN1_TYPE_BIT_STRING:
if (isset($mapping['mapping'])) {
$offset = ord($decoded['content'][0]);
@@ -1040,7 +1052,12 @@ class File_ASN1
case FILE_ASN1_TYPE_GENERALIZED_TIME:
$format = $mapping['type'] == FILE_ASN1_TYPE_UTC_TIME ? 'y' : 'Y';
$format.= 'mdHis';
- $value = @gmdate($format, strtotime($source)) . 'Z';
+ if (!class_exists('DateTime')) {
+ $value = @gmdate($format, strtotime($source)) . 'Z';
+ } else {
+ $date = new DateTime($source, new DateTimeZone('GMT'));
+ $value = $date->format($format) . 'Z';
+ }
break;
case FILE_ASN1_TYPE_BIT_STRING:
if (isset($mapping['mapping'])) {
@@ -1202,7 +1219,7 @@ class File_ASN1
}
/**
- * BER-decode the time
+ * BER-decode the time (using UNIX time)
*
* Called by _decode_ber() and in the case of implicit tags asn1map().
*
@@ -1211,7 +1228,7 @@ class File_ASN1
* @param int $tag
* @return string
*/
- function _decodeTime($content, $tag)
+ function _decodeUnixTime($content, $tag)
{
/* UTCTime:
http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
@@ -1250,6 +1267,55 @@ class File_ASN1
return @$mktime((int)$hour, (int)$minute, (int)$second, (int)$month, (int)$day, (int)$year) + $timezone;
}
+
+ /**
+ * BER-decode the time (using DateTime)
+ *
+ * Called by _decode_ber() and in the case of implicit tags asn1map().
+ *
+ * @access private
+ * @param string $content
+ * @param int $tag
+ * @return string
+ */
+ function _decodeDateTime($content, $tag)
+ {
+ /* UTCTime:
+ http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+ http://www.obj-sys.com/asn1tutorial/node15.html
+
+ GeneralizedTime:
+ http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
+ http://www.obj-sys.com/asn1tutorial/node14.html */
+
+ $format = 'YmdHis';
+
+ if ($tag == FILE_ASN1_TYPE_UTC_TIME) {
+ // https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds
+ // element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the
+ // browsers parse it phpseclib ought to too
+ if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) {
+ $content = $matches[1] . '00' . $matches[2];
+ }
+ $prefix = substr($content, 0, 2) >= 50 ? '19' : '20';
+ $content = $prefix . $content;
+ } elseif (strpos($content, '.') !== false) {
+ $format.= '.u';
+ }
+
+ if ($content[strlen($content) - 1] == 'Z') {
+ $content = substr($content, 0, -1) . '+0000';
+ }
+
+ if (strpos($content, '-') !== false || strpos($content, '+') !== false) {
+ $format.= 'O';
+ }
+
+ // error supression isn't necessary as of PHP 7.0:
+ // http://php.net/manual/en/migration70.other-changes.php
+ return @DateTime::createFromFormat($format, $content);
+ }
+
/**
* Set the time format
*
diff --git a/libs/phpseclib-1.0.7/File/X509.php b/libs/phpseclib-1.0.8/File/X509.php
index e6c8443..6f84793 100644
--- a/libs/phpseclib-1.0.7/File/X509.php
+++ b/libs/phpseclib-1.0.8/File/X509.php
@@ -2114,7 +2114,9 @@ class File_X509
}
if (!isset($date)) {
- $date = time();
+ $date = class_exists('DateTime') ?
+ new DateTime($date, new DateTimeZone(@date_default_timezone_get())) :
+ time();
}
$notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
@@ -2123,9 +2125,17 @@ class File_X509
$notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
+ if (class_exists('DateTime')) {
+ $notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
+ $notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
+ } else {
+ $notBefore = @strtotime($notBefore);
+ $notAfter = @strtotime($notAfter);
+ }
+
switch (true) {
- case $date < @strtotime($notBefore):
- case $date > @strtotime($notAfter):
+ case $date < $notBefore:
+ case $date > $notAfter:
return false;
}
@@ -3385,7 +3395,15 @@ class File_X509
*/
function _timeField($date)
{
- $year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
+ if (is_object($date) && strtolower(get_class($date)) == 'file_asn1_element') {
+ return $date;
+ }
+ if (!class_exists('DateTime')) {
+ $year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
+ } else {
+ $dateObj = new DateTime($date, new DateTimeZone('GMT'));
+ $year = $dateObj->format('Y');
+ }
if ($year < 2050) {
return array('utcTime' => $date);
} else {
@@ -3450,8 +3468,16 @@ class File_X509
return false;
}
- $startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
- $endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
+ if (!class_exists('DateTime')) {
+ $startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
+ $endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
+ } else {
+ $startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+ $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O');
+
+ $endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get()));
+ $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O');
+ }
if (!empty($this->serialNumber)) {
$serialNumber = $this->serialNumber;
} else {
@@ -3724,7 +3750,12 @@ class File_X509
$currentCert = isset($this->currentCert) ? $this->currentCert : null;
$signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
- $thisUpdate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
+ if (!class_exists('DateTime')) {
+ $thisUpdate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
+ } else {
+ $thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+ $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O');
+ }
if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
$this->currentCert = $crl->currentCert;
@@ -3876,7 +3907,12 @@ class File_X509
*/
function setStartDate($date)
{
- $this->startDate = @date('D, d M Y H:i:s O', @strtotime($date));
+ if (class_exists('DateTime')) {
+ $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
+ $this->startDate = $date->format('D, d M Y H:i:s O');
+ } else {
+ $this->startDate = @date('D, d M Y H:i:s O', @strtotime($date));
+ }
}
/**
@@ -3900,7 +3936,12 @@ class File_X509
$temp = chr(FILE_ASN1_TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
$this->endDate = new File_ASN1_Element($temp);
} else {
- $this->endDate = @date('D, d M Y H:i:s O', @strtotime($date));
+ if (class_exists('DateTime')) {
+ $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
+ $this->endDate = $date->format('D, d M Y H:i:s O');
+ } else {
+ $this->endDate = @date('D, d M Y H:i:s O', @strtotime($date));
+ }
}
}
@@ -4640,9 +4681,16 @@ class File_X509
return false;
}
+ if (!class_exists('DateTime')) {
+ $revocationDate = @date('D, d M Y H:i:s O');
+ } else {
+ $revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+ $revocationDate = $revocationDate->format('D, d M Y H:i:s O');
+ }
+
$i = count($rclist);
$rclist[] = array('userCertificate' => $serial,
- 'revocationDate' => $this->_timeField(@date('D, d M Y H:i:s O')));
+ 'revocationDate' => $this->_timeField($revocationDate));
return $i;
}
diff --git a/libs/phpseclib-1.0.7/Math/BigInteger.php b/libs/phpseclib-1.0.8/Math/BigInteger.php
index 192ce82..6f9d591 100644
--- a/libs/phpseclib-1.0.7/Math/BigInteger.php
+++ b/libs/phpseclib-1.0.8/Math/BigInteger.php
@@ -360,8 +360,12 @@ class Math_BigInteger
case 256:
switch (MATH_BIGINTEGER_MODE) {
case MATH_BIGINTEGER_MODE_GMP:
- $sign = $this->is_negative ? '-' : '';
- $this->value = gmp_init($sign . '0x' . bin2hex($x));
+ $this->value = function_exists('gmp_import') ?
+ gmp_import($x) :
+ gmp_init('0x' . bin2hex($x));
+ if ($this->is_negative) {
+ $this->value = gmp_neg($this->value);
+ }
break;
case MATH_BIGINTEGER_MODE_BCMATH:
// round $len to the nearest 4 (thanks, DavidMJ!)
@@ -563,9 +567,13 @@ class Math_BigInteger
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
}
- $temp = gmp_strval(gmp_abs($this->value), 16);
- $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
- $temp = pack('H*', $temp);
+ if (function_exists('gmp_export')) {
+ $temp = gmp_export($this->value);
+ } else {
+ $temp = gmp_strval(gmp_abs($this->value), 16);
+ $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
+ $temp = pack('H*', $temp);
+ }
return $this->precision > 0 ?
substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
@@ -2937,7 +2945,7 @@ class Math_BigInteger
// (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
$temp = $this->toBytes();
if ($temp == '') {
- return '';
+ return $this->_normalize(new Math_BigInteger());
}
$pre_msb = decbin(ord($temp[0]));
$temp = ~$temp;
diff --git a/libs/phpseclib-1.0.7/Net/SCP.php b/libs/phpseclib-1.0.8/Net/SCP.php
index 354acea..354acea 100644
--- a/libs/phpseclib-1.0.7/Net/SCP.php
+++ b/libs/phpseclib-1.0.8/Net/SCP.php
diff --git a/libs/phpseclib-1.0.7/Net/SFTP.php b/libs/phpseclib-1.0.8/Net/SFTP.php
index 40c97da..a0b3632 100644
--- a/libs/phpseclib-1.0.7/Net/SFTP.php
+++ b/libs/phpseclib-1.0.8/Net/SFTP.php
@@ -199,7 +199,7 @@ class Net_SFTP extends Net_SSH2
* Current working directory
*
* @var string
- * @see self::_realpath()
+ * @see self::realpath()
* @see self::chdir()
* @access private
*/
@@ -228,7 +228,7 @@ class Net_SFTP extends Net_SSH2
*
* @see self::getSFTPErrors()
* @see self::getLastSFTPError()
- * @var string
+ * @var array
* @access private
*/
var $sftp_errors = array();
@@ -278,6 +278,20 @@ class Net_SFTP extends Net_SSH2
var $sortOptions = array();
/**
+ * Canonicalization Flag
+ *
+ * Determines whether or not paths should be canonicalized before being
+ * passed on to the remote server.
+ *
+ * @see self::enablePathCanonicalization()
+ * @see self::disablePathCanonicalization()
+ * @see self::realpath()
+ * @var bool
+ * @access private
+ */
+ var $canonicalize_paths = true;
+
+ /**
* Default Constructor.
*
* Connects to an SFTP server
@@ -631,6 +645,26 @@ class Net_SFTP extends Net_SSH2
}
/**
+ * Enable path canonicalization
+ *
+ * @access public
+ */
+ function enablePathCanonicalization()
+ {
+ $this->canonicalize_paths = true;
+ }
+
+ /**
+ * Enable path canonicalization
+ *
+ * @access public
+ */
+ function disablePathCanonicalization()
+ {
+ $this->canonicalize_paths = false;
+ }
+
+ /**
* Returns the current directory name
*
* @return mixed
@@ -688,13 +722,20 @@ class Net_SFTP extends Net_SSH2
* SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns
* the absolute (canonicalized) path.
*
+ * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is.
+ *
* @see self::chdir()
+ * @see self::disablePathCanonicalization()
* @param string $path
* @return mixed
* @access private
*/
function _realpath($path)
{
+ if (!$this->canonicalize_paths) {
+ return $path;
+ }
+
if ($this->pwd === false) {
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
@@ -1349,7 +1390,7 @@ class Net_SFTP extends Net_SSH2
/**
* Returns general information about a file or symbolic link
*
- * Determines information without calling Net_SFTP::_realpath().
+ * Determines information without calling Net_SFTP::realpath().
* The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
*
* @param string $filename
@@ -1510,7 +1551,7 @@ class Net_SFTP extends Net_SSH2
return true;
}
- $filename = $this->_realPath($filename);
+ $filename = $this->realpath($filename);
// rather than return what the permissions *should* be, we'll return what they actually are. this will also
// tell us if the file actually exists.
// incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
@@ -1995,7 +2036,7 @@ class Net_SFTP extends Net_SSH2
if (isset($fp)) {
$stat = fstat($fp);
- $size = $stat['size'];
+ $size = !empty($stat) ? $stat['size'] : 0;
if ($local_start >= 0) {
fseek($fp, $local_start);
@@ -3071,7 +3112,7 @@ class Net_SFTP extends Net_SSH2
/**
* Returns all errors
*
- * @return string
+ * @return array
* @access public
*/
function getSFTPErrors()
diff --git a/libs/phpseclib-1.0.7/Net/SFTP/Stream.php b/libs/phpseclib-1.0.8/Net/SFTP/Stream.php
index a944d7f..a944d7f 100644
--- a/libs/phpseclib-1.0.7/Net/SFTP/Stream.php
+++ b/libs/phpseclib-1.0.8/Net/SFTP/Stream.php
diff --git a/libs/phpseclib-1.0.7/Net/SSH1.php b/libs/phpseclib-1.0.8/Net/SSH1.php
index 55473d0..55473d0 100644
--- a/libs/phpseclib-1.0.7/Net/SSH1.php
+++ b/libs/phpseclib-1.0.8/Net/SSH1.php
diff --git a/libs/phpseclib-1.0.7/Net/SSH2.php b/libs/phpseclib-1.0.8/Net/SSH2.php
index d104b81..67f571e 100644
--- a/libs/phpseclib-1.0.7/Net/SSH2.php
+++ b/libs/phpseclib-1.0.8/Net/SSH2.php
@@ -96,10 +96,10 @@ define('NET_SSH2_MASK_WINDOW_ADJUST', 0x00000020);
* @see self::_get_channel_packet()
* @access private
*/
-define('NET_SSH2_CHANNEL_EXEC', 0); // PuTTy uses 0x100
-define('NET_SSH2_CHANNEL_SHELL', 1);
-define('NET_SSH2_CHANNEL_SUBSYSTEM', 2);
-define('NET_SSH2_CHANNEL_AGENT_FORWARD', 3);
+define('NET_SSH2_CHANNEL_EXEC', 1); // PuTTy uses 0x100
+define('NET_SSH2_CHANNEL_SHELL', 2);
+define('NET_SSH2_CHANNEL_SUBSYSTEM', 3);
+define('NET_SSH2_CHANNEL_AGENT_FORWARD', 4);
/**#@-*/
/**#@+
@@ -122,6 +122,10 @@ define('NET_SSH2_LOG_REALTIME', 3);
* Dumps the content real-time to a file
*/
define('NET_SSH2_LOG_REALTIME_FILE', 4);
+/**
+ * Make sure that the log never gets larger than this
+ */
+define('NET_SSH2_LOG_MAX_SIZE', 1024 * 1024);
/**#@-*/
/**#@+
@@ -137,9 +141,9 @@ define('NET_SSH2_READ_SIMPLE', 1);
*/
define('NET_SSH2_READ_REGEX', 2);
/**
- * Make sure that the log never gets larger than this
+ * Returns when a string matching the regular expression $expect is found
*/
-define('NET_SSH2_LOG_MAX_SIZE', 1024 * 1024);
+define('NET_SSH2_READ_NEXT', 3);
/**#@-*/
/**
@@ -872,6 +876,54 @@ class Net_SSH2
var $agent;
/**
+ * Send the identification string first?
+ *
+ * @var bool
+ * @access private
+ */
+ var $send_id_string_first = true;
+
+ /**
+ * Send the key exchange initiation packet first?
+ *
+ * @var bool
+ * @access private
+ */
+ var $send_kex_first = true;
+
+ /**
+ * Some versions of OpenSSH incorrectly calculate the key size
+ *
+ * @var bool
+ * @access private
+ */
+ var $bad_key_size_fix = false;
+
+ /**
+ * The selected decryption algorithm
+ *
+ * @var string
+ * @access private
+ */
+ var $decrypt_algorithm = '';
+
+ /**
+ * Should we try to re-connect to re-establish keys?
+ *
+ * @var bool
+ * @access private
+ */
+ var $retry_connect = false;
+
+ /**
+ * Binary Packet Buffer
+ *
+ * @var string|false
+ * @access private
+ */
+ var $binary_packet_buffer = false;
+
+ /**
* Default Constructor.
*
* $host can either be a string, representing the host, or a stream resource.
@@ -1013,7 +1065,7 @@ class Net_SSH2
* CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT
*
* @param int $engine
- * @access private
+ * @access public
*/
function setCryptoEngine($engine)
{
@@ -1021,6 +1073,62 @@ class Net_SSH2
}
/**
+ * Send Identification String First
+ *
+ * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
+ * both sides MUST send an identification string". It does not say which side sends it first. In
+ * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+ *
+ * @access public
+ */
+ function sendIdentificationStringFirst()
+ {
+ $this->send_id_string_first = true;
+ }
+
+ /**
+ * Send Identification String Last
+ *
+ * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
+ * both sides MUST send an identification string". It does not say which side sends it first. In
+ * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+ *
+ * @access public
+ */
+ function sendIdentificationStringLast()
+ {
+ $this->send_id_string_first = false;
+ }
+
+ /**
+ * Send SSH_MSG_KEXINIT First
+ *
+ * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
+ * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
+ * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+ *
+ * @access public
+ */
+ function sendKEXINITFirst()
+ {
+ $this->send_kex_first = true;
+ }
+
+ /**
+ * Send SSH_MSG_KEXINIT Last
+ *
+ * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
+ * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
+ * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+ *
+ * @access public
+ */
+ function sendKEXINITLast()
+ {
+ $this->send_kex_first = false;
+ }
+
+ /**
* Connect to an SSHv2 server
*
* @return bool
@@ -1061,7 +1169,9 @@ class Net_SSH2
$this->identifier = $this->_generate_identifier();
- fputs($this->fsock, $this->identifier . "\r\n");
+ if ($this->send_id_string_first) {
+ fputs($this->fsock, $this->identifier . "\r\n");
+ }
/* According to the SSH2 specs,
@@ -1116,23 +1226,33 @@ class Net_SSH2
$this->errors[] = utf8_decode($extra);
}
- if ($matches[1] != '1.99' && $matches[1] != '2.0') {
+ if (version_compare($matches[1], '1.99', '<')) {
user_error("Cannot connect to SSH $matches[1] servers");
return false;
}
- $response = $this->_get_binary_packet();
- if ($response === false) {
- user_error('Connection closed by server');
- return false;
+ if (!$this->send_id_string_first) {
+ fputs($this->fsock, $this->identifier . "\r\n");
}
- if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
- user_error('Expected SSH_MSG_KEXINIT');
- return false;
+ if (!$this->send_kex_first) {
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
+ user_error('Expected SSH_MSG_KEXINIT');
+ return false;
+ }
+
+ if (!$this->_key_exchange($response)) {
+ return false;
+ }
}
- if (!$this->_key_exchange($response)) {
+ if ($this->send_kex_first && !$this->_key_exchange()) {
return false;
}
@@ -1176,10 +1296,10 @@ class Net_SSH2
/**
* Key Exchange
*
- * @param string $kexinit_payload_server
+ * @param string $kexinit_payload_server optional
* @access private
*/
- function _key_exchange($kexinit_payload_server)
+ function _key_exchange($kexinit_payload_server = false)
{
static $kex_algorithms = array(
'diffie-hellman-group1-sha1', // REQUIRED
@@ -1290,8 +1410,9 @@ class Net_SSH2
);
// some SSH servers have buggy implementations of some of the above algorithms
- switch ($this->server_identifier) {
- case 'SSH-2.0-SSHD':
+ switch (true) {
+ case $this->server_identifier == 'SSH-2.0-SSHD':
+ case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK':
$mac_algorithms = array_values(array_diff(
$mac_algorithms,
array('hmac-sha1-96', 'hmac-md5-96')
@@ -1312,6 +1433,51 @@ class Net_SSH2
$client_cookie = crypt_random_string(16);
+ $kexinit_payload_client = pack(
+ 'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
+ NET_SSH2_MSG_KEXINIT,
+ $client_cookie,
+ strlen($str_kex_algorithms),
+ $str_kex_algorithms,
+ strlen($str_server_host_key_algorithms),
+ $str_server_host_key_algorithms,
+ strlen($encryption_algorithms_client_to_server),
+ $encryption_algorithms_client_to_server,
+ strlen($encryption_algorithms_server_to_client),
+ $encryption_algorithms_server_to_client,
+ strlen($mac_algorithms_client_to_server),
+ $mac_algorithms_client_to_server,
+ strlen($mac_algorithms_server_to_client),
+ $mac_algorithms_server_to_client,
+ strlen($compression_algorithms_client_to_server),
+ $compression_algorithms_client_to_server,
+ strlen($compression_algorithms_server_to_client),
+ $compression_algorithms_server_to_client,
+ 0,
+ '',
+ 0,
+ '',
+ 0,
+ 0
+ );
+
+ if ($this->send_kex_first) {
+ if (!$this->_send_binary_packet($kexinit_payload_client)) {
+ return false;
+ }
+
+ $kexinit_payload_server = $this->_get_binary_packet();
+ if ($kexinit_payload_server === false) {
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) {
+ user_error('Expected SSH_MSG_KEXINIT');
+ return false;
+ }
+ }
+
$response = $kexinit_payload_server;
$this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
$server_cookie = $this->_string_shift($response, 16);
@@ -1382,39 +1548,9 @@ class Net_SSH2
extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
$first_kex_packet_follows = $first_kex_packet_follows != 0;
- // the sending of SSH2_MSG_KEXINIT could go in one of two places. this is the second place.
- $kexinit_payload_client = pack(
- 'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
- NET_SSH2_MSG_KEXINIT,
- $client_cookie,
- strlen($str_kex_algorithms),
- $str_kex_algorithms,
- strlen($str_server_host_key_algorithms),
- $str_server_host_key_algorithms,
- strlen($encryption_algorithms_client_to_server),
- $encryption_algorithms_client_to_server,
- strlen($encryption_algorithms_server_to_client),
- $encryption_algorithms_server_to_client,
- strlen($mac_algorithms_client_to_server),
- $mac_algorithms_client_to_server,
- strlen($mac_algorithms_server_to_client),
- $mac_algorithms_server_to_client,
- strlen($compression_algorithms_client_to_server),
- $compression_algorithms_client_to_server,
- strlen($compression_algorithms_server_to_client),
- $compression_algorithms_server_to_client,
- 0,
- '',
- 0,
- '',
- 0,
- 0
- );
-
- if (!$this->_send_binary_packet($kexinit_payload_client)) {
+ if (!$this->send_kex_first && !$this->_send_binary_packet($kexinit_payload_client)) {
return false;
}
- // here ends the second place.
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
// we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
@@ -1825,6 +1961,8 @@ class Net_SSH2
//$this->decrypt = new Crypt_Null();
}
+ $this->decrypt_algorithm = $decrypt;
+
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
if ($this->encrypt) {
@@ -1983,6 +2121,10 @@ class Net_SSH2
*/
function _encryption_algorithm_to_key_size($algorithm)
{
+ if ($this->bad_key_size_fix && $this->_bad_algorithm_candidate($algorithm)) {
+ return 16;
+ }
+
switch ($algorithm) {
case 'none':
return 0;
@@ -2014,6 +2156,27 @@ class Net_SSH2
}
/**
+ * Tests whether or not proposed algorithm has a potential for issues
+ *
+ * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html
+ * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291
+ * @param string $algorithm Name of the encryption algorithm
+ * @return bool
+ * @access private
+ */
+ function _bad_algorithm_candidate($algorithm)
+ {
+ switch ($algorithm) {
+ case 'arcfour256':
+ case 'aes192-ctr':
+ case 'aes256-ctr':
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
* Login
*
* The $password parameter can be a plaintext password, a Crypt_RSA object or an array
@@ -2092,6 +2255,13 @@ class Net_SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
+ if ($this->retry_connect) {
+ $this->retry_connect = false;
+ if (!$this->_connect()) {
+ return false;
+ }
+ return $this->_login_helper($username, $password);
+ }
user_error('Connection closed by server');
return false;
}
@@ -2659,7 +2829,7 @@ class Net_SSH2
return false;
}
- $response = $this->_get_binary_packet();
+ $response = $this->_get_binary_packet(true);
if ($response === false) {
user_error('Connection closed by server');
return false;
@@ -2913,6 +3083,10 @@ class Net_SSH2
$channel = $this->_get_interactive_channel();
+ if ($mode == NET_SSH2_READ_NEXT) {
+ return $this->_get_channel_packet($channel);
+ }
+
$match = $expect;
while (true) {
if ($mode == NET_SSH2_READ_REGEX) {
@@ -3112,6 +3286,24 @@ class Net_SSH2
}
/**
+ * Resets a connection for re-use
+ *
+ * @param int $reason
+ * @access private
+ */
+ function _reset_connection($reason)
+ {
+ $this->_disconnect($reason);
+ $this->decrypt = $this->encrypt = false;
+ $this->decrypt_block_size = $this->encrypt_block_size = 8;
+ $this->hmac_check = $this->hmac_create = false;
+ $this->hmac_size = false;
+ $this->session_id = false;
+ $this->retry_connect = true;
+ $this->get_seq_no = $this->send_seq_no = 0;
+ }
+
+ /**
* Gets Binary Packets
*
* See '6. Binary Packet Protocol' of rfc4253 for more info.
@@ -3120,7 +3312,7 @@ class Net_SSH2
* @return string
* @access private
*/
- function _get_binary_packet()
+ function _get_binary_packet($filter_channel_packets = false)
{
if (!is_resource($this->fsock) || feof($this->fsock)) {
user_error('Connection closed prematurely');
@@ -3154,6 +3346,11 @@ class Net_SSH2
// "implementations SHOULD check that the packet length is reasonable"
// PuTTY uses 0x9000 as the actual max packet size and so to shall we
if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
+ if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decrypt_algorithm) && !($this->bitmap & NET_SSH2_MASK_LOGIN)) {
+ $this->bad_key_size_fix = true;
+ $this->_reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ return false;
+ }
user_error('Invalid size');
return false;
}
@@ -3169,6 +3366,7 @@ class Net_SSH2
$buffer.= $temp;
$remaining_length-= strlen($temp);
}
+
$stop = strtok(microtime(), ' ') + strtok('');
if (strlen($buffer)) {
$raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
@@ -3204,7 +3402,7 @@ class Net_SSH2
$this->last_packet = $current;
}
- return $this->_filter($payload);
+ return $this->_filter($payload, $filter_channel_packets);
}
/**
@@ -3216,7 +3414,7 @@ class Net_SSH2
* @return string
* @access private
*/
- function _filter($payload)
+ function _filter($payload, $filter_channel_packets)
{
switch (ord($payload[0])) {
case NET_SSH2_MSG_DISCONNECT:
@@ -3266,6 +3464,17 @@ class Net_SSH2
// only called when we've already logged in
if (($this->bitmap & NET_SSH2_MASK_CONNECTED) && $this->isAuthenticated()) {
switch (ord($payload[0])) {
+ case NET_SSH2_MSG_CHANNEL_DATA:
+ case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
+ case NET_SSH2_MSG_CHANNEL_REQUEST:
+ case NET_SSH2_MSG_CHANNEL_CLOSE:
+ case NET_SSH2_MSG_CHANNEL_EOF:
+ if ($filter_channel_packets) {
+ $this->binary_packet_buffer = $payload;
+ $this->_get_channel_packet(true);
+ $payload = $this->_get_binary_packet(true);
+ }
+ break;
case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
if (strlen($payload) < 4) {
return false;
@@ -3450,32 +3659,38 @@ class Net_SSH2
}
while (true) {
- if ($this->curTimeout) {
- if ($this->curTimeout < 0) {
- $this->is_timeout = true;
- return true;
- }
+ if ($this->binary_packet_buffer !== false) {
+ $response = $this->binary_packet_buffer;
+ $this->binary_packet_buffer = false;
+ } else {
+ if ($this->curTimeout) {
+ if ($this->curTimeout < 0) {
+ $this->is_timeout = true;
+ return true;
+ }
- $read = array($this->fsock);
- $write = $except = null;
+ $read = array($this->fsock);
+ $write = $except = null;
- $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
- $sec = floor($this->curTimeout);
- $usec = 1000000 * ($this->curTimeout - $sec);
- // on windows this returns a "Warning: Invalid CRT parameters detected" error
- if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
- $this->is_timeout = true;
- return true;
+ $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+ $sec = floor($this->curTimeout);
+ $usec = 1000000 * ($this->curTimeout - $sec);
+ // on windows this returns a "Warning: Invalid CRT parameters detected" error
+ if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
+ $this->is_timeout = true;
+ return true;
+ }
+ $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
+ $this->curTimeout-= $elapsed;
}
- $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
- $this->curTimeout-= $elapsed;
- }
- $response = $this->_get_binary_packet();
- if ($response === false) {
- user_error('Connection closed by server');
- return false;
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ user_error('Connection closed by server');
+ return false;
+ }
}
+
if ($client_channel == -1 && $response === true) {
return true;
}
diff --git a/libs/phpseclib-1.0.7/System/SSH/Agent.php b/libs/phpseclib-1.0.8/System/SSH/Agent.php
index 7388cb4..7388cb4 100644
--- a/libs/phpseclib-1.0.7/System/SSH/Agent.php
+++ b/libs/phpseclib-1.0.8/System/SSH/Agent.php
diff --git a/libs/phpseclib-1.0.7/System/SSH_Agent.php b/libs/phpseclib-1.0.8/System/SSH_Agent.php
index ea434b9..ea434b9 100644
--- a/libs/phpseclib-1.0.7/System/SSH_Agent.php
+++ b/libs/phpseclib-1.0.8/System/SSH_Agent.php
diff --git a/libs/phpseclib-1.0.7/bootstrap.php b/libs/phpseclib-1.0.8/bootstrap.php
index 0da0999..0da0999 100644
--- a/libs/phpseclib-1.0.7/bootstrap.php
+++ b/libs/phpseclib-1.0.8/bootstrap.php
diff --git a/libs/phpseclib-1.0.7/openssl.cnf b/libs/phpseclib-1.0.8/openssl.cnf
index 2b8b52f..2b8b52f 100644
--- a/libs/phpseclib-1.0.7/openssl.cnf
+++ b/libs/phpseclib-1.0.8/openssl.cnf