def connect(self, host=None, username=None, password=None, private_key=None, private_key_pass=None, port=None, timeout=30, compress=None): host = host or self._host username = username or self._username password = password or self._password compress = compress or self._compress port = port if port is not None else self._port pkey = self._pkey if private_key: pkey = self.load_private_key(private_key, private_key_pass) log.debug("connecting to host %s on port %d as user %s" % (host, port, username)) try: sock = self._get_socket(host, port) transport = paramiko.Transport(sock) transport.banner_timeout = timeout except socket.error: raise exception.SSHConnectionError(host, port) # Enable/disable compression transport.use_compression(compress) # Authenticate the transport. try: transport.connect(username=username, pkey=pkey, password=password) except paramiko.AuthenticationException: raise exception.SSHAuthException(username, host) except paramiko.SSHException, e: msg = e.args[0] raise exception.SSHError(msg)
def connect(self, host=None, username=None, password=None, private_key=None, private_key_pass=None, port=22, timeout=30): host = host or self._host username = username or self._username password = password or self._password pkey = self._pkey if private_key: pkey = self.load_private_key(private_key, private_key_pass) log.debug("connecting to host %s on port %d as user %s" % (host, port, username)) try: sock = self._get_socket(host, port) transport = ssh.Transport(sock) transport.banner_timeout = timeout except socket.error: raise exception.SSHConnectionError(host, port) # Authenticate the transport. try: transport.connect(username=username, pkey=pkey, password=password) except ssh.AuthenticationException: raise exception.SSHAuthException(username, host) except ssh.SSHException, e: msg = e.args[0] raise exception.SSHError(msg)
def get_public_rsa_fingerprint(pubkey_location): try: k = RSAKey.from_private_key_file(pubkey_location) except paramiko.SSHException: raise exception.SSHError("Invalid RSA private key file: %s" % pubkey_location) md5digest = hashlib.md5(str(k)).hexdigest() return insert_char_every_n_chars(md5digest, ':', 2)
def execute(self, command, silent=True, only_printable=False, ignore_exit_status=False, log_output=True, detach=False, source_profile=False, raise_on_failure=False): """ Execute a remote command and return stdout/stderr NOTE: this function blocks until the process finishes kwargs: silent - do not log output to console only_printable - filter the command's output to allow only printable characters ignore_exit_status - don't warn about non-zero exit status log_output - log output to debug file detach - detach the remote process so that it continues to run even after the SSH connection closes (does NOT return output or check for non-zero exit status if detach=True) source_profile - if True prefix the command with "source /etc/profile" raise_on_failure - raise exception.SSHError if command fails returns List of output lines """ channel = self.transport.open_session() if detach: command = "nohup %s &" % command if source_profile: command = "source /etc/profile && %s" % command channel.exec_command(command) channel.close() self.__last_status = None return if source_profile: command = "source /etc/profile && %s" % command channel.exec_command(command) output = self._get_output(channel, silent=silent, only_printable=only_printable) exit_status = channel.recv_exit_status() self.__last_status = exit_status if exit_status != 0: msg = "command '%s' failed with status %d" % (command, exit_status) if not ignore_exit_status: log.error(msg) else: log.debug(msg) if log_output: for line in output: log.debug(line.strip()) if exit_status != 0 and raise_on_failure: raise exception.SSHError(msg) return output
def get_dsa_key(key_location=None, key_file_obj=None, passphrase=None, use_pycrypto=False): key_fobj = key_file_obj or open(key_location) try: key = paramiko.DSSKey.from_private_key(key_fobj, password=passphrase) if use_pycrypto: key = DSA.construct((key.y, key.g, key.p, key.q, key.x)) return key except (paramiko.SSHException, ValueError): raise exception.SSHError( "Invalid DSA private key file or missing passphrase: %s" % key_location)
def _get_socket(self, hostname, port): for (family, socktype, proto, canonname, sockaddr) in \ socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM): if socktype == socket.SOCK_STREAM: af = family break else: raise exception.SSHError('No suitable address family for %s' % hostname) sock = socket.socket(af, socket.SOCK_STREAM) sock.settimeout(self._timeout) sock.connect((hostname, port)) return sock
def __init__(self, host, username=None, password=None, private_key=None, private_key_pass=None, port=22, timeout=30): self._timeout = timeout self._sftp_live = False self._sftp = None self._pkey = None if not username: username = os.environ['LOGNAME'] # Begin the SSH transport. self._transport_live = False try: sock = self._get_socket(host, port) self._transport = paramiko.Transport(sock) self._transport.banner_timeout = self._timeout except socket.error: raise exception.SSHConnectionError(host, port) self._transport_live = True # Authenticate the transport. pkey = None if private_key: # Use Private Key. log.debug('private key specified') if private_key.endswith('rsa') or private_key.count('rsa'): pkey = self._load_rsa_key(private_key, private_key_pass) elif private_key.endswith('dsa') or private_key.count('dsa'): pkey = self._load_dsa_key(private_key, private_key_pass) else: log.debug("specified key does not end in either rsa or dsa" + \ ", trying both") pkey = self._load_rsa_key(private_key, private_key_pass) if pkey is None: pkey = self._load_dsa_key(private_key, private_key_pass) self._pkey = pkey elif not password: raise exception.SSHNoCredentialsError() try: self._transport.connect(username=username, pkey=pkey, password=password) except paramiko.AuthenticationException: raise exception.SSHAuthException(username, host) except paramiko.SSHException, e: msg = e.args[0] raise exception.SSHError(msg)
def get_rsa_key(key_location=None, key_file_obj=None, passphrase=None, use_pycrypto=False): key_fobj = key_file_obj or open(key_location) try: if use_pycrypto: key = RSA.importKey(key_fobj, passphrase=passphrase) else: key = paramiko.RSAKey.from_private_key(key_fobj, password=passphrase) return key except (paramiko.SSHException, ValueError): raise exception.SSHError( "Invalid RSA private key file or missing passphrase: %s" % key_location)
def get_private_rsa_fingerprint(key_location): """ Returns the fingerprint of a private RSA key as a 59-character string (40 characters separated every 2 characters by a ':'). The fingerprint is computed using a SHA1 digest of the DER encoded RSA private key. """ try: k = RSAKey.from_private_key_file(key_location) except paramiko.SSHException: raise exception.SSHError("Invalid RSA private key file: %s" % key_location) params = dict(invq=util.mod_inverse(k.q, k.p), dp=k.d % (k.p - 1), dq=k.d % (k.q - 1), d=k.d, n=k.n, p=k.p, q=k.q, e=k.e) assert len(params) == 8 # must convert from pkcs1 to pkcs8 and then DER encode pkcs8der = export_rsa_to_pkcs8(params) sha1digest = hashlib.sha1(pkcs8der).hexdigest() return insert_char_every_n_chars(sha1digest, ':', 2)
raise exception.SSHNoCredentialsError() try: self._transport.connect(username=username, pkey=pkey, password=password) except paramiko.AuthenticationException: raise exception.SSHAuthException(username, host) except paramiko.SSHException, e: msg = e.args[0] raise exception.SSHError(msg) except socket.error: raise exception.SSHConnectionError(host, port) except EOFError: raise exception.SSHConnectionError(host, port) except Exception, e: raise exception.SSHError(str(e)) def _get_socket(self, hostname, port): for (family, socktype, proto, canonname, sockaddr) in \ socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM): if socktype == socket.SOCK_STREAM: af = family break else: raise exception.SSHError('No suitable address family for %s' % hostname) sock = socket.socket(af, socket.SOCK_STREAM) sock.settimeout(self._timeout) sock.connect((hostname, port)) return sock