phpseclib\Net\SSH2::_connect PHP Метод

_connect() публичный Метод

Connect to an SSHv2 server
public _connect ( ) : boolean
Результат boolean
    function _connect()
    {
        if ($this->bitmap & self::MASK_CONSTRUCTOR) {
            return false;
        }
        $this->bitmap |= self::MASK_CONSTRUCTOR;
        $this->curTimeout = $this->timeout;
        $this->last_packet = microtime(true);
        if (!is_resource($this->fsock)) {
            $start = microtime(true);
            // with stream_select a timeout of 0 means that no timeout takes place;
            // with fsockopen a timeout of 0 means that you instantly timeout
            // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0
            $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout);
            if (!$this->fsock) {
                $host = $this->host . ':' . $this->port;
                throw new \RuntimeException(rtrim("Cannot connect to {$host}. Error {$errno}. {$errstr}"));
            }
            $elapsed = microtime(true) - $start;
            $this->curTimeout -= $elapsed;
            if ($this->curTimeout <= 0) {
                $this->is_timeout = true;
                return false;
            }
        }
        $this->identifier = $this->_generate_identifier();
        fputs($this->fsock, $this->identifier . "\r\n");
        /* According to the SSH2 specs,
        
                  "The server MAY send other lines of data before sending the version
                   string.  Each line SHOULD be terminated by a Carriage Return and Line
                   Feed.  Such lines MUST NOT begin with "SSH-", and SHOULD be encoded
                   in ISO-10646 UTF-8 [RFC3629] (language is not specified).  Clients
                   MUST be able to process such lines." */
        $data = '';
        while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\\d\\.\\d+).*)#ms', $data, $matches)) {
            $line = '';
            while (true) {
                if ($this->curTimeout) {
                    if ($this->curTimeout < 0) {
                        $this->is_timeout = true;
                        return false;
                    }
                    $read = array($this->fsock);
                    $write = $except = null;
                    $start = microtime(true);
                    $sec = floor($this->curTimeout);
                    $usec = 1000000 * ($this->curTimeout - $sec);
                    // on windows this returns a "Warning: Invalid CRT parameters detected" error
                    // the !count() is done as a workaround for <https://bugs.php.net/42682>
                    if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
                        $this->is_timeout = true;
                        return false;
                    }
                    $elapsed = microtime(true) - $start;
                    $this->curTimeout -= $elapsed;
                }
                $temp = stream_get_line($this->fsock, 255, "\n");
                if (strlen($temp) == 255) {
                    continue;
                }
                $line .= "{$temp}\n";
                // quoting RFC4253, "Implementers who wish to maintain
                // compatibility with older, undocumented versions of this protocol may
                // want to process the identification string without expecting the
                // presence of the carriage return character for reasons described in
                // Section 5 of this document."
                //if (substr($line, -2) == "\r\n") {
                //    break;
                //}
                break;
            }
            $data .= $line;
        }
        if (feof($this->fsock)) {
            throw new \RuntimeException('Connection closed by server');
        }
        $extra = $matches[1];
        if (defined('NET_SSH2_LOGGING')) {
            $this->_append_log('<-', $matches[0]);
            $this->_append_log('->', $this->identifier . "\r\n");
        }
        $this->server_identifier = trim($temp, "\r\n");
        if (strlen($extra)) {
            $this->errors[] = utf8_decode($data);
        }
        if ($matches[3] != '1.99' && $matches[3] != '2.0') {
            throw new \RuntimeException("Cannot connect to SSH {$matches['1']} servers");
        }
        $response = $this->_get_binary_packet();
        if ($response === false) {
            throw new \RuntimeException('Connection closed by server');
        }
        if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
            throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
        }
        if (!$this->_key_exchange($response)) {
            return false;
        }
        $this->bitmap |= self::MASK_CONNECTED;
        return true;
    }