Example #1
0
 /**
  * Connect to an SSHv1 server
  *
  * @access private
  * @return Boolean
  */
 public function _connect()
 {
     $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->connectionTimeout);
     if (!$this->fsock) {
         user_error(rtrim("Cannot connect to {$this->host}:{$this->port}. Error {$errno}. {$errstr}"));
         return false;
     }
     $this->server_identification = $init_line = fgets($this->fsock, 255);
     if (defined('NET_SSH1_LOGGING')) {
         $this->_append_log('<-', $this->server_identification);
         $this->_append_log('->', $this->identifier . "\r\n");
     }
     if (!preg_match('#SSH-([0-9\\.]+)-(.+)#', $init_line, $parts)) {
         user_error('Can only connect to SSH servers');
         return false;
     }
     if ($parts[1][0] != 1) {
         user_error("Cannot connect to SSH {$parts['1']} servers");
         return false;
     }
     fputs($this->fsock, $this->identifier . "\r\n");
     $response = $this->_get_binary_packet();
     if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
         user_error('Expected SSH_SMSG_PUBLIC_KEY');
         return false;
     }
     $anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8);
     $this->_string_shift($response[self::RESPONSE_DATA], 4);
     $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
     $server_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
     $this->server_key_public_exponent = $server_key_public_exponent;
     $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
     $server_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
     $this->server_key_public_modulus = $server_key_public_modulus;
     $this->_string_shift($response[self::RESPONSE_DATA], 4);
     $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
     $host_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
     $this->host_key_public_exponent = $host_key_public_exponent;
     $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
     $host_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
     $this->host_key_public_modulus = $host_key_public_modulus;
     $this->_string_shift($response[self::RESPONSE_DATA], 4);
     // get a list of the supported ciphers
     extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
     foreach ($this->supported_ciphers as $mask => $name) {
         if (($supported_ciphers_mask & 1 << $mask) == 0) {
             unset($this->supported_ciphers[$mask]);
         }
     }
     // get a list of the supported authentications
     extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
     foreach ($this->supported_authentications as $mask => $name) {
         if (($supported_authentications_mask & 1 << $mask) == 0) {
             unset($this->supported_authentications[$mask]);
         }
     }
     $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie));
     $session_key = Random::string(32);
     $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0));
     if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) {
         $double_encrypted_session_key = $this->_rsa_crypt($double_encrypted_session_key, array($server_key_public_exponent, $server_key_public_modulus));
         $double_encrypted_session_key = $this->_rsa_crypt($double_encrypted_session_key, array($host_key_public_exponent, $host_key_public_modulus));
     } else {
         $double_encrypted_session_key = $this->_rsa_crypt($double_encrypted_session_key, array($host_key_public_exponent, $host_key_public_modulus));
         $double_encrypted_session_key = $this->_rsa_crypt($double_encrypted_session_key, array($server_key_public_exponent, $server_key_public_modulus));
     }
     $cipher = isset($this->supported_ciphers[$this->cipher]) ? $this->cipher : self::CIPHER_3DES;
     $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);
     if (!$this->_send_binary_packet($data)) {
         user_error('Error sending SSH_CMSG_SESSION_KEY');
         return false;
     }
     switch ($cipher) {
         //case self::CIPHER_NONE:
         //    $this->crypto = new \Topxia\Service\Util\Phpsec\Crypt\Null();
         //    break;
         case self::CIPHER_DES:
             $this->crypto = new DES();
             $this->crypto->disablePadding();
             $this->crypto->enableContinuousBuffer();
             $this->crypto->setKey(substr($session_key, 0, 8));
             break;
         case self::CIPHER_3DES:
             $this->crypto = new TripleDES(TripleDES::MODE_3CBC);
             $this->crypto->disablePadding();
             $this->crypto->enableContinuousBuffer();
             $this->crypto->setKey(substr($session_key, 0, 24));
             break;
             //case self::CIPHER_RC4:
             //    $this->crypto = new RC4();
             //    $this->crypto->enableContinuousBuffer();
             //    $this->crypto->setKey(substr($session_key, 0,  16));
             //    break;
     }
     $response = $this->_get_binary_packet();
     if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
         user_error('Expected SSH_SMSG_SUCCESS');
         return false;
     }
     $this->bitmap = self::MASK_CONNECTED;
     return true;
 }
Example #2
0
 /**
  * Logical Exclusive-Or
  *
  * @access public
  * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
  * @param  \Topxia\Service\Util\Phpsec\Math\BigInteger   $x
  * @return \Topxia\Service\Util\Phpsec\Math\BigInteger
  */
 public function bitwise_xor($x)
 {
     switch (MATH_BIGINTEGER_MODE) {
         case self::MODE_GMP:
             $temp = new static();
             $temp->value = gmp_xor($this->value, $x->value);
             return $this->_normalize($temp);
         case self::MODE_BCMATH:
             $left = $this->toBytes();
             $right = $x->toBytes();
             $length = max(strlen($left), strlen($right));
             $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
             $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
             return $this->_normalize(new static($left ^ $right, 256));
     }
     $length = max(count($this->value), count($x->value));
     $result = $this->copy();
     $result->value = array_pad($result->value, $length, 0);
     $x->value = array_pad($x->value, $length, 0);
     for ($i = 0; $i < $length; ++$i) {
         $result->value[$i] ^= $x->value[$i];
     }
     return $this->_normalize($result);
 }