Ejemplo n.º 1
0
 /**
  * Exponentiate with or without Chinese Remainder Theorem
  *
  * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.
  *
  * @access private
  * @param BigInteger $x
  * @return BigInteger
  */
 function _exponentiate($x)
 {
     if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {
         return $x->modPow($this->exponent, $this->modulus);
     }
     $num_primes = count($this->primes);
     if (defined('RSA_DISABLE_BLINDING')) {
         $m_i = array(1 => $x->modPow($this->exponents[1], $this->primes[1]), 2 => $x->modPow($this->exponents[2], $this->primes[2]));
         $h = $m_i[1]->subtract($m_i[2]);
         $h = $h->multiply($this->coefficients[2]);
         list(, $h) = $h->divide($this->primes[1]);
         $m = $m_i[2]->add($h->multiply($this->primes[2]));
         $r = $this->primes[1];
         for ($i = 3; $i <= $num_primes; $i++) {
             $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);
             $r = $r->multiply($this->primes[$i - 1]);
             $h = $m_i->subtract($m);
             $h = $h->multiply($this->coefficients[$i]);
             list(, $h) = $h->divide($this->primes[$i]);
             $m = $m->add($r->multiply($h));
         }
     } else {
         $smallest = $this->primes[1];
         for ($i = 2; $i <= $num_primes; $i++) {
             if ($smallest->compare($this->primes[$i]) > 0) {
                 $smallest = $this->primes[$i];
             }
         }
         $one = new BigInteger(1);
         $one->setRandomGenerator('Random');
         $r = $one->random($one, $smallest->subtract($one));
         $m_i = array(1 => $this->_blind($x, $r, 1), 2 => $this->_blind($x, $r, 2));
         $h = $m_i[1]->subtract($m_i[2]);
         $h = $h->multiply($this->coefficients[2]);
         list(, $h) = $h->divide($this->primes[1]);
         $m = $m_i[2]->add($h->multiply($this->primes[2]));
         $r = $this->primes[1];
         for ($i = 3; $i <= $num_primes; $i++) {
             $m_i = $this->_blind($x, $r, $i);
             $r = $r->multiply($this->primes[$i - 1]);
             $h = $m_i->subtract($m);
             $h = $h->multiply($this->coefficients[$i]);
             list(, $h) = $h->divide($this->primes[$i]);
             $m = $m->add($r->multiply($h));
         }
     }
     return $m;
 }
Ejemplo n.º 2
0
 /**
  * Key Exchange
  *
  * @param String $kexinit_payload_server
  * @access private
  */
 function _key_exchange($kexinit_payload_server)
 {
     static $kex_algorithms = array('diffie-hellman-group1-sha1', 'diffie-hellman-group14-sha1');
     static $server_host_key_algorithms = array('ssh-rsa', 'ssh-dss');
     static $encryption_algorithms = array('arcfour256', 'arcfour128', 'arcfour', 'aes128-cbc', 'aes192-cbc', 'aes256-cbc', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', '3des-ctr', '3des-cbc', 'none');
     static $mac_algorithms = array('hmac-sha1-96', 'hmac-sha1', 'hmac-md5-96', 'hmac-md5', 'none');
     static $compression_algorithms = array('none');
     static $str_kex_algorithms, $str_server_host_key_algorithms, $encryption_algorithms_server_to_client, $mac_algorithms_server_to_client, $compression_algorithms_server_to_client, $encryption_algorithms_client_to_server, $mac_algorithms_client_to_server, $compression_algorithms_client_to_server;
     if (empty($str_kex_algorithms)) {
         $str_kex_algorithms = implode(',', $kex_algorithms);
         $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
         $encryption_algorithms_server_to_client = $encryption_algorithms_client_to_server = implode(',', $encryption_algorithms);
         $mac_algorithms_server_to_client = $mac_algorithms_client_to_server = implode(',', $mac_algorithms);
         $compression_algorithms_server_to_client = $compression_algorithms_client_to_server = implode(',', $compression_algorithms);
     }
     $client_cookie = '';
     for ($i = 0; $i < 16; $i++) {
         $client_cookie .= chr(Random(0, 255));
     }
     $response = $kexinit_payload_server;
     $this->_string_shift($response, 1);
     // skip past the message number (it should be SSH_MSG_KEXINIT)
     $server_cookie = $this->_string_shift($response, 16);
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->encryption_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->encryption_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->mac_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->mac_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->compression_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->compression_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->languages_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->languages_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
     extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
     $first_kex_packet_follows = $first_kex_packet_follows != 0;
     // the sending of SSH2_MSG_KEXINIT could go in one of two places.  this is the second place.
     $kexinit_payload_client = pack('Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN', SSH2_MSG_KEXINIT, $client_cookie, strlen($str_kex_algorithms), $str_kex_algorithms, strlen($str_server_host_key_algorithms), $str_server_host_key_algorithms, strlen($encryption_algorithms_client_to_server), $encryption_algorithms_client_to_server, strlen($encryption_algorithms_server_to_client), $encryption_algorithms_server_to_client, strlen($mac_algorithms_client_to_server), $mac_algorithms_client_to_server, strlen($mac_algorithms_server_to_client), $mac_algorithms_server_to_client, strlen($compression_algorithms_client_to_server), $compression_algorithms_client_to_server, strlen($compression_algorithms_server_to_client), $compression_algorithms_server_to_client, 0, '', 0, '', 0, 0);
     if (!$this->_send_binary_packet($kexinit_payload_client)) {
         return false;
     }
     // here ends the second place.
     // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
     for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_server_to_client); $i++) {
     }
     if ($i == count($encryption_algorithms)) {
         user_error('No compatible server to client encryption algorithms found', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
     // diffie-hellman key exchange as fast as possible
     $decrypt = $encryption_algorithms[$i];
     switch ($decrypt) {
         case '3des-cbc':
         case '3des-ctr':
             $decryptKeyLength = 24;
             // eg. 192 / 8
             break;
         case 'aes256-cbc':
         case 'aes256-ctr':
             $decryptKeyLength = 32;
             // eg. 256 / 8
             break;
         case 'aes192-cbc':
         case 'aes192-ctr':
             $decryptKeyLength = 24;
             // eg. 192 / 8
             break;
         case 'aes128-cbc':
         case 'aes128-ctr':
             $decryptKeyLength = 16;
             // eg. 128 / 8
             break;
         case 'arcfour':
         case 'arcfour128':
             $decryptKeyLength = 16;
             // eg. 128 / 8
             break;
         case 'arcfour256':
             $decryptKeyLength = 32;
             // eg. 128 / 8
             break;
         case 'none':
             $decryptKeyLength = 0;
     }
     for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_client_to_server); $i++) {
     }
     if ($i == count($encryption_algorithms)) {
         user_error('No compatible client to server encryption algorithms found', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $encrypt = $encryption_algorithms[$i];
     switch ($encrypt) {
         case '3des-cbc':
         case '3des-ctr':
             $encryptKeyLength = 24;
             break;
         case 'aes256-cbc':
         case 'aes256-ctr':
             $encryptKeyLength = 32;
             break;
         case 'aes192-cbc':
         case 'aes192-ctr':
             $encryptKeyLength = 24;
             break;
         case 'aes128-cbc':
         case 'aes128-ctr':
             $encryptKeyLength = 16;
             break;
         case 'arcfour':
         case 'arcfour128':
             $encryptKeyLength = 16;
             break;
         case 'arcfour256':
             $encryptKeyLength = 32;
             break;
         case 'none':
             $encryptKeyLength = 0;
     }
     $keyLength = $decryptKeyLength > $encryptKeyLength ? $decryptKeyLength : $encryptKeyLength;
     // through diffie-hellman key exchange a symmetric key is obtained
     for ($i = 0; $i < count($kex_algorithms) && !in_array($kex_algorithms[$i], $this->kex_algorithms); $i++) {
     }
     if ($i == count($kex_algorithms)) {
         user_error('No compatible key exchange algorithms found', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     switch ($kex_algorithms[$i]) {
         // see http://tools.ietf.org/html/rfc2409#section-6.2 and
         // http://tools.ietf.org/html/rfc2412, appendex E
         case 'diffie-hellman-group1-sha1':
             $p = pack('H256', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF');
             $keyLength = $keyLength < 160 ? $keyLength : 160;
             $hash = 'sha1';
             break;
             // see http://tools.ietf.org/html/rfc3526#section-3
         // see http://tools.ietf.org/html/rfc3526#section-3
         case 'diffie-hellman-group14-sha1':
             $p = pack('H512', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF');
             $keyLength = $keyLength < 160 ? $keyLength : 160;
             $hash = 'sha1';
     }
     $p = new BigInteger($p, 256);
     //$q = $p->bitwise_rightShift(1);
     /* To increase the speed of the key exchange, both client and server may
                reduce the size of their private exponents.  It should be at least
                twice as long as the key material that is generated from the shared
                secret.  For more details, see the paper by van Oorschot and Wiener
                [VAN-OORSCHOT].
     
                -- http://tools.ietf.org/html/rfc4419#section-6.2 */
     $q = new BigInteger(1);
     $q = $q->bitwise_leftShift(2 * $keyLength);
     $q = $q->subtract(new BigInteger(1));
     $g = new BigInteger(2);
     $x = new BigInteger();
     $x->setRandomGenerator('Random');
     $x = $x->random(new BigInteger(1), $q);
     $e = $g->modPow($x, $p);
     $eBytes = $e->toBytes(true);
     $data = pack('CNa*', SSH2_MSG_KEXDH_INIT, strlen($eBytes), $eBytes);
     if (!$this->_send_binary_packet($data)) {
         user_error('Connection closed by server', E_USER_NOTICE);
         return false;
     }
     $response = $this->_get_binary_packet();
     if ($response === false) {
         user_error('Connection closed by server', E_USER_NOTICE);
         return false;
     }
     extract(unpack('Ctype', $this->_string_shift($response, 1)));
     if ($type != SSH2_MSG_KEXDH_REPLY) {
         user_error('Expected SSH_MSG_KEXDH_REPLY', E_USER_NOTICE);
         return false;
     }
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->server_public_host_key = $server_public_host_key = $this->_string_shift($response, $temp['length']);
     $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
     $public_key_format = $this->_string_shift($server_public_host_key, $temp['length']);
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $fBytes = $this->_string_shift($response, $temp['length']);
     $f = new BigInteger($fBytes, -256);
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->signature = $this->_string_shift($response, $temp['length']);
     $temp = unpack('Nlength', $this->_string_shift($this->signature, 4));
     $this->signature_format = $this->_string_shift($this->signature, $temp['length']);
     $key = $f->modPow($x, $p);
     $keyBytes = $key->toBytes(true);
     $this->exchange_hash = pack('Na*Na*Na*Na*Na*Na*Na*Na*', strlen($this->identifier), $this->identifier, strlen($this->server_identifier), $this->server_identifier, strlen($kexinit_payload_client), $kexinit_payload_client, strlen($kexinit_payload_server), $kexinit_payload_server, strlen($this->server_public_host_key), $this->server_public_host_key, strlen($eBytes), $eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes);
     $this->exchange_hash = pack('H*', $hash($this->exchange_hash));
     if ($this->session_id === false) {
         $this->session_id = $this->exchange_hash;
     }
     for ($i = 0; $i < count($server_host_key_algorithms) && !in_array($server_host_key_algorithms[$i], $this->server_host_key_algorithms); $i++) {
     }
     if ($i == count($server_host_key_algorithms)) {
         user_error('No compatible server host key algorithms found', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) {
         user_error('Sever Host Key Algorithm Mismatch', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $packet = pack('C', SSH2_MSG_NEWKEYS);
     if (!$this->_send_binary_packet($packet)) {
         return false;
     }
     $response = $this->_get_binary_packet();
     if ($response === false) {
         user_error('Connection closed by server', E_USER_NOTICE);
         return false;
     }
     extract(unpack('Ctype', $this->_string_shift($response, 1)));
     if ($type != SSH2_MSG_NEWKEYS) {
         user_error('Expected SSH_MSG_NEWKEYS', E_USER_NOTICE);
         return false;
     }
     switch ($encrypt) {
         case '3des-cbc':
             $this->encrypt = new TripleDES();
             // $this->encrypt_block_size = 64 / 8 == the default
             break;
         case '3des-ctr':
             $this->encrypt = new TripleDES(DES_MODE_CTR);
             // $this->encrypt_block_size = 64 / 8 == the default
             break;
         case 'aes256-cbc':
         case 'aes192-cbc':
         case 'aes128-cbc':
             $this->encrypt = new AES();
             $this->encrypt_block_size = 16;
             // eg. 128 / 8
             break;
         case 'aes256-ctr':
         case 'aes192-ctr':
         case 'aes128-ctr':
             $this->encrypt = new AES(AES_MODE_CTR);
             $this->encrypt_block_size = 16;
             // eg. 128 / 8
             break;
         case 'arcfour':
         case 'arcfour128':
         case 'arcfour256':
             $this->encrypt = new RC4();
             break;
         case 'none':
             //$this->encrypt = new Crypt_Null();
     }
     switch ($decrypt) {
         case '3des-cbc':
             $this->decrypt = new TripleDES();
             break;
         case '3des-ctr':
             $this->decrypt = new TripleDES(DES_MODE_CTR);
             break;
         case 'aes256-cbc':
         case 'aes192-cbc':
         case 'aes128-cbc':
             $this->decrypt = new AES();
             $this->decrypt_block_size = 16;
             break;
         case 'aes256-ctr':
         case 'aes192-ctr':
         case 'aes128-ctr':
             $this->decrypt = new AES(AES_MODE_CTR);
             $this->decrypt_block_size = 16;
             break;
         case 'arcfour':
         case 'arcfour128':
         case 'arcfour256':
             $this->decrypt = new RC4();
             break;
         case 'none':
             //$this->decrypt = new Crypt_Null();
     }
     $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
     if ($this->encrypt) {
         $this->encrypt->enableContinuousBuffer();
         $this->encrypt->disablePadding();
         $iv = pack('H*', $hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id));
         while ($this->encrypt_block_size > strlen($iv)) {
             $iv .= pack('H*', $hash($keyBytes . $this->exchange_hash . $iv));
         }
         $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
         $key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id));
         while ($encryptKeyLength > strlen($key)) {
             $key .= pack('H*', $hash($keyBytes . $this->exchange_hash . $key));
         }
         $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
     }
     if ($this->decrypt) {
         $this->decrypt->enableContinuousBuffer();
         $this->decrypt->disablePadding();
         $iv = pack('H*', $hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id));
         while ($this->decrypt_block_size > strlen($iv)) {
             $iv .= pack('H*', $hash($keyBytes . $this->exchange_hash . $iv));
         }
         $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
         $key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id));
         while ($decryptKeyLength > strlen($key)) {
             $key .= pack('H*', $hash($keyBytes . $this->exchange_hash . $key));
         }
         $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
     }
     /* The "arcfour128" algorithm is the RC4 cipher, as described in
                [SCHNEIER], using a 128-bit key.  The first 1536 bytes of keystream
                generated by the cipher MUST be discarded, and the first byte of the
                first encrypted packet MUST be encrypted using the 1537th byte of
                keystream.
     
                -- http://tools.ietf.org/html/rfc4345#section-4 */
     if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') {
         $this->encrypt->encrypt(str_repeat("", 1536));
     }
     if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') {
         $this->decrypt->decrypt(str_repeat("", 1536));
     }
     for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++) {
     }
     if ($i == count($mac_algorithms)) {
         user_error('No compatible client to server message authentication algorithms found', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $createKeyLength = 0;
     // ie. $mac_algorithms[$i] == 'none'
     switch ($mac_algorithms[$i]) {
         case 'hmac-sha1':
             $this->hmac_create = new Hash('sha1');
             $createKeyLength = 20;
             break;
         case 'hmac-sha1-96':
             $this->hmac_create = new Hash('sha1-96');
             $createKeyLength = 20;
             break;
         case 'hmac-md5':
             $this->hmac_create = new Hash('md5');
             $createKeyLength = 16;
             break;
         case 'hmac-md5-96':
             $this->hmac_create = new Hash('md5-96');
             $createKeyLength = 16;
     }
     for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_server_to_client); $i++) {
     }
     if ($i == count($mac_algorithms)) {
         user_error('No compatible server to client message authentication algorithms found', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $checkKeyLength = 0;
     $this->hmac_size = 0;
     switch ($mac_algorithms[$i]) {
         case 'hmac-sha1':
             $this->hmac_check = new Hash('sha1');
             $checkKeyLength = 20;
             $this->hmac_size = 20;
             break;
         case 'hmac-sha1-96':
             $this->hmac_check = new Hash('sha1-96');
             $checkKeyLength = 20;
             $this->hmac_size = 12;
             break;
         case 'hmac-md5':
             $this->hmac_check = new Hash('md5');
             $checkKeyLength = 16;
             $this->hmac_size = 16;
             break;
         case 'hmac-md5-96':
             $this->hmac_check = new Hash('md5-96');
             $checkKeyLength = 16;
             $this->hmac_size = 12;
     }
     $key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id));
     while ($createKeyLength > strlen($key)) {
         $key .= pack('H*', $hash($keyBytes . $this->exchange_hash . $key));
     }
     $this->hmac_create->setKey(substr($key, 0, $createKeyLength));
     $key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id));
     while ($checkKeyLength > strlen($key)) {
         $key .= pack('H*', $hash($keyBytes . $this->exchange_hash . $key));
     }
     $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
     for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_server_to_client); $i++) {
     }
     if ($i == count($compression_algorithms)) {
         user_error('No compatible server to client compression algorithms found', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $this->decompress = $compression_algorithms[$i] == 'zlib';
     for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_client_to_server); $i++) {
     }
     if ($i == count($compression_algorithms)) {
         user_error('No compatible client to server compression algorithms found', E_USER_NOTICE);
         return $this->_disconnect(SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $this->compress = $compression_algorithms[$i] == 'zlib';
     return true;
 }