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
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)
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)
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())
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
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
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()
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)
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())
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)
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())
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())
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)
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)
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())
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
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)
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)
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()
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
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()
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))
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))
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 == []
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)
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))
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()
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))
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()
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))
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))
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)
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)
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)
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
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())
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))
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()
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()
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.')
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)
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)
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))
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))
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)
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))
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)