예제 #1
0
 def _check_keypair_from_file(self, ref_fingerprint, private_key_path):
     """Function to check if a certain keypair from a file matches the fingerprint
     from a reference one
     :param str ref_fingerprint: fingerprint to be compared
     :raises: KeypairError: if the keypair is not valid, or if the fingerprint to check
                         and the one computed from the private key is not the same
     :raises: KeyNotAccessible: if the private key is password protected
                         and the password provided is not correct
     """
     
     pkey=None
     
     # This block avoid repetition of checks after it is done for the first instance
     if self._SSH_KEY_CHECKED==True:
         if self._SSH_KEY_ACCESS_ERROR==True: # This avoid user entering the code right the second time
             raise KeyNotAccessible#("Unable to access key file `"+private_key_path+": Invalid password")  
         else:
             return
     try:
         pkey=DSSKey.from_private_key_file(private_key_path)
     except PasswordRequiredException:
         try:
             asked_password = getpass.getpass('Enter passphrase for '+private_key_path+ ':')
             pkey=DSSKey.from_private_key_file(private_key_path,asked_password)
         except SSHException:
             self._SSH_KEY_CHECKED=True
             self._SSH_KEY_ACCESS_ERROR=True # This avoid user entering the code right the second time
             raise KeyNotAccessible#("Unable to access key file `"+private_key_path+": Invalid password")      
     except SSHException:
         try:
             pkey=RSAKey.from_private_key_file(private_key_path)
         except PasswordRequiredException:
             try:
                 asked_password = getpass.getpass('Enter passphrase for '+private_key_path+ ':')
                 pkey=RSAKey.from_private_key_file(private_key_path,asked_password)
             except SSHException:
                 self._SSH_KEY_CHECKED=True
                 self._SSH_KEY_ACCESS_ERROR=True # This avoid user entering the code right the second time
                 raise KeyNotAccessible#("Unable to access key file `"+private_key_path+": Invalid password")  
         except SSHException:
             raise KeypairError('File `%s` is neither a valid DSA key '
                                'or RSA key' % private_key_path)
     fingerprint = str.join(
             ':', (i.encode('hex') for i in pkey.get_fingerprint()))
     if ref_fingerprint!=fingerprint:
         raise KeypairError(
             "Keypair from "+private_key_path+" is present but has "
             "different fingerprint. Aborting!")
     self._SSH_KEY_CHECKED=True
     return
예제 #2
0
    def _set_authentication(self, password, private_key, private_key_pass):
        '''Authenticate the transport. prefer password if given'''
        if password is None:
            # Use Private Key.
            if not private_key:
                # Try to use default key.
                if os.path.exists(os.path.expanduser('~/.ssh/id_rsa')):
                    private_key = '~/.ssh/id_rsa'
                elif os.path.exists(os.path.expanduser('~/.ssh/id_dsa')):
                    private_key = '~/.ssh/id_dsa'
                else:
                    raise CredentialException("No password or key specified.")

            if isinstance(private_key, (AgentKey, RSAKey)):
                # use the paramiko agent or rsa key
                self._tconnect['pkey'] = private_key
            else:
                # isn't a paramiko AgentKey or RSAKey, try to build a
                # key from what we assume is a path to a key
                private_key_file = os.path.expanduser(private_key)
                try:  # try rsa
                    self._tconnect['pkey'] = RSAKey.from_private_key_file(
                        private_key_file, private_key_pass)
                except paramiko.SSHException:   # if it fails, try dss
                    # pylint:disable=r0204
                    self._tconnect['pkey'] = DSSKey.from_private_key_file(
                        private_key_file, private_key_pass)
예제 #3
0
    def from_file(filename, password = '', keytype = None):
        """
        Returns a new PrivateKey instance with the given attributes.
        If keytype is None, we attempt to automatically detect the type.

        @type  filename: string
        @param filename: The key file name.
        @type  password: string
        @param password: The key password.
        @type  keytype: string
        @param keytype: The key type.
        @rtype:  PrivateKey
        @return: The new key.
        """
        if keytype is None:
            try:
                key = RSAKey.from_private_key_file(filename)
                keytype = 'rsa'
            except SSHException, e:
                try:
                    key = DSSKey.from_private_key_file(filename)
                    keytype = 'dss'
                except SSHException, e:
                    msg = 'not a recognized private key: ' + repr(filename)
                    raise ValueError(msg)
예제 #4
0
    def _set_authentication(self, password, private_key, private_key_pass):
        '''Authenticate the transport. prefer password if given'''
        if password is None:
            # Use Private Key.
            if not private_key:
                # Try to use default key.
                if os.path.exists(os.path.expanduser('~/.ssh/id_rsa')):
                    private_key = '~/.ssh/id_rsa'
                elif os.path.exists(os.path.expanduser('~/.ssh/id_dsa')):
                    private_key = '~/.ssh/id_dsa'
                else:
                    raise CredentialException("No password or key specified.")

            if isinstance(private_key, (AgentKey, RSAKey)):
                # use the paramiko agent or rsa key
                self._tconnect['pkey'] = private_key
            else:
                # isn't a paramiko AgentKey or RSAKey, try to build a
                # key from what we assume is a path to a key
                private_key_file = os.path.expanduser(private_key)
                try:  # try rsa
                    self._tconnect['pkey'] = RSAKey.from_private_key_file(
                        private_key_file, private_key_pass)
                except paramiko.SSHException:  # if it fails, try dss
                    # pylint:disable=r0204
                    self._tconnect['pkey'] = DSSKey.from_private_key_file(
                        private_key_file, private_key_pass)
예제 #5
0
 def test_load_dss_password(self):
     key = DSSKey.from_private_key_file(_support("test_dss_password.key"),
                                        "television")
     self.assertEqual("ssh-dss", key.get_name())
     self.assert_key_fingerprints(key, FINGER_DSS)
     self.assertEqual(PUB_DSS.split()[1], key.get_base64())
     self.assertEqual(1024, key.get_bits())
