Merge branch 'master' into php5

This commit is contained in:
terrafrost 2013-12-27 10:25:19 -06:00
commit a1b749a0a0
11 changed files with 350 additions and 217 deletions

View File

@ -992,8 +992,9 @@ class Crypt_RSA
$iv = pack('H*', trim($matches[2])); $iv = pack('H*', trim($matches[2]));
$symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key
$symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8))); $symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8)));
$ciphertext = preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-| #s', '', $key); // remove the Proc-Type / DEK-Info sections as they're no longer needed
$ciphertext = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $ciphertext) ? base64_decode($ciphertext) : false; $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
$ciphertext = $this->_extractBER($key);
if ($ciphertext === false) { if ($ciphertext === false) {
$ciphertext = $key; $ciphertext = $key;
} }
@ -1037,8 +1038,7 @@ class Crypt_RSA
$crypto->setIV($iv); $crypto->setIV($iv);
$decoded = $crypto->decrypt($ciphertext); $decoded = $crypto->decrypt($ciphertext);
} else { } else {
$decoded = preg_replace('#-.+-|[\r\n]| #', '', $key); $decoded = $this->_extractBER($key);
$decoded = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $decoded) ? base64_decode($decoded) : false;
} }
if ($decoded !== false) { if ($decoded !== false) {
@ -2781,4 +2781,31 @@ class Crypt_RSA
return $this->_rsassa_pss_verify($message, $signature); return $this->_rsassa_pss_verify($message, $signature);
} }
} }
/**
* Extract raw BER from Base64 encoding
*
* @access private
* @param String $str
* @return String
*/
function _extractBER($str)
{
/* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
* above and beyond the ceritificate.
* ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
*
* Bag Attributes
* localKeyID: 01 00 00 00
* subject=/O=organization/OU=org unit/CN=common name
* issuer=/O=organization/CN=common name
*/
$temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1);
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
$temp = preg_replace('#-+[^-]+-+#', '', $temp);
// remove new lines
$temp = str_replace(array("\r", "\n", ' '), '', $temp);
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
return $temp != false ? $temp : $str;
}
} }

View File

