phpseclib\Net\SSH2::_get_binary_packet PHP Method

_get_binary_packet() public method

See '6. Binary Packet Protocol' of rfc4253 for more info.
See also: self::_send_binary_packet()
public _get_binary_packet ( ) : string
return string
    function _get_binary_packet()
    {
        if (!is_resource($this->fsock) || feof($this->fsock)) {
            $this->bitmap = 0;
            throw new \RuntimeException('Connection closed prematurely');
        }
        $start = microtime(true);
        $raw = stream_get_contents($this->fsock, $this->decrypt_block_size);
        if (!strlen($raw)) {
            return '';
        }
        if ($this->decrypt !== false) {
            $raw = $this->decrypt->decrypt($raw);
        }
        if (strlen($raw) < 5) {
            return false;
        }
        extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5)));
        $remaining_length = $packet_length + 4 - $this->decrypt_block_size;
        // quoting <http://tools.ietf.org/html/rfc4253#section-6.1>,
        // "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) {
            throw new \RuntimeException('Invalid size');
        }
        $buffer = '';
        while ($remaining_length > 0) {
            $temp = stream_get_contents($this->fsock, $remaining_length);
            if ($temp === false || feof($this->fsock)) {
                $this->bitmap = 0;
                throw new \RuntimeException('Error reading from socket');
            }
            $buffer .= $temp;
            $remaining_length -= strlen($temp);
        }
        $stop = microtime(true);
        if (strlen($buffer)) {
            $raw .= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
        }
        $payload = Strings::shift($raw, $packet_length - $padding_length - 1);
        $padding = Strings::shift($raw, $padding_length);
        // should leave $raw empty
        if ($this->hmac_check !== false) {
            $hmac = stream_get_contents($this->fsock, $this->hmac_size);
            if ($hmac === false || strlen($hmac) != $this->hmac_size) {
                $this->bitmap = 0;
                throw new \RuntimeException('Error reading socket');
            } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
                throw new \RuntimeException('Invalid HMAC');
            }
        }
        //if ($this->decompress) {
        //    $payload = gzinflate(substr($payload, 2));
        //}
        $this->get_seq_no++;
        if (defined('NET_SSH2_LOGGING')) {
            $current = microtime(true);
            $message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')';
            $message_number = '<- ' . $message_number . ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
            $this->_append_log($message_number, $payload);
            $this->last_packet = $current;
        }
        return $this->_filter($payload);
    }