예제 #6
0
class NullServer (ServerInterface):
    paranoid_did_password = False
    paranoid_did_public_key = False
    paranoid_key = DSSKey.from_private_key_file(test_path('test_dss.key'))

    def get_allowed_auths(self, username):
        if username == 'slowdive':
            return 'publickey,password'
        if username == 'paranoid':
            if not self.paranoid_did_password and not self.paranoid_did_public_key:
                return 'publickey,password'
            elif self.paranoid_did_password:
                return 'publickey'
            else:
                return 'password'
        if username == 'commie':
            return 'keyboard-interactive'
        if username == 'utf8':
            return 'password'
        if username == 'non-utf8':
            return 'password'
        return 'publickey'

    def check_auth_password(self, username, password):
        if (username == 'slowdive') and (password == 'pygmalion'):
            return AUTH_SUCCESSFUL
        if (username == 'paranoid') and (password == 'paranoid'):
            # 2-part auth (even openssh doesn't support this)
            self.paranoid_did_password = True
            if self.paranoid_did_public_key:
                return AUTH_SUCCESSFUL
            return AUTH_PARTIALLY_SUCCESSFUL
        if (username == 'utf8') and (password == _pwd):
            return AUTH_SUCCESSFUL
        if (username == 'non-utf8') and (password == '\xff'):
            return AUTH_SUCCESSFUL
        if username == 'bad-server':
            raise Exception("Ack!")
        return AUTH_FAILED

    def check_auth_publickey(self, username, key):
        if (username == 'paranoid') and (key == self.paranoid_key):
            # 2-part auth
            self.paranoid_did_public_key = True
            if self.paranoid_did_password:
                return AUTH_SUCCESSFUL
            return AUTH_PARTIALLY_SUCCESSFUL
        return AUTH_FAILED

    def check_auth_interactive(self, username, submethods):
        if username == 'commie':
            self.username = username
            return InteractiveQuery('password', 'Please enter a password.', ('Password', False))
        return AUTH_FAILED

    def check_auth_interactive_response(self, responses):
        if self.username == 'commie':
            if (len(responses) == 1) and (responses[0] == 'cat'):
                return AUTH_SUCCESSFUL
        return AUTH_FAILED
예제 #7
0
    def from_file(filename, password='', keytype=None):
        """
        Returns a new PrivateKey instance with the given attributes.
        If keytype is None, we attempt to automatically detect the type.

        :type  filename: string
        :param filename: The key file name.
        :type  password: string
        :param password: The key password.
        :type  keytype: string
        :param keytype: The key type.
        :rtype:  PrivateKey
        :return: The new key.
        """
        if keytype is None:
            try:
                key = RSAKey.from_private_key_file(filename)
                keytype = 'rsa'
            except SSHException as e:
                try:
                    key = DSSKey.from_private_key_file(filename)
                    keytype = 'dss'
                except SSHException as e:
                    msg = 'not a recognized private key: ' + repr(filename)
                    raise ValueError(msg)
        key = PrivateKey(keytype)
        key.filename = filename
        key.password = password
        return key
예제 #8
0
    def __init__(self,
                 host,
                 user,
                 private_key_file,
                 private_key_passwd,
                 known_hosts_file,
                 port=22,
                 key_type="RSA"):
        """
        Creates a new sftp connection. Currently only with auth over key-file

        :param str host: host-name (dns/ip)
        :param str user: user-name
        :param str private_key_file: path to private key file
        :param str private_key_passwd: password which protects your private key file
        :param str known_hosts_file: path to known_hosts file
        :param int port: port to server, default: 22
        :param str key_type: RSA/DSA type of your private key file
        """
        if key_type == "RSA":
            p_key = RSAKey.from_private_key_file(private_key_file,
                                                 private_key_passwd)
        elif key_type == "DSA":
            p_key = DSSKey.from_private_key_file(private_key_file,
                                                 private_key_passwd)

        self._ssh = SSHClient()
        self._ssh.load_host_keys(known_hosts_file)
        self._ssh.connect(hostname=host, username=user, port=port, pkey=p_key)
        self._sftp = self._ssh.open_sftp()
예제 #9
0
 def test_7_compare_dss(self):
     # verify that the private & public keys compare equal
     key = DSSKey.from_private_key_file('tests/test_dss.key')
     self.assertEquals(key, key)
     pub = DSSKey(data=str(key))
     self.assert_(key.can_sign())
     self.assert_(not pub.can_sign())
     self.assertEquals(key, pub)
예제 #10
0
 def test_7_compare_dss(self):
     # verify that the private & public keys compare equal
     key = DSSKey.from_private_key_file('tests/test_dss.key')
     self.assertEquals(key, key)
     pub = DSSKey(data=str(key))
     self.assert_(key.can_sign())
     self.assert_(not pub.can_sign())
     self.assertEquals(key, pub)
예제 #11
0
 def test_5_load_dss_password(self):
     key = DSSKey.from_private_key_file('tests/test_dss_password.key', 'television')
     self.assertEquals('ssh-dss', key.get_name())
     exp_dss = FINGER_DSS.split()[1].replace(':', '')
     my_dss = hexlify(key.get_fingerprint())
     self.assertEquals(exp_dss, my_dss)
     self.assertEquals(PUB_DSS.split()[1], key.get_base64())
     self.assertEquals(1024, key.get_bits())
예제 #12
0
 def test_7_compare_dss(self):
     # verify that the private & public keys compare equal
     key = DSSKey.from_private_key_file(test_path('test_dss.key'))
     self.assertEqual(key, key)
     pub = DSSKey(data=key.asbytes())
     self.assertTrue(key.can_sign())
     self.assertTrue(not pub.can_sign())
     self.assertEqual(key, pub)
예제 #13
0
 def test_5_load_dss_password(self):
     key = DSSKey.from_private_key_file(test_path("test_dss_password.key"), "television")
     self.assertEqual("ssh-dss", key.get_name())
     exp_dss = b(FINGER_DSS.split()[1].replace(":", ""))
     my_dss = hexlify(key.get_fingerprint())
     self.assertEqual(exp_dss, my_dss)
     self.assertEqual(PUB_DSS.split()[1], key.get_base64())
     self.assertEqual(1024, key.get_bits())
예제 #14
0
 def test_5_load_dss_password(self):
     key = DSSKey.from_private_key_file(test_path('test_dss_password.key'), 'television')
     self.assertEqual('ssh-dss', key.get_name())
     exp_dss = b(FINGER_DSS.split()[1].replace(':', ''))
     my_dss = hexlify(key.get_fingerprint())
     self.assertEqual(exp_dss, my_dss)
     self.assertEqual(PUB_DSS.split()[1], key.get_base64())
     self.assertEqual(1024, key.get_bits())
예제 #15
0
 def test_7_compare_dss(self):
     # verify that the private & public keys compare equal
     key = DSSKey.from_private_key_file(_support("test_dss.key"))
     self.assertEqual(key, key)
     pub = DSSKey(data=key.asbytes())
     self.assertTrue(key.can_sign())
     self.assertTrue(not pub.can_sign())
     self.assertEqual(key, pub)
