diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 85cd9439..4b2bb8d1 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -869,7 +869,9 @@ class SSH2 /** * Default Constructor. * - * @param String $host + * $host can either be a string, representing the host, or a stream resource. + * + * @param Mixed $host * @param optional Integer $port * @param optional Integer $timeout * @see \phpseclib\Net\SSH2::login() @@ -954,9 +956,16 @@ class SSH2 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST') ); - $this->host = $host; - $this->port = $port; - $this->timeout = $timeout; + if (is_resource($host)) { + $this->fsock = $host; + return; + } + + if (is_string($host)) { + $this->host = $host; + $this->port = $port; + $this->timeout = $timeout; + } } /** @@ -993,19 +1002,21 @@ class SSH2 $this->last_packet = microtime(true); - $start = microtime(true); - $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout); - if (!$this->fsock) { - user_error(rtrim("Cannot connect to $host. Error $errno. $errstr")); - return false; - } - $elapsed = microtime(true) - $start; + if (!is_resource($this->fsock)) { + $start = microtime(true); + $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout); + if (!$this->fsock) { + user_error(rtrim("Cannot connect to $host. Error $errno. $errstr")); + return false; + } + $elapsed = microtime(true) - $start; - $this->curTimeout-= $elapsed; + $this->curTimeout-= $elapsed; - if ($this->curTimeout <= 0) { - $this->is_timeout = true; - return false; + if ($this->curTimeout <= 0) { + $this->is_timeout = true; + return false; + } } /* According to the SSH2 specs, diff --git a/tests/Functional/Net/SSH2Test.php b/tests/Functional/Net/SSH2Test.php index 44f18d1e..51373705 100644 --- a/tests/Functional/Net/SSH2Test.php +++ b/tests/Functional/Net/SSH2Test.php @@ -87,4 +87,17 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase $this->assertInternalType('string', $ssh->getServerPublicHostKey()); } + + public function testOpenSocketConnect() + { + $fsock = fsockopen($this->getEnv('SSH_HOSTNAME'), 22); + $ssh = new SSH2($fsock); + + $username = $this->getEnv('SSH_USERNAME'); + $password = $this->getEnv('SSH_PASSWORD'); + $this->assertTrue( + $ssh->login($username, $password), + 'SSH2 login using an open socket failed.' + ); + } }