@ -131,9 +131,7 @@ function crypt_random_string($length)
$old_session_id = session_id(); $old_session_id = session_id();
$old_use_cookies = ini_get('session.use_cookies'); $old_use_cookies = ini_get('session.use_cookies');
$old_session_cache_limiter = session_cache_limiter(); $old_session_cache_limiter = session_cache_limiter();
if (isset($_SESSION)) { $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
$_OLD_SESSION = $_SESSION;
}
if ($old_session_id != '') { if ($old_session_id != '') {
session_write_close(); session_write_close();
} }
@ -166,7 +164,7 @@ function crypt_random_string($length)
ini_set('session.use_cookies', $old_use_cookies); ini_set('session.use_cookies', $old_use_cookies);
session_cache_limiter($old_session_cache_limiter); session_cache_limiter($old_session_cache_limiter);
} else { } else {
if (isset($_OLD_SESSION)) { if ($_OLD_SESSION !== false) {
$_SESSION = $_OLD_SESSION; $_SESSION = $_OLD_SESSION;
unset($_OLD_SESSION); unset($_OLD_SESSION);
} else { } else {

View File

@ -4413,14 +4413,14 @@ class File_X509
*/ */
function _extractBER($str) function _extractBER($str)
{ {
/* /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them above and beyond the ceritificate. ie. * above and beyond the ceritificate.
some may have the following preceding the -----BEGIN CERTIFICATE----- line: * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
*
Bag Attributes * Bag Attributes
localKeyID: 01 00 00 00 * localKeyID: 01 00 00 00
subject=/O=organization/OU=org unit/CN=common name * subject=/O=organization/OU=org unit/CN=common name
issuer=/O=organization/CN=common name * issuer=/O=organization/CN=common name
*/ */
$temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1); $temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1);
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff

View File

@ -402,7 +402,7 @@ class Net_SFTP extends Net_SSH2
function login($username) function login($username)
{ {
$args = func_get_args(); $args = func_get_args();
if (!call_user_func_array(array('Net_SSH2', 'login'), $args)) { if (!call_user_func_array(array(&$this, '_login'), $args)) {
return false; return false;
} }
@ -1042,7 +1042,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function truncate($filename, $new_size) function truncate($filename, $new_size)
{ {
$attr = pack('N3', NET_SFTP_ATTR_SIZE, $new_size / 0x100000000, $new_size); $attr = pack('N3', NET_SFTP_ATTR_SIZE, $new_size / 4294967296, $new_size); // 4294967296 == 0x100000000 == 1<<32
return $this->_setstat($filename, $attr, false); return $this->_setstat($filename, $attr, false);
} }
@ -1539,7 +1539,7 @@ class Net_SFTP extends Net_SSH2
while ($sent < $size) { while ($sent < $size) {
$temp = $mode & NET_SFTP_LOCAL_FILE ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size); $temp = $mode & NET_SFTP_LOCAL_FILE ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
$subtemp = $offset + $sent; $subtemp = $offset + $sent;
$packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 0x100000000, $subtemp, strlen($temp), $temp); $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) { if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
fclose($fp); fclose($fp);
return false; return false;
@ -1687,7 +1687,7 @@ class Net_SFTP extends Net_SSH2
$size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length; $size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length;
while (true) { while (true) {
$packet = pack('Na*N3', strlen($handle), $handle, $offset / 0x100000000, $offset, $size); $packet = pack('Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, $size);
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) { if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
if ($local_file !== false) { if ($local_file !== false) {
fclose($fp); fclose($fp);
@ -1925,7 +1925,7 @@ class Net_SFTP extends Net_SSH2
// (0xFFFFFFFF bytes), anyway. as such, we'll just represent all file sizes that are bigger than // (0xFFFFFFFF bytes), anyway. as such, we'll just represent all file sizes that are bigger than
// 4GB as being 4GB. // 4GB as being 4GB.
extract(unpack('Nupper/Nsize', $this->_string_shift($response, 8))); extract(unpack('Nupper/Nsize', $this->_string_shift($response, 8)));
$attr['size'] = $upper ? 0x100000000 * $upper : 0; $attr['size'] = $upper ? 4294967296 * $upper : 0;
$attr['size']+= $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; $attr['size']+= $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;
break; break;
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)

View File

@ -201,11 +201,11 @@ define('NET_SSH1_LOG_COMPLEX', 2);
/** /**
* Outputs the content real-time * Outputs the content real-time
*/ */
define('NET_SSH2_LOG_REALTIME', 3); define('NET_SSH1_LOG_REALTIME', 3);
/** /**
* Dumps the content real-time to a file * Dumps the content real-time to a file
*/ */
define('NET_SSH2_LOG_REALTIME_FILE', 4); define('NET_SSH1_LOG_REALTIME_FILE', 4);
/**#@-*/ /**#@-*/
/**#@+ /**#@+
@ -429,11 +429,35 @@ class Net_SSH1
/** /**
* Current Timeout * Current Timeout
* *
* @see Net_SSH2::_get_channel_packet() * @see Net_SSH1::_get_channel_packet()
* @access private * @access private
*/ */
var $curTimeout; var $curTimeout;
/**
* Log Boundary
*
* @see Net_SSH1::_format_log
* @access private
*/
var $log_boundary = ':';
/**
* Log Long Width
*
* @see Net_SSH1::_format_log
* @access private
*/
var $log_long_width = 65;
/**
* Log Short Width
*
* @see Net_SSH1::_format_log
* @access private
*/
var $log_short_width = 16;
/** /**
* Default Constructor. * Default Constructor.
* *
@ -1318,7 +1342,7 @@ class Net_SSH1
/** /**
* Returns a log of the packets that have been sent and received. * Returns a log of the packets that have been sent and received.
* *
* Returns a string if NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX, an array if NET_SSH2_LOGGING == NET_SSH2_LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING') * Returns a string if NET_SSH1_LOGGING == NET_SSH1_LOG_COMPLEX, an array if NET_SSH1_LOGGING == NET_SSH1_LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING')
* *
* @access public * @access public
* @return String or Array * @return String or Array
@ -1351,8 +1375,6 @@ class Net_SSH1
*/ */
function _format_log($message_log, $message_number_log) function _format_log($message_log, $message_number_log)
{ {
static $boundary = ':', $long_width = 65, $short_width = 16;
$output = ''; $output = '';
for ($i = 0; $i < count($message_log); $i++) { for ($i = 0; $i < count($message_log); $i++) {
$output.= $message_number_log[$i] . "\r\n"; $output.= $message_number_log[$i] . "\r\n";
@ -1362,19 +1384,13 @@ class Net_SSH1
if (strlen($current_log)) { if (strlen($current_log)) {
$output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 ';
} }
$fragment = $this->_string_shift($current_log, $short_width); $fragment = $this->_string_shift($current_log, $this->log_short_width);
$hex = substr( $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary));
preg_replace(
'#(.)#es',
'"' . $boundary . '" . str_pad(dechex(ord(substr("\\1", -1))), 2, "0", STR_PAD_LEFT)',
$fragment),
strlen($boundary)
);
// replace non ASCII printable characters with dots // replace non ASCII printable characters with dots
// http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
// also replace < with a . since < messes up the output on web browsers // also replace < with a . since < messes up the output on web browsers
$raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment);
$output.= str_pad($hex, $long_width - $short_width, ' ') . $raw . "\r\n"; $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n";
$j++; $j++;
} while (strlen($current_log)); } while (strlen($current_log));
$output.= "\r\n"; $output.= "\r\n";
@ -1383,6 +1399,20 @@ class Net_SSH1
return $output; return $output;
} }
/**
* Helper function for _format_log
*
* For use with preg_replace_callback()
*
* @param Array $matches
* @access private
* @return String
*/
function _format_log_helper($matches)
{
return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT);
}
/** /**
* Return the server key public exponent * Return the server key public exponent
* *
@ -1507,7 +1537,7 @@ class Net_SSH1
$this->_string_shift($message); $this->_string_shift($message);
$this->log_size+= strlen($message); $this->log_size+= strlen($message);
$this->message_log[] = $message; $this->message_log[] = $message;
while ($this->log_size > NET_SSH2_LOG_MAX_SIZE) { while ($this->log_size > NET_SSH1_LOG_MAX_SIZE) {
$this->log_size-= strlen(array_shift($this->message_log)); $this->log_size-= strlen(array_shift($this->message_log));
array_shift($this->protocol_flags_log); array_shift($this->protocol_flags_log);
} }
@ -1527,7 +1557,7 @@ class Net_SSH1
case NET_SSH1_LOG_REALTIME_FILE: case NET_SSH1_LOG_REALTIME_FILE:
if (!isset($this->realtime_log_file)) { if (!isset($this->realtime_log_file)) {
// PHP doesn't seem to like using constants in fopen() // PHP doesn't seem to like using constants in fopen()
$filename = NET_SSH2_LOG_REALTIME_FILE; $filename = NET_SSH1_LOG_REALTIME_FILE;
$fp = fopen($filename, 'w'); $fp = fopen($filename, 'w');
$this->realtime_log_file = $fp; $this->realtime_log_file = $fp;
} }

View File

@ -1284,7 +1284,8 @@ class Net_SSH2
-- http://tools.ietf.org/html/rfc4419#section-6.2 */ -- http://tools.ietf.org/html/rfc4419#section-6.2 */
$one = new Math_BigInteger(1); $one = new Math_BigInteger(1);
$keyLength = min($keyLength, $kexHash->getLength()); $keyLength = min($keyLength, $kexHash->getLength());
$max = $one->bitwise_leftShift(16 * $keyLength)->subtract($one); // 2 * 8 * $keyLength $max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength
$max = $max->subtract($one);
$x = $one->random($one, $max); $x = $one->random($one, $max);
$e = $g->modPow($x, $prime); $e = $g->modPow($x, $prime);
@ -1671,10 +1672,26 @@ class Net_SSH2
* @param Mixed $password * @param Mixed $password
* @param Mixed $... * @param Mixed $...
* @return Boolean * @return Boolean
* @see _login_helper * @see _login
* @access public * @access public
*/ */
function login($username) function login($username)
{
$args = func_get_args();
return call_user_func_array(array(&$this, '_login'), $args);
}
/**
* Login Helper
*
* @param String $username
* @param Mixed $password
* @param Mixed $...
* @return Boolean
* @see _login_helper
* @access private
*/
function _login($username)
{ {
$args = array_slice(func_get_args(), 1); $args = array_slice(func_get_args(), 1);
if (empty($args)) { if (empty($args)) {
@ -3607,7 +3624,15 @@ class Net_SSH2
*/ */
function _is_includable($suffix) function _is_includable($suffix)
{ {
foreach (explode(PATH_SEPARATOR, get_include_path()) as $prefix) { // stream_resolve_include_path was introduced in PHP 5.3.2
if (function_exists('stream_resolve_include_path')) {
return stream_resolve_include_path($suffix) !== false;
}
$paths = PATH_SEPARATOR == ':' ?
preg_split('#(?<!phar):#', get_include_path()) :
explode(PATH_SEPARATOR, get_include_path());
foreach ($paths as $prefix) {
$ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR; $ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
$file = $prefix . $ds . $suffix; $file = $prefix . $ds . $suffix;

41
tests/Net/SSH1Test.php Normal file
View File

@ -0,0 +1,41 @@
<?php
/**
* @author Marc Scholten <marc@pedigital.de>
* @copyright MMXIII Marc Scholten
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Net_SSH1Test extends PhpseclibTestCase
{
public function formatLogDataProvider()
{
return array(
array(
array('hello world'),
array('<--'),
"<--\r\n00000000 68:65:6c:6c:6f:20:77:6f:72:6c:64 hello world\r\n\r\n"
),
array(
array('hello', 'world'),
array('<--', '<--'),
"<--\r\n00000000 68:65:6c:6c:6f hello\r\n\r\n" .
"<--\r\n00000000 77:6f:72:6c:64 world\r\n\r\n"
),
);
}
/**
* @dataProvider formatLogDataProvider
*/
public function testFormatLog(array $message_log, array $message_number_log, $expected)
{
$ssh = $this->getMockBuilder('Net_SSH1')
->disableOriginalConstructor()
->setMethods(null)
->getMock();
$result = $ssh->_format_log($message_log, $message_number_log);
$this->assertEquals($expected, $result);
}
}

View File

@ -56,6 +56,18 @@
</rule> </rule>
<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint" /> <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint" />
<!-- There MUST NOT be trailing whitespace at the end of lines. -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace" />
<!-- There MUST NOT be whitespace before the first content of a file -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile" />
<!-- There MUST NOT be whitespace after the last content of a file -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile" />
<!-- Functions MUST NOT contain multiple empty lines in a row -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines" />
<!-- The ?> closing tag MUST be omitted from files containing only PHP. --> <!-- The ?> closing tag MUST be omitted from files containing only PHP. -->
<rule ref="Zend.Files.ClosingTag" /> <rule ref="Zend.Files.ClosingTag" />