예제 #16
0
 def test_load_openssh_format_DSS_key(self):
     key = DSSKey.from_private_key_file(_support("test_dss_openssh.key"),
                                        b"television")
     self.assertEqual("ssh-dss", key.get_name())
     self.assertEqual(PUB_DSS_1K_OPENSSH.split()[1], key.get_base64())
     self.assertEqual(1024, key.get_bits())
     exp_rsa = b(FINGER_DSS_1K_OPENSSH.split()[1].replace(":", ""))
     my_rsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_rsa, my_rsa)
예제 #17
0
 def test_load_dss_password(self):
     key = DSSKey.from_private_key_file(_support("test_dss_password.key"),
                                        "television")
     self.assertEqual("ssh-dss", key.get_name())
     exp_dss = b(FINGER_DSS.split()[1].replace(":", ""))
     my_dss = hexlify(key.get_fingerprint())
     self.assertEqual(exp_dss, my_dss)
     self.assertEqual(PUB_DSS.split()[1], key.get_base64())
     self.assertEqual(1024, key.get_bits())
예제 #18
0
class NullServer(ServerInterface):
    paranoid_did_password = False
    paranoid_did_public_key = False
    paranoid_key = DSSKey.from_private_key_file(_support('test_dss.key'))

    def get_allowed_auths(self, username):
        if username == 'slowdive':
            return 'publickey,password'
        return 'publickey'

    def check_auth_password(self, username, password):
        if (username == 'slowdive') and (password == 'pygmalion'):
            return AUTH_SUCCESSFUL
        return AUTH_FAILED

    def check_channel_request(self, kind, chanid):
        if kind == 'bogus':
            return OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
        return OPEN_SUCCEEDED

    def check_channel_exec_request(self, channel, command):
        if command != b'yes':
            return False
        return True

    def check_channel_shell_request(self, channel):
        return True

    def check_global_request(self, kind, msg):
        self._global_request = kind
        # NOTE: for w/e reason, older impl of this returned False always, even
        # tho that's only supposed to occur if the request cannot be served.
        # For now, leaving that the default unless test supplies specific
        # 'acceptable' request kind
        return kind == 'acceptable'

    def check_channel_x11_request(self, channel, single_connection,
                                  auth_protocol, auth_cookie, screen_number):
        self._x11_single_connection = single_connection
        self._x11_auth_protocol = auth_protocol
        self._x11_auth_cookie = auth_cookie
        self._x11_screen_number = screen_number
        return True

    def check_port_forward_request(self, addr, port):
        self._listen = socket.socket()
        self._listen.bind(('127.0.0.1', 0))
        self._listen.listen(1)
        return self._listen.getsockname()[1]

    def cancel_port_forward_request(self, addr, port):
        self._listen.close()
        self._listen = None

    def check_channel_direct_tcpip_request(self, chanid, origin, destination):
        self._tcpip_dest = destination
        return OPEN_SUCCEEDED
예제 #19
0
 def test_load_DSS_key_new_format(self):
     key = DSSKey.from_private_key_file(_support('test_dss_1k_o.key'),
                                        b'television')
     self.assertEqual('ssh-dss', key.get_name())
     self.assertEqual(PUB_DSS_1K_OPENSSH.split()[1], key.get_base64())
     self.assertEqual(1024, key.get_bits())
     exp_rsa = b(FINGER_DSS_1K_OPENSSH.split()[1].replace(':', ''))
     my_rsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_rsa, my_rsa)
예제 #20
0
    def test_load_dss(self):
        key = DSSKey.from_private_key_file(_support('test_dss.key'))
        self.assert_key_values(key, 'ssh-dss', 1024, PUB_DSS,
                               FINGER_DSS.split()[1], FINGER_SHA256_DSS)

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(DSS_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = DSSKey.from_private_key(s)
        self.assertEqual(key, key2)
예제 #21
0
 def test_3_multipart_auth(self):
     """
     verify that multipart auth works.
     """
     self.start_server()
     self.tc.connect(hostkey=self.public_host_key)
     remain = self.tc.auth_password(username='******', password='******')
     self.assertEqual(['publickey'], remain)
     key = DSSKey.from_private_key_file(test_path('test_dss.key'))
     remain = self.tc.auth_publickey(username='******', key=key)
     self.assertEqual([], remain)
     self.verify_finished()
예제 #22
0
class NullServer(ServerInterface):
    paranoid_did_password = False
    paranoid_did_public_key = False
    paranoid_key = DSSKey.from_private_key_file(test_path('test_dss.key'))

    def get_allowed_auths(self, username):
        if username == 'slowdive':
            return 'publickey,password'
        return 'publickey'

    def check_auth_password(self, username, password):
        if (username == 'slowdive') and (password == 'pygmalion'):
            return AUTH_SUCCESSFUL
        return AUTH_FAILED

    def check_channel_request(self, kind, chanid):
        if kind == 'bogus':
            return OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
        return OPEN_SUCCEEDED

    def check_channel_exec_request(self, channel, command):
        if command != 'yes':
            return False
        return True

    def check_channel_shell_request(self, channel):
        return True

    def check_global_request(self, kind, msg):
        self._global_request = kind
        return False

    def check_channel_x11_request(self, channel, single_connection,
                                  auth_protocol, auth_cookie, screen_number):
        self._x11_single_connection = single_connection
        self._x11_auth_protocol = auth_protocol
        self._x11_auth_cookie = auth_cookie
        self._x11_screen_number = screen_number
        return True

    def check_port_forward_request(self, addr, port):
        self._listen = socket.socket()
        self._listen.bind(('127.0.0.1', 0))
        self._listen.listen(1)
        return self._listen.getsockname()[1]

    def cancel_port_forward_request(self, addr, port):
        self._listen.close()
        self._listen = None

    def check_channel_direct_tcpip_request(self, chanid, origin, destination):
        self._tcpip_dest = destination
        return OPEN_SUCCEEDED
예제 #23
0
 def test_multipart_auth(self):
     """
     verify that multipart auth works.
     """
     self.start_server()
     self.tc.connect(hostkey=self.public_host_key)
     remain = self.tc.auth_password(username='******', password='******')
     self.assertEqual(['publickey'], remain)
     key = DSSKey.from_private_key_file(_support('test_dss.key'))
     remain = self.tc.auth_publickey(username='******', key=key)
     self.assertEqual([], remain)
     self.verify_finished()
예제 #24
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        connection = self._connect()
        keypairs = connection.get_all_key_pairs()
        keypairs = dict((k.name, k) for k in keypairs)

        # decide if dsa or rsa key is provided
        pkey = None
        is_dsa_key = False
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
            is_dsa_key = True
        except PasswordRequiredException:
            raise KeypairError(
                "Key `%s` is encrypted with a password. Please, use"
                "an unencrypted key or use ssh-agent" %
                private_key_path)
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                raise KeypairError(
                    "Key `%s` is encrypted with a password. Please, use"
                    "an unencrypted key or use ssh-agent" %
                    private_key_path)
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        # create keys that don't exist yet
        if name not in keypairs:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._url)
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    # check for DSA on amazon
                    if "amazon" in self._ec2host and is_dsa_key:
                        log.error(
                            "Apparently, amazon does not support DSA keys. "
                            "Please specify a valid RSA key.")
                        raise KeypairError(
                            "Apparently, amazon does not support DSA keys."
                            "Please specify a valid RSA key.")

                    connection.import_key_pair(name, key_material)
                except Exception, ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._url)
                    raise KeypairError(
                        "could not create keypair `%s`: %s" % (name, ex))
