diff --git a/phpseclib/Crypt/Random.php b/phpseclib/Crypt/Random.php index 01e34cc3..e5c819c7 100644 --- a/phpseclib/Crypt/Random.php +++ b/phpseclib/Crypt/Random.php @@ -97,7 +97,10 @@ class Random $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 b4963fc8..ddbc6159 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -2179,7 +2179,11 @@ class 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 514b20a2..81f6b00e 100644 --- a/phpseclib/Net/SSH1.php +++ b/phpseclib/Net/SSH1.php @@ -1124,6 +1124,9 @@ class 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 34a29301..e105b4d0 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1218,6 +1218,9 @@ class SSH2 if (strlen($temp) == 255) { continue; } + if ($temp === false) { + return false; + } $line.= "$temp\n"; diff --git a/phpseclib/System/SSH/Agent.php b/phpseclib/System/SSH/Agent.php index 99dcecfe..2b25250b 100644 --- a/phpseclib/System/SSH/Agent.php +++ b/phpseclib/System/SSH/Agent.php @@ -160,7 +160,12 @@ class 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 != self::SSH_AGENT_IDENTITIES_ANSWER) { user_error('Unable to request identities'); @@ -168,14 +173,38 @@ class 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); @@ -297,14 +326,24 @@ class 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); diff --git a/phpseclib/System/SSH/Agent/Identity.php b/phpseclib/System/SSH/Agent/Identity.php index b4649046..68b6bfdf 100644 --- a/phpseclib/System/SSH/Agent/Identity.php +++ b/phpseclib/System/SSH/Agent/Identity.php @@ -188,15 +188,26 @@ class 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 != Agent::SSH_AGENT_SIGN_RESPONSE) { user_error('Unable to retrieve 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');