From a8863e2b3deceec209876bec5873a6b5d0594f90 Mon Sep 17 00:00:00 2001 From: Jim Wigginton Date: Sun, 29 Aug 2010 03:27:02 +0000 Subject: [PATCH] - included a work-around for a bug in Portable OpenSSH 4.4 and earlier whereby faulty key sizes are used for aes256-ctr, aes192-ctr and arcfour256 (thanks, f.dammassa!) git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@116 21d32557-59b3-4da0-833f-c5933fad653e --- phpseclib/Net/SSH2.php | 49 +++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index cee090ae..a78f9480 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -60,7 +60,7 @@ * @author Jim Wigginton * @copyright MMVII Jim Wigginton * @license http://www.gnu.org/licenses/lgpl.txt - * @version $Id: SSH2.php,v 1.49 2010-08-28 17:26:22 terrafrost Exp $ + * @version $Id: SSH2.php,v 1.50 2010-08-29 03:27:02 terrafrost Exp $ * @link http://phpseclib.sourceforge.net */ @@ -563,6 +563,23 @@ class Net_SSH2 { */ var $signature_format = ''; + /** + * Key size fix + * + * Portable OpenSSH 4.4 and earlier use faulty key sizes for aes256-ctr, aes192-ctr and arcfour256. + * These algorithms could be removed from $encryption_algorithms in Net_SSH2::_key_exchange() but we'll + * adjust the key sizes instead to confirm that the version detection technique we're using is correct. + * If it isn't correct than we'll get decryption / encryption errors. We wouldn't get any errors, in + * contrast, if the algorithms were simply removed, and would never know if the version detection + * technique we were using was correct. + * + * @link http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh + * @see Net_SSH2::Net_SSH2() + * @var Boolean + * @access private + */ + var $adjust_key_fix = false; + /** * Default Constructor. * @@ -708,6 +725,8 @@ class Net_SSH2 { return; } + $this->adjust_key_fix = preg_match('#SSH-' . $matches[1] . '\-OpenSSH_([\d\.]+)#', $this->server_identifier, $matches) && $matches[1] < 4.6; + fputs($this->fsock, $this->identifier . "\r\n"); $response = $this->_get_binary_packet(); @@ -866,12 +885,16 @@ class Net_SSH2 { $decryptKeyLength = 24; // eg. 192 / 8 break; case 'aes256-cbc': - case 'aes256-ctr': $decryptKeyLength = 32; // eg. 256 / 8 break; + case 'aes256-ctr': + $decryptKeyLength = !$this->adjust_key_fix ? 32 : 16; + break; case 'aes192-cbc': + $decryptKeyLength = 24; + break; case 'aes192-ctr': - $decryptKeyLength = 24; // eg. 192 / 8 + $decryptKeyLength = !$this->adjust_key_fix ? 24 : 16; break; case 'aes128-cbc': case 'aes128-ctr': @@ -879,10 +902,10 @@ class Net_SSH2 { break; case 'arcfour': case 'arcfour128': - $decryptKeyLength = 16; // eg. 128 / 8 + $decryptKeyLength = 16; break; case 'arcfour256': - $decryptKeyLength = 32; // eg. 128 / 8 + $decryptKeyLength = !$this->adjust_key_fix ? 32 : 16; break; case 'none'; $decryptKeyLength = 0; @@ -901,13 +924,17 @@ class Net_SSH2 { $encryptKeyLength = 24; break; case 'aes256-cbc': - case 'aes256-ctr': $encryptKeyLength = 32; break; + case 'aes256-ctr': + $encryptKeyLength = !$this->adjust_key_fix ? 32 : 16; + break; case 'aes192-cbc': - case 'aes192-ctr': $encryptKeyLength = 24; break; + case 'aes192-ctr': + $encryptKeyLength = !$this->adjust_key_fix ? 24 : 16; + break; case 'aes128-cbc': case 'aes128-ctr': $encryptKeyLength = 16; @@ -917,7 +944,7 @@ class Net_SSH2 { $encryptKeyLength = 16; break; case 'arcfour256': - $encryptKeyLength = 32; + $encryptKeyLength = !$this->adjust_key_fix ? 32 : 16; break; case 'none'; $encryptKeyLength = 0; @@ -1408,7 +1435,7 @@ class Net_SSH2 { for ($i = 0; $i < $num_prompts; $i++) { extract(unpack('Nlength', $this->_string_shift($response, 4))); // prompt - ie. "Password: "; must not be empty - $this->_string_shift($response, $length); // prompt; must not be empty + $this->_string_shift($response, $length); $echo = $this->_string_shift($response) != chr(0); } */ @@ -1418,9 +1445,10 @@ class Net_SSH2 { MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message. */ // see http://tools.ietf.org/html/rfc4256#section-3.4 - $packet = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); + $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); for ($i = 0; $i < count($responses); $i++) { $packet.= pack('Na*', strlen($responses[$i]), $responses[$i]); + $logged.= pack('Na*', strlen('dummy-answer'), 'dummy-answer'); } if (!$this->_send_binary_packet($packet)) { @@ -1429,6 +1457,7 @@ class Net_SSH2 { if (defined('NET_SSH2_LOGGING')) { $this->message_number_log[count($this->message_number_log) - 1] = 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'; + $this->message_log[count($this->message_log) - 1] = $logged; } /*