From c2be7e648060fc373381f16509c2c7aea8728a57 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 1 Feb 2020 16:47:09 -0600 Subject: [PATCH] return early if fread() response is bool(false) --- phpseclib/Crypt/Random.php | 5 ++- phpseclib/File/X509.php | 6 +++- phpseclib/Net/SSH1.php | 3 ++ phpseclib/Net/SSH2.php | 6 +++- phpseclib/System/SSH/Agent.php | 66 ++++++++++++++++++++++++++++++---- 5 files changed, 76 insertions(+), 10 deletions(-) diff --git a/phpseclib/Crypt/Random.php b/phpseclib/Crypt/Random.php index 85c302f2..b7874ea1 100644 --- a/phpseclib/Crypt/Random.php +++ b/phpseclib/Crypt/Random.php @@ -105,7 +105,10 @@ if (!function_exists('crypt_random_string')) { $fp = @fopen('/dev/urandom', 'rb'); } if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource() - return fread($fp, $length); + $temp = fread($fp, $length); + if (strlen($temp) != $length) { + return $temp; + } } // method 3. pretty much does the same thing as method 2 per the following url: // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391 diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 2b24d471..9295c699 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -2218,7 +2218,11 @@ class File_X509 } while (!feof($fsock)) { - $data.= fread($fsock, 1024); + $temp = fread($fsock, 1024); + if ($temp === false) { + return false; + } + $data.= $temp; } break; diff --git a/phpseclib/Net/SSH1.php b/phpseclib/Net/SSH1.php index 55473d08..b7b7cd8a 100644 --- a/phpseclib/Net/SSH1.php +++ b/phpseclib/Net/SSH1.php @@ -1169,6 +1169,9 @@ class Net_SSH1 while ($length > 0) { $temp = fread($this->fsock, $length); + if (stlren($temp) != $length) { + return false; + } $raw.= $temp; $length-= strlen($temp); } diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index d22786b9..7b463de4 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1252,7 +1252,11 @@ class Net_SSH2 $elapsed = strtok(microtime(), ' ') + strtok('') - $start; $this->curTimeout-= $elapsed; } - $temp.= fgets($this->fsock, 255); + $subtemp = fgets($this->fsock, 255); + if ($subtemp === '' || $subtemp === false) { + return false; + } + $temp.= $subtemp; } if (feof($this->fsock)) { diff --git a/phpseclib/System/SSH/Agent.php b/phpseclib/System/SSH/Agent.php index 8861f2a0..5ac3f6b8 100644 --- a/phpseclib/System/SSH/Agent.php +++ b/phpseclib/System/SSH/Agent.php @@ -263,22 +263,35 @@ class System_SSH_Agent_Identity $packet = pack('Na*', strlen($packet), $packet); if (strlen($packet) != fputs($this->fsock, $packet)) { user_error('Connection closed during signing'); + return false; } - $length = current(unpack('N', fread($this->fsock, 4))); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed during signing'); + return false; + } + $length = current(unpack('N', $temp)); $type = ord(fread($this->fsock, 1)); if ($type != SYSTEM_SSH_AGENT_SIGN_RESPONSE) { user_error('Unable to retreive signature'); + return false; } $signature_blob = fread($this->fsock, $length - 1); + if (strlen($signature_blob) != $length - 1) { + user_error('Connection closed during signing'); + return false; + } $length = current(unpack('N', $this->_string_shift($signature_blob, 4))); if ($length != strlen($signature_blob)) { user_error('Malformed signature blob'); + return false; } $length = current(unpack('N', $this->_string_shift($signature_blob, 4))); if ($length > strlen($signature_blob) + 4) { user_error('Malformed signature blob'); + return false; } $type = $this->_string_shift($signature_blob, $length); $this->_string_shift($signature_blob, 4); @@ -406,7 +419,12 @@ class System_SSH_Agent return array(); } - $length = current(unpack('N', fread($this->fsock, 4))); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while requesting identities'); + return array(); + } + $length = current(unpack('N', $temp)); $type = ord(fread($this->fsock, 1)); if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) { user_error('Unable to request identities'); @@ -414,14 +432,38 @@ class System_SSH_Agent } $identities = array(); - $keyCount = current(unpack('N', fread($this->fsock, 4))); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while requesting identities'); + return array(); + } + $keyCount = current(unpack('N', $temp)); for ($i = 0; $i < $keyCount; $i++) { - $length = current(unpack('N', fread($this->fsock, 4))); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while requesting identities'); + return array(); + } + $length = current(unpack('N', $temp)); $key_blob = fread($this->fsock, $length); + if (strlen($key_blob) != $length) { + user_error('Connection closed while requesting identities'); + return array(); + } $key_str = 'ssh-rsa ' . base64_encode($key_blob); - $length = current(unpack('N', fread($this->fsock, 4))); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while requesting identities'); + return array(); + } + $length = current(unpack('N', $temp)); if ($length) { - $key_str.= ' ' . fread($this->fsock, $length); + $temp = fread($this->fsock, $length); + if (strlen($temp) != $length) { + user_error('Connection closed while requesting identities'); + return array(); + } + $key_str.= ' ' . $temp; } $length = current(unpack('N', substr($key_blob, 0, 4))); $key_type = substr($key_blob, 4, $length); @@ -546,14 +588,24 @@ class System_SSH_Agent if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { user_error('Connection closed attempting to forward data to SSH agent'); + return false; } $this->socket_buffer = ''; $this->expected_bytes = 0; - $agent_reply_bytes = current(unpack('N', fread($this->fsock, 4))); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while reading data response'); + return false; + } + $agent_reply_bytes = current(unpack('N', $temp)); $agent_reply_data = fread($this->fsock, $agent_reply_bytes); + if (strlen($agent_reply_data) != $agent_reply_bytes) { + user_error('Connection closed while reading data response'); + return false; + } $agent_reply_data = current(unpack('a*', $agent_reply_data)); return pack('Na*', $agent_reply_bytes, $agent_reply_data);