예제 #25
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        connection = self._connect()
        keypairs = connection.get_all_key_pairs()
        keypairs = dict((k.name, k) for k in keypairs)

        # decide if dsa or rsa key is provided
        pkey = None
        is_dsa_key = False
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
            is_dsa_key = True
        except PasswordRequiredException:
            log.warning(
                "Unable to check key file `%s` because it is encrypted with a "
                "password. Please, ensure that you added it to the SSH agent "
                "with `ssh-add %s`", private_key_path, private_key_path)
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                log.warning(
                    "Unable to check key file `%s` because it is encrypted with a "
                    "password. Please, ensure that you added it to the SSH agent "
                    "with `ssh-add %s`", private_key_path, private_key_path)
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        # create keys that don't exist yet
        if name not in keypairs:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._url)
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    # check for DSA on amazon
                    if "amazon" in self._ec2host and is_dsa_key:
                        log.error(
                            "Apparently, amazon does not support DSA keys. "
                            "Please specify a valid RSA key.")
                        raise KeypairError(
                            "Apparently, amazon does not support DSA keys."
                            "Please specify a valid RSA key.")

                    connection.import_key_pair(name, key_material)
                except Exception, ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._url)
                    raise KeypairError(
                        "could not create keypair `%s`: %s" % (name, ex))
예제 #26
0
 def test_multipart_auth(self, trans):
     """
     verify that multipart auth works.
     """
     trans.connect()
     remains = trans.auth_password(
         username='******',
         password='******',
     )
     assert remains == ['publickey']
     key = DSSKey.from_private_key_file(_support('test_dss.key'))
     remains = trans.auth_publickey(username='******', key=key)
     assert remains == []
예제 #27
0
    def test_load_dss(self):
        key = DSSKey.from_private_key_file(_support("test_dss.key"))
        self.assertEqual("ssh-dss", key.get_name())
        self.assert_key_fingerprints(key, FINGER_DSS)
        self.assertEqual(PUB_DSS.split()[1], key.get_base64())
        self.assertEqual(1024, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(DSS_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = DSSKey.from_private_key(s)
        self.assertEqual(key, key2)
예제 #28
0
 def test_9_sign_dss(self):
     # verify that the dss private key can sign and verify
     key = DSSKey.from_private_key_file(test_path('test_dss.key'))
     msg = key.sign_ssh_data(b'ice weasels')
     self.assertTrue(type(msg) is Message)
     msg.rewind()
     self.assertEqual('ssh-dss', msg.get_text())
     # can't do the same test as we do for RSA, because DSS signatures
     # are usually different each time.  but we can test verification
     # anyway so it's ok.
     self.assertEqual(40, len(msg.get_binary()))
     msg.rewind()
     pub = DSSKey(data=key.asbytes())
     self.assertTrue(pub.verify_ssh_sig(b'ice weasels', msg))
예제 #29
0
 def test_3_multipart_auth(self):
     """
     verify that multipart auth works.
     """
     self.start_server()
     self.tc.connect(hostkey=self.public_host_key)
     remain = self.tc.auth_password(
         username="******", password="******"
     )
     self.assertEqual(["publickey"], remain)
     key = DSSKey.from_private_key_file(_support("test_dss.key"))
     remain = self.tc.auth_publickey(username="******", key=key)
     self.assertEqual([], remain)
     self.verify_finished()
예제 #30
0
 def test_9_sign_dss(self):
     # verify that the dss private key can sign and verify
     key = DSSKey.from_private_key_file('tests/test_dss.key')
     msg = key.sign_ssh_data(rng, 'ice weasels')
     self.assert_(type(msg) is Message)
     msg.rewind()
     self.assertEquals('ssh-dss', msg.get_string())
     # can't do the same test as we do for RSA, because DSS signatures
     # are usually different each time.  but we can test verification
     # anyway so it's ok.
     self.assertEquals(40, len(msg.get_string()))
     msg.rewind()
     pub = DSSKey(data=str(key))
     self.assert_(pub.verify_ssh_sig('ice weasels', msg))
예제 #31
0
 def test_9_pubkey_probe(self):
     """
     verify whether publickey would be accepted.
     """
     self.start_server()
     self.tc.connect(hostkey=self.public_host_key)
     key = DSSKey.from_private_key_file(test_path('test_dss.key'))
     self.tc.auth_publickey(username='******', key=key, probe=True)
     self.assertEqual(True, self.tc.is_publickey_probe_ok())
     self.assertEqual(False, self.tc.is_authenticated())
     self.tc.auth_publickey(username='******', key=key)
     self.assertEqual(False, self.tc.is_publickey_probe_ok())
     self.assertEqual(False, self.tc.is_authenticated())
     self.verify_finished()
예제 #32
0
 def test_9_sign_dss(self):
     # verify that the dss private key can sign and verify
     key = DSSKey.from_private_key_file(_support("test_dss.key"))
     msg = key.sign_ssh_data(b"ice weasels")
     self.assertTrue(type(msg) is Message)
     msg.rewind()
     self.assertEqual("ssh-dss", msg.get_text())
     # can't do the same test as we do for RSA, because DSS signatures
     # are usually different each time.  but we can test verification
     # anyway so it's ok.
     self.assertEqual(40, len(msg.get_binary()))
     msg.rewind()
     pub = DSSKey(data=key.asbytes())
     self.assertTrue(pub.verify_ssh_sig(b"ice weasels", msg))
예제 #33
0
 def test_9_sign_dss(self):
     # verify that the dss private key can sign and verify
     key = DSSKey.from_private_key_file('tests/test_dss.key')
     msg = key.sign_ssh_data(randpool, 'ice weasels')
     self.assert_(type(msg) is Message)
     msg.rewind()
     self.assertEquals('ssh-dss', msg.get_string())
     # can't do the same test as we do for RSA, because DSS signatures
     # are usually different each time.  but we can test verification
     # anyway so it's ok.
     self.assertEquals(40, len(msg.get_string()))
     msg.rewind()
     pub = DSSKey(data=str(key))
     self.assert_(pub.verify_ssh_sig('ice weasels', msg))
예제 #34
0
    def test_4_load_dss(self):
        key = DSSKey.from_private_key_file('tests/test_dss.key')
        self.assertEquals('ssh-dss', key.get_name())
        exp_dss = FINGER_DSS.split()[1].replace(':', '')
        my_dss = hexlify(key.get_fingerprint())
        self.assertEquals(exp_dss, my_dss)
        self.assertEquals(PUB_DSS.split()[1], key.get_base64())
        self.assertEquals(1024, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEquals(DSS_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = DSSKey.from_private_key(s)
        self.assertEquals(key, key2)
예제 #35
0
    def test_4_load_dss(self):
        key = DSSKey.from_private_key_file('tests/test_dss.key')
        self.assertEquals('ssh-dss', key.get_name())
        exp_dss = FINGER_DSS.split()[1].replace(':', '')
        my_dss = hexlify(key.get_fingerprint())
        self.assertEquals(exp_dss, my_dss)
        self.assertEquals(PUB_DSS.split()[1], key.get_base64())
        self.assertEquals(1024, key.get_bits())

        s = StringIO.StringIO()
        key.write_private_key(s)
        self.assertEquals(DSS_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = DSSKey.from_private_key(s)
        self.assertEquals(key, key2)
예제 #36
0
    def test_4_load_dss(self):
        key = DSSKey.from_private_key_file(_support("test_dss.key"))
        self.assertEqual("ssh-dss", key.get_name())
        exp_dss = b(FINGER_DSS.split()[1].replace(":", ""))
        my_dss = hexlify(key.get_fingerprint())
        self.assertEqual(exp_dss, my_dss)
        self.assertEqual(PUB_DSS.split()[1], key.get_base64())
        self.assertEqual(1024, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(DSS_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = DSSKey.from_private_key(s)
        self.assertEqual(key, key2)
예제 #37
0
    def test_4_load_dss(self):
        key = DSSKey.from_private_key_file(_support("test_dss.key"))
        self.assertEqual("ssh-dss", key.get_name())
        exp_dss = b(FINGER_DSS.split()[1].replace(":", ""))
        my_dss = hexlify(key.get_fingerprint())
        self.assertEqual(exp_dss, my_dss)
        self.assertEqual(PUB_DSS.split()[1], key.get_base64())
        self.assertEqual(1024, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(DSS_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = DSSKey.from_private_key(s)
        self.assertEqual(key, key2)
예제 #38
0
    def connect(self):

        try:

            # Build a public key object from the server (agent) key file
            if self.publicKeyType == 'rsa':
                agent_public_key = RSAKey(
                    data=base64.decodestring(self.publicKey))
            elif self.publicKeyType == 'dss':
                agent_public_key = DSSKey(
                    data=base64.decodestring(self.publicKey))

            # Build a private key object from the manager key file, and connect to the agent:
            if self.privateKeyFile != None:
                # Using client (manager) private key to authenticate
                if self.privateKeyType == "rsa":
                    user_private_key = RSAKey.from_private_key_file(
                        self.privateKeyFile)
                elif self.privateKeyType == "dss":
                    user_private_key = DSSKey.from_private_key_file(
                        self.privateKeyFile)
                self.ssh.connect(hostkey=agent_public_key,
                                 username=self.username,
                                 pkey=user_private_key)
            else:
                # Using client (manager) password to authenticate
                self.ssh.connect(hostkey=agent_public_key,
                                 username=self.username,
                                 password=self.password)

            # Request a new channel to the server, of type "session".
            self.chan = self.ssh.open_session()

            # Request a "netconf" subsystem on the server:
            self.chan.invoke_subsystem(C.NETCONF_SSH_SUBSYSTEM)

        except Exception, exp:
            syslog.openlog("YencaP Manager")
            syslog.syslog(syslog.LOG_ERR, str(exp))
            syslog.closelog()
            return C.FAILED
예제 #39
0
 def test_8_multipart_auth(self):
     """
     verify that multipart auth works.
     """
     host_key = RSAKey.from_private_key_file('tests/test_rsa.key')
     public_host_key = RSAKey(data=str(host_key))
     self.ts.add_server_key(host_key)
     event = threading.Event()
     server = NullServer()
     self.assert_(not event.isSet())
     self.ts.start_server(event, server)
     self.tc.ultra_debug = True
     self.tc.connect(hostkey=public_host_key)
     remain = self.tc.auth_password(username='******', password='******')
     self.assertEquals(['publickey'], remain)
     key = DSSKey.from_private_key_file('tests/test_dss.key')
     remain = self.tc.auth_publickey(username='******', key=key)
     self.assertEquals([], remain)
     event.wait(1.0)
     self.assert_(event.isSet())
     self.assert_(self.ts.is_active())
예제 #40
0
 def test_8_multipart_auth(self):
     """
     verify that multipart auth works.
     """
     host_key = RSAKey.from_private_key_file('tests/test_rsa.key')
     public_host_key = RSAKey(data=str(host_key))
     self.ts.add_server_key(host_key)
     event = threading.Event()
     server = NullServer()
     self.assert_(not event.isSet())
     self.ts.start_server(event, server)
     self.tc.ultra_debug = True
     self.tc.connect(hostkey=public_host_key)
     remain = self.tc.auth_password(username='******',
                                    password='******')
     self.assertEquals(['publickey'], remain)
     key = DSSKey.from_private_key_file('tests/test_dss.key')
     remain = self.tc.auth_publickey(username='******', key=key)
     self.assertEquals([], remain)
     event.wait(1.0)
     self.assert_(event.isSet())
     self.assert_(self.ts.is_active())
예제 #41
0
    def __init__(self, \
                 timeout, \
                 remoteMachine, \
                 port, \
                 username, \
                 password, \
                 loggerName, \
                 pk, \
                 bufsize = 8192):
                 

        import logging
        self.logger = logging.getLogger(loggerName)
        
        self.timeout = timeout
        self.remoteMachine = remoteMachine
        self.port = port
        self.username = username
        self.password = password
        self.bufsize = bufsize
        self.pk = DSSKey.from_private_key_file(expanduser(pk))
        self.logger.info('Object succesfully created')
        self.logger.debug ('timeout = %s, remoteMachine = %s, port = %s, username = %s'%(self.timeout, self.remoteMachine, self.port, self.username))
예제 #42
0
    def connect(self, wait_prompt=True):
        self.socket = socket(AF_INET, SOCK_STREAM)
        self.socket.connect((self.hostname, self.port))
        self.session = Transport(self.socket)
        self.session.start_client()
        if self.password is not None:
            self.session.auth_password(self.username, self.password)
        elif self.key_algorithm != DSA_KEY_ALGORITHM:
            key = RSAKey.from_private_key_file(
                self.private_key_file, self.key_passphrase
            )
            self.session.auth_publickey(self.username, key)
        else:
            key = DSSKey.from_private_key_file(
                self.private_key_file, self.key_passphrase
            )
            self.session.auth_publickey(self.username, key)

        self.channel = self.session.open_session()
        self.channel.get_pty()
        self.channel.invoke_shell()
        if wait_prompt:
            self.receive()
예제 #43
0
    def submitJobToFramework(self, **kwargs):
        jobCommand = 'job'
        
        daemonArgs = DaemonArgs(self.config)
        daemonArgs.command = jobCommand
        unScheduledJob = kwargs['unScheduledJob']
        
        is_fileFeeder = False
        fileFeederUploadedFile = None
        del daemonArgs.param[:]

        # go through all parameters
        for parameter in unScheduledJob.parameters.all():

            # add parameter to daemonArgs.param
            if parameter.service and parameter.param_key and parameter.param_value:

                # check if a file feeder is used
                if parameter.service == settings.FILE_FEEDER_ID:
                    is_fileFeeder = True
                    fileFeederUploadedFile = parameter.param_value

                    remoteFeederFile = os.path.join(self.sftpRemotePath, parameter.param_value)
                    parameterString = '%s.%s=%s' % ( parameter.service, parameter.param_key, remoteFeederFile )
                else:
                    parameterString = '%s.%s=%s' % ( parameter.service, parameter.param_key, parameter.param_value )

                self.logger.debug("add parameter string: %s" % parameterString)
                daemonArgs.param.append([parameterString])

        # in case of a filefeeder upload file to framework server
        if is_fileFeeder:
            self.logger.debug("is file feeder")
            sftp = None
            transport = None
            try:
                transport = Transport((self.sftpHost, self.sftpPort))
                if self.sftpPassword:
                    transport.connect(username=self.sftpUsername, password=self.sftpPassword)
                else:
                    privateKey = None
                    if self.sftpPrivateKeyType and self.sftpPrivateKeyType.lower() == 'rsa':
                        privateKey = RSAKey.from_private_key_file(self.sftpPrivateKey, password=self.sftpPrivateKeyPassword )
                    if self.sftpPrivateKeyType and self.sftpPrivateKeyType.lower() == 'dss':
                        privateKey = DSSKey.from_private_key_file(self.sftpPrivateKey, password=self.sftpPrivateKeyPassword )

                    transport.connect(username=self.sftpUsername, pkey=privateKey)

                sftp = SFTPClient.from_transport(transport)

                filePath = os.path.join( settings.MEDIA_ROOT, fileFeederUploadedFile )
                remotePath = os.path.join( self.sftpRemotePath, fileFeederUploadedFile )

                self.logger.debug("uploading file from %s to %s on remote machine" % (filePath, remotePath))

                sftp.put(filePath, remotePath)
#                            sftp.put(filePath, remotePath, confirm=False)
                sftp.chmod( remotePath, 0644 )

                self.logger.debug("put OK")

            except IOError as e:
                self.logger.error("IOError: %s. Will continue with next scheduled job." % e)
                self.saveJob(Job.FAILED_STATUS, None, unScheduledJob)
            except PasswordRequiredException as e:
                self.logger.error("PasswordRequiredException: %s. Will continue with next scheduled job." % e)
                self.saveJob(Job.FAILED_STATUS, None, unScheduledJob)
            except SSHException as e:
                self.logger.error("SSH Exception: %s. Will continue with next scheduled job." % e)
                self.saveJob(Job.FAILED_STATUS, None, unScheduledJob)
            except Exception as e:
                self.logger.error("Unkown SFTP problem. Will continue with next scheduled job. %s" % e)
                self.saveJob(Job.FAILED_STATUS, None, unScheduledJob)
            finally:
                if sftp is not None:
                    sftp.close()
                if transport is not None:
                    transport.close()
                
        # set job workflow
        daemonArgs.jd_workflow = unScheduledJob.workflow.name

        frameworkJobId = None
        
        try:
            setattr(daemonArgs, jobCommand, 'submit')
            frameworkJobId = self.sendFrameworkCommand(jobCommand, daemonArgs)
            self.saveJob(Job.PROCESSING_STATUS, frameworkJobId, unScheduledJob)
        except WorkflowNotDeployedException:
            # The workflow is not deployed in the framework. To prevent the scheduler retrying continuously
            # we disable this job
            unScheduledJob.status = Schedule.DEACTIVATE_STATUS
            unScheduledJob.save()
        except:
            self.saveJob(Job.FAILED_STATUS, None, unScheduledJob)
        finally:
            daemonArgs.clean(jobCommand)
        
        if unScheduledJob.scheduled_start is not None:
            unScheduledJob.status = Schedule.DEACTIVATED_STATUS
            unScheduledJob.save()
예제 #44
0
파일: ssh-sign.py 프로젝트: unhaltable/txti
	def __init__(self, args):
		self.knownfile = ''
		self.keytype = ''
		self.pubfile = ''
		self.privfile = ''
		self.signfile = ''
		self.blob = ''
		self.host = ''
		self.hhost = ''
		self.privkey = ''
		self.pubkey = ''
		self.signkey = ''
		self.knownkey = ''

		if 'known' in args:
			self.knownfile = args['known']
		if 'pub' in args:
			self.pubfile = args['pub']
		if 'priv' in args:
			self.privfile = args['priv']
		if 'sign' in args:
			self.signfile = args['sign']
		if 'host' in args:
			self.host = args['host']
		if 'blob' in args:
			self.blob = args['blob']

		# for decryption
		if self.privfile != '':
			rsakey = ''
			try:
				f = open(self.privfile, 'r')
				for line in f:
					rsakey += line
			except:
				error('No private key file found.')
			f.close()
			try:
				self.privkey = RSA.importKey(rsakey)
			except:
				error('No valid private RSA key found.')

		# to sign files
		if self.signfile != '':
			try:
				f = open(self.signfile, 'r')
				line = f.readline()
				f.close()
				if line.find('RSA') != -1 or line.find('rsa') != -1:
					self.signkey = RSAKey.from_private_key_file(self.signfile)
				else:
					self.signkey = DSSKey.from_private_key_file(self.signfile)
			except:
				error('No valid signature key found.')

		# to encrypt files
		if self.pubfile != '':
			try:
				s = subprocess.check_output(['ssh-keygen', '-e', '-m', 'PKCS8', '-f',
				                            self.pubfile], shell = False)
				self.pubkey = RSA.importKey(s)
			except:
				error('No valid public RSA key found.')
예제 #45
0
 def test_load_dss_password(self):
     key = DSSKey.from_private_key_file(_support('test_dss_password.key'),
                                        'television')
     self.assert_key_values(key, 'ssh-dss', 1024, PUB_DSS,
                            FINGER_DSS.split()[1], FINGER_SHA256_DSS)
예제 #46
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        """First checks if the keypair is valid, then checks if the keypair
        is registered with on the cloud. If not the keypair is added to the
        users ssh keys.

        :param str name: name of the ssh key
        :param str public_key_path: path to the ssh public key file
        :param str private_key_path: path to the ssh private key file

        :raises: `KeypairError` if key is not a valid RSA or DSA key,
                 the key could not be uploaded or the fingerprint does not
                 match to the one uploaded to the cloud.
        """
        connection = self._connect()
        keypairs = connection.get_all_key_pairs()
        keypairs = dict((k.name, k) for k in keypairs)

        # decide if dsa or rsa key is provided
        pkey = None
        is_dsa_key = False
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
            is_dsa_key = True
        except PasswordRequiredException:
            warn(
                "Unable to check key file `{0}` because it is encrypted with a "
                "password. Please, ensure that you added it to the SSH agent "
                "with `ssh-add {1}`".format(private_key_path,
                                            private_key_path))
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                warn(
                    "Unable to check key file `{0}` because it is encrypted with a "
                    "password. Please, ensure that you added it to the SSH agent "
                    "with `ssh-add {1}`".format(private_key_path,
                                                private_key_path))
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        # create keys that don't exist yet
        if name not in keypairs:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._url)
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    # check for DSA on amazon
                    if "amazon" in self._ec2host and is_dsa_key:
                        log.error(
                            "Apparently, amazon does not support DSA keys. "
                            "Please specify a valid RSA key.")
                        raise KeypairError(
                            "Apparently, amazon does not support DSA keys."
                            "Please specify a valid RSA key.")

                    connection.import_key_pair(name, key_material)
                except Exception as ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._url)
                    raise KeypairError("could not create keypair `%s`: %s" %
                                       (name, ex))
        else:
            # check fingerprint
            cloud_keypair = keypairs[name]

            if pkey:
                fingerprint = str.join(':', (i.encode('hex')
                                             for i in pkey.get_fingerprint()))

                if fingerprint != cloud_keypair.fingerprint:
                    if "amazon" in self._ec2host:
                        log.error(
                            "Apparently, Amazon does not compute the RSA key "
                            "fingerprint as we do! We cannot check if the "
                            "uploaded keypair is correct!")
                    else:
                        raise KeypairError("Keypair `%s` is present but has "
                                           "different fingerprint. Aborting!" %
                                           name)
예제 #47
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        """First checks if the keypair is valid, then checks if the keypair
        is registered with on the cloud. If not the keypair is added to the
        users ssh keys.

        :param str name: name of the ssh key
        :param str public_key_path: path to the ssh public key file
        :param str private_key_path: path to the ssh private key file

        :raises: `KeypairError` if key is not a valid RSA or DSA key,
                 the key could not be uploaded or the fingerprint does not
                 match to the one uploaded to the cloud.
        """

        # Read key. We do it as first thing because we need it either
        # way, to check the fingerprint of the remote keypair if it
        # exists already, or to create a new keypair.
        pkey = None
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
        except PasswordRequiredException:
            warn("Unable to check key file `{0}` because it is encrypted with a "
                 "password. Please, ensure that you added it to the SSH agent "
                 "with `ssh-add {1}`"
                 .format(private_key_path, private_key_path))
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                warn("Unable to check key file `{0}` because it is encrypted with a "
                     "password. Please, ensure that you added it to the SSH agent "
                     "with `ssh-add {1}`"
                     .format(private_key_path, private_key_path))
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        try:
            # Check if a keypair `name` exists on the cloud.
            keypair = self.nova_client.keypairs.get(name)

            # Check if it has the correct keypair, but only if we can read the local key
            if pkey:
                fingerprint = str.join(
                    ':', (i.encode('hex') for i in pkey.get_fingerprint()))
                if fingerprint != keypair.fingerprint:
                    raise KeypairError(
                        "Keypair `%s` is present but has "
                        "different fingerprint. Aborting!" % name)
            else:
                warn("Unable to check if the keypair is using the correct key.")
        except NotFound:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._os_auth_url)

            # Create a new keypair
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    self.nova_client.keypairs.create(name, key_material)
                except Exception as ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._os_auth_url)
                    raise KeypairError(
                        "could not create keypair `%s`: %s" % (name, ex))
예제 #48
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        """First checks if the keypair is valid, then checks if the keypair
        is registered with on the cloud. If not the keypair is added to the
        users ssh keys.

        :param str name: name of the ssh key
        :param str public_key_path: path to the ssh public key file
        :param str private_key_path: path to the ssh private key file

        :raises: `KeypairError` if key is not a valid RSA or DSA key,
                 the key could not be uploaded or the fingerprint does not
                 match to the one uploaded to the cloud.
        """
        self._init_os_api()
        # Read key. We do it as first thing because we need it either
        # way, to check the fingerprint of the remote keypair if it
        # exists already, or to create a new keypair.
        pkey = None
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
        except PasswordRequiredException:
            warn(
                "Unable to check key file `{0}` because it is encrypted with a "
                "password. Please, ensure that you added it to the SSH agent "
                "with `ssh-add {1}`".format(private_key_path,
                                            private_key_path))
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                warn(
                    "Unable to check key file `{0}` because it is encrypted with a "
                    "password. Please, ensure that you added it to the SSH agent "
                    "with `ssh-add {1}`".format(private_key_path,
                                                private_key_path))
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        try:
            # Check if a keypair `name` exists on the cloud.
            keypair = self.nova_client.keypairs.get(name)

            # Check if it has the correct keypair, but only if we can read the local key
            if pkey:
                fingerprint = str.join(':', (i.encode('hex')
                                             for i in pkey.get_fingerprint()))
                if fingerprint != keypair.fingerprint:
                    raise KeypairError("Keypair `%s` is present but has "
                                       "different fingerprint. Aborting!" %
                                       name)
            else:
                warn(
                    "Unable to check if the keypair is using the correct key.")
        except NotFound:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._os_auth_url)

            # Create a new keypair
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    self.nova_client.keypairs.create(name, key_material)
                except Exception as ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._os_auth_url)
                    raise KeypairError("could not create keypair `%s`: %s" %
                                       (name, ex))
예제 #49
0
 def test_load_DSS_key_new_format(self):
     key = DSSKey.from_private_key_file(_support('test_dss_1k_o.key'),
                                        b'television')
     self.assert_key_values(key, 'ssh-dss', 1024, PUB_DSS_1K_OPENSSH,
                            FINGER_DSS_1K_OPENSSH.split()[1],
                            FINGER_SHA256_DSS_1K_OPENSSH)
예제 #50
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        """First checks if the keypair is valid, then checks if the keypair
        is registered with on the cloud. If not the keypair is added to the
        users ssh keys.

        :param str name: name of the ssh key
        :param str public_key_path: path to the ssh public key file
        :param str private_key_path: path to the ssh private key file

        :raises: `KeypairError` if key is not a valid RSA or DSA key,
                 the key could not be uploaded or the fingerprint does not
                 match to the one uploaded to the cloud.
        """
        connection = self._connect()
        keypairs = connection.get_all_key_pairs()
        keypairs = dict((k.name, k) for k in keypairs)

        # decide if dsa or rsa key is provided
        pkey = None
        is_dsa_key = False
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
            is_dsa_key = True
        except PasswordRequiredException:
            log.warning(
                "Unable to check key file `%s` because it is encrypted with a "
                "password. Please, ensure that you added it to the SSH agent "
                "with `ssh-add %s`", private_key_path, private_key_path)
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                log.warning(
                    "Unable to check key file `%s` because it is encrypted with a "
                    "password. Please, ensure that you added it to the SSH agent "
                    "with `ssh-add %s`", private_key_path, private_key_path)
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        # create keys that don't exist yet
        if name not in keypairs:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._url)
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    # check for DSA on amazon
                    if "amazon" in self._ec2host and is_dsa_key:
                        log.error(
                            "Apparently, amazon does not support DSA keys. "
                            "Please specify a valid RSA key.")
                        raise KeypairError(
                            "Apparently, amazon does not support DSA keys."
                            "Please specify a valid RSA key.")

                    connection.import_key_pair(name, key_material)
                except Exception, ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._url)
                    raise KeypairError(
                        "could not create keypair `%s`: %s" % (name, ex))
예제 #51
0
    def _check_keypair(self, name, public_key_path, private_key_path):
        """First checks if the keypair is valid, then checks if the keypair
        is registered with on the cloud. If not the keypair is added to the
        users ssh keys.

        :param str name: name of the ssh key
        :param str public_key_path: path to the ssh public key file
        :param str private_key_path: path to the ssh private key file

        :raises: `KeypairError` if key is not a valid RSA or DSA key,
                 the key could not be uploaded or the fingerprint does not
                 match to the one uploaded to the cloud.
        """
        connection = self._connect()
        keypairs = connection.get_all_key_pairs()
        keypairs = dict((k.name, k) for k in keypairs)

        # decide if dsa or rsa key is provided
        pkey = None
        is_dsa_key = False
        try:
            pkey = DSSKey.from_private_key_file(private_key_path)
            is_dsa_key = True
        except PasswordRequiredException:
            warn("Unable to check key file `{0}` because it is encrypted with a "
                 "password. Please, ensure that you added it to the SSH agent "
                 "with `ssh-add {1}`"
                 .format(private_key_path, private_key_path))
        except SSHException:
            try:
                pkey = RSAKey.from_private_key_file(private_key_path)
            except PasswordRequiredException:
                warn("Unable to check key file `{0}` because it is encrypted with a "
                     "password. Please, ensure that you added it to the SSH agent "
                     "with `ssh-add {1}`"
                     .format(private_key_path, private_key_path))
            except SSHException:
                raise KeypairError('File `%s` is neither a valid DSA key '
                                   'or RSA key.' % private_key_path)

        # create keys that don't exist yet
        if name not in keypairs:
            log.warning(
                "Keypair `%s` not found on resource `%s`, Creating a new one",
                name, self._url)
            with open(os.path.expanduser(public_key_path)) as f:
                key_material = f.read()
                try:
                    # check for DSA on amazon
                    if "amazon" in self._ec2host and is_dsa_key:
                        log.error(
                            "Apparently, amazon does not support DSA keys. "
                            "Please specify a valid RSA key.")
                        raise KeypairError(
                            "Apparently, amazon does not support DSA keys."
                            "Please specify a valid RSA key.")

                    connection.import_key_pair(name, key_material)
                except Exception as ex:
                    log.error(
                        "Could not import key `%s` with name `%s` to `%s`",
                        name, public_key_path, self._url)
                    raise KeypairError(
                        "could not create keypair `%s`: %s" % (name, ex))
        else:
            # check fingerprint
            cloud_keypair = keypairs[name]

            if pkey:
                if "amazon" in self._ec2host:
                    # AWS takes the MD5 hash of the key's DER representation.
                    key = RSA.importKey(open(private_key_path).read())
                    der = key.publickey().exportKey('DER')

                    m = hashlib.md5()
                    m.update(der)
                    digest = m.hexdigest()
                    fingerprint = ':'.join(digest[i:(i + 2)]
                                           for i in range(0, len(digest), 2))
                else:
                    fingerprint = ':'.join(byte_to_hex(byte)
                                           for byte in pkey.get_fingerprint())


                if fingerprint != cloud_keypair.fingerprint:
                    if "amazon" in self._ec2host:
                        log.error(
                            "Apparently, Amazon does not compute the RSA key "
                            "fingerprint as we do! We cannot check if the "
                            "uploaded keypair is correct!")
                    else:
                        raise KeypairError(
                            "Keypair `%s` is present but has "
                            "different fingerprint. Aborting!" % name)