class RepoWriteLock: def __init__(self, url): self.url = url self.transport = None self.client = None self.socket = socket() def __enter__(self): self.socket.connect((interpret_urlish(self.url)[1], 22)) self.transport = Transport(self.socket) self.transport.start_client() authenticate_transport(self.transport) self.client = self.transport.open_sftp_client() self.client.chdir(interpret_urlish(self.url)[2]) self._lock() def _lock(self): target_locks = self.client.listdir("locks") target_locks.sort() if target_locks: raise RuntimeError("repo is locked; try again later") else: self.client.mkdir("locks/write_lock") def _unlock(self): self.client.rmdir("locks/write_lock") def __exit__(self, *args): self._unlock() self.client.close() self.transport.close() self.socket.close()
def check_ssh_up(host, port): """ Return True if SSH connectivity exists. First checks if port is open, then tries to see if it response to SSH connectivity. """ try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(2) try: s.connect((host, port)) except socket.error as e: if e.errno in (61,): return False else: raise else: # Basic connectivity works, try SSH t = Transport(s) # Shut up paramiko logging plog = logging.getLogger('paramiko.transport') plog.disabled = True try: t.start_client() return True except paramiko.SSHException as e: return False finally: t.close() s.close() plog.disabled = False except Exception as e: raise SshError('Error while checking %s:%d for SSH: %s' % (host, port, e))
def authenticate_sftp_user(user_name, password, otc, hostname, port): def sftp_auth_handler(title, instructions, prompt_list): if len(prompt_list) == 0: return [] if 'Password' in prompt_list[0][0]: return [password] else: return [otc] transport = Transport((hostname, int(port))) if otc != '': transport.start_client() transport.auth_interactive(user_name, sftp_auth_handler) else: transport.connect(None, user_name, password) return transport
def get_host_key(host, port=22): logger.debug("Connecting to host %s to get ssh public host key" % host) INTERVAL = 15 MAX_RETRY = 60 / INTERVAL * 5 c = 0 while 1: try: sock = create_connection((host, port)) transport = Transport(sock) transport.start_client() key = transport.get_remote_server_key() transport.close() break except error, e: if type(e) is timeout: log = logger.warn else: log = logger.error log('socket %s: errno=%r, error msg=%s for server %s' % (e.__class__.__name__, e.errno, e.strerror, host)) except SSHException, e: logger.exception("attempt %s - error while attempting to connect to %s" % (c, host))
def get_host_keys(address, port=22, types=None): if types is None: types = Transport._preferred_keys af, sock_type, proto, name, addr = socket.getaddrinfo( address, port, 0,0, socket.IPPROTO_TCP)[0] keys = [] for key_type in types: try: sock = socket.socket(af, sock_type, proto) sock.connect(addr) t = Transport(sock) t.get_security_options().key_types = [key_type] t.start_client() keys.append(t.get_remote_server_key()) except Exception: pass finally: t.close() sock.close() return keys
def checkUsername(self, username, tried=0): sock = socket.socket() sock.connect((self.hostname, self.port)) # instantiate transport transport = Transport(sock) try: transport.start_client() except paramiko.ssh_exception.SSHException: # server was likely flooded, retry up to 3 times transport.close() if tried < 4: tried += 1 return self.checkUsername(username, tried) else: print("[-] Failed to negotiate SSH transport") try: transport.auth_publickey(username, paramiko.RSAKey.generate(1024)) except BadUsername: return (username, False) except paramiko.ssh_exception.AuthenticationException: return (username, True) #Successful auth(?) raise Exception( "There was an error. Is this the correct version of OpenSSH?")
def ssh_paramiko_connect_to(display_desc): #plain socket attributes: dtype = display_desc["type"] host = display_desc["host"] port = display_desc.get("ssh-port", 22) #ssh and command attributes: username = display_desc.get("username") or get_username() if "proxy_host" in display_desc: display_desc.setdefault("proxy_username", get_username()) password = display_desc.get("password") remote_xpra = display_desc["remote_xpra"] proxy_command = display_desc["proxy_command"] #ie: "_proxy_start" socket_dir = display_desc.get("socket_dir") display = display_desc.get("display") display_as_args = display_desc["display_as_args"] #ie: "--start=xterm :10" paramiko_config = display_desc.copy() paramiko_config.update(display_desc.get("paramiko-config", {})) socket_info = { "host" : host, "port" : port, } def get_keyfiles(host_config, config_name="key"): keyfiles = (host_config or {}).get("identityfile") or get_default_keyfiles() keyfile = paramiko_config.get(config_name) if keyfile: keyfiles.insert(0, keyfile) return keyfiles with nogssapi_context(): from paramiko import SSHConfig, ProxyCommand ssh_config = SSHConfig() user_config_file = os.path.expanduser("~/.ssh/config") sock = None host_config = None if os.path.exists(user_config_file): with open(user_config_file) as f: ssh_config.parse(f) log("parsed user config '%s': %i hosts found", user_config_file, len(ssh_config.get_hostnames())) host_config = ssh_config.lookup(host) if host_config: log("got host config for '%s': %s", host, host_config) chost = host_config.get("hostname", host) cusername = host_config.get("user", username) cport = host_config.get("port", port) try: port = int(cport) except (TypeError, ValueError): raise InitExit(EXIT_SSH_FAILURE, "invalid ssh port specified: '%s'" % cport) from None proxycommand = host_config.get("proxycommand") if proxycommand: log("found proxycommand='%s' for host '%s'", proxycommand, chost) sock = ProxyCommand(proxycommand) log("ProxyCommand(%s)=%s", proxycommand, sock) from xpra.child_reaper import getChildReaper cmd = getattr(sock, "cmd", []) def proxycommand_ended(proc): log("proxycommand_ended(%s) exit code=%s", proc, proc.poll()) getChildReaper().add_process(sock.process, "paramiko-ssh-client", cmd, True, True, callback=proxycommand_ended) proxy_keys = get_keyfiles(host_config, "proxy_key") log("proxy keys=%s", proxy_keys) from paramiko.client import SSHClient ssh_client = SSHClient() ssh_client.load_system_host_keys() log("ssh proxy command connect to %s", (chost, cport, sock)) ssh_client.connect(chost, cport, sock=sock) transport = ssh_client.get_transport() do_ssh_paramiko_connect_to(transport, chost, cusername, password, host_config or ssh_config.lookup("*"), proxy_keys, paramiko_config) chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args) peername = (chost, cport) conn = SSHProxyCommandConnection(chan, peername, peername, socket_info) conn.target = host_target_string("ssh", cusername, chost, port, display) conn.timeout = SOCKET_TIMEOUT conn.start_stderr_reader() conn.process = (sock.process, "ssh", cmd) from xpra.net import bytestreams from paramiko.ssh_exception import ProxyCommandFailure bytestreams.CLOSED_EXCEPTIONS = tuple(list(bytestreams.CLOSED_EXCEPTIONS)+[ProxyCommandFailure]) return conn keys = get_keyfiles(host_config) from xpra.scripts.main import socket_connect from paramiko.transport import Transport from paramiko import SSHException if "proxy_host" in display_desc: proxy_host = display_desc["proxy_host"] proxy_port = display_desc.get("proxy_port", 22) proxy_username = display_desc.get("proxy_username", username) proxy_password = display_desc.get("proxy_password", password) proxy_keys = get_keyfiles(host_config, "proxy_key") sock = socket_connect(dtype, proxy_host, proxy_port) middle_transport = Transport(sock) middle_transport.use_compression(False) try: middle_transport.start_client() except SSHException as e: log("start_client()", exc_info=True) raise InitExit(EXIT_SSH_FAILURE, "SSH negotiation failed: %s" % e) from None proxy_host_config = ssh_config.lookup(host) do_ssh_paramiko_connect_to(middle_transport, proxy_host, proxy_username, proxy_password, proxy_host_config or ssh_config.lookup("*"), proxy_keys, paramiko_config) log("Opening proxy channel") chan_to_middle = middle_transport.open_channel("direct-tcpip", (host, port), ('localhost', 0)) transport = Transport(chan_to_middle) transport.use_compression(False) try: transport.start_client() except SSHException as e: log("start_client()", exc_info=True) raise InitExit(EXIT_SSH_FAILURE, "SSH negotiation failed: %s" % e) do_ssh_paramiko_connect_to(transport, host, username, password, host_config or ssh_config.lookup("*"), keys, paramiko_config) chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args) peername = (host, port) conn = SSHProxyCommandConnection(chan, peername, peername, socket_info) conn.target = "%s via %s" % ( host_target_string("ssh", username, host, port, display), host_target_string("ssh", proxy_username, proxy_host, proxy_port, None), ) conn.timeout = SOCKET_TIMEOUT conn.start_stderr_reader() return conn #plain TCP connection to the server, #we open it then give the socket to paramiko: sock = socket_connect(dtype, host, port) sockname = sock.getsockname() peername = sock.getpeername() log("paramiko socket_connect: sockname=%s, peername=%s", sockname, peername) transport = Transport(sock) transport.use_compression(False) try: transport.start_client() except SSHException as e: log("start_client()", exc_info=True) raise InitExit(EXIT_SSH_FAILURE, "SSH negotiation failed: %s" % e) from None do_ssh_paramiko_connect_to(transport, host, username, password, host_config or ssh_config.lookup("*"), keys, paramiko_config) chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args) conn = SSHSocketConnection(chan, sock, sockname, peername, (host, port), socket_info) conn.target = host_target_string("ssh", username, host, port, display) conn.timeout = SOCKET_TIMEOUT conn.start_stderr_reader() return conn
class Repository: def __init__(self, url): self.url = url self.index = {} self.read_lock = RepoReadLock(url) self.write_lock = RepoWriteLock(url) self.client = None self.transport = None self.socket = socket() self.opened = False def open(self): """ Opens the connection """ self.socket.connect((interpret_urlish(self.url)[1], 22)) self.transport = Transport(self.socket) self.transport.start_client() authenticate_transport(self.transport) self.client = self.transport.open_sftp_client() target_path = interpret_urlish(self.url)[2] try: self.client.stat(target_path) except IOError: self.client.mkdir(target_path) self.client.chdir(target_path) self.opened = True def close(self): """ Closes the connection """ if not self.opened: return self.client.close() self.transport.close() self.socket.close() self.opened = False def update(self): """ Update the information in this class to match that of the remote. Raises exceptions if remote is invalid or in an invalid state """ if not self.opened: self.open() with self.read_lock: with self.client.open("index.json") as f: self.index = json.load(f) def get_script(self, hname=None): """ Get the script object """ if hname is None: hname = self.index["start"] return self.index["scripts"][hname] def download_script(self, hname=None): if hname is None: hname = self.index["start"] with self.read_lock: with self.client.open("scripts/" + hname + ".py", "r") as f: return f.read() def get_revision(self): return self.index["revision"] def append_script(self, script_obj, script_contents): h = sha512() h.update(script_contents.encode("utf-7")) hname = h.hexdigest() script_obj["prev"] = self.index["end"] with self.write_lock: self.index["revision"] += 1 if self.index["end"]: self.index["scripts"][self.index["end"]]["next"] = hname self.index["end"] = hname self.index["scripts"][hname] = script_obj if self.index["start"] == "": self.index["start"] = hname self._write() with self.client.open("scripts/" + hname + ".py", "w") as f: f.write(script_contents) def _write(self): with self.client.open("index.json", "w") as f: json.dump(self.index, f) def write(self): with self.write_lock: self._write() def __iter__(self): return FollowChainIterator(self, self.index["start"]) def iterate_from(self, pos): return FollowChainIterator(self, pos) def new(self): if not self.opened: self.open() try: self.client.stat("index.json") raise RuntimeError( "already init-ed, manually delete the folder to re-init") except IOError: pass # create the skeleton fs self.client.mkdir("locks") self.client.mkdir("scripts") # create a basic index.json self.index = { "version": 1, "revision": 0, "start": "", "end": "", "scripts": {} } self.write()
def ssh_paramiko_connect_to(display_desc): #plain socket attributes: dtype = display_desc["type"] host = display_desc["host"] port = display_desc.get("ssh-port", 22) #ssh and command attributes: username = display_desc.get("username") or get_username() if "proxy_host" in display_desc: display_desc.setdefault("proxy_username", get_username()) password = display_desc.get("password") target = ssh_target_string(display_desc) remote_xpra = display_desc["remote_xpra"] proxy_command = display_desc["proxy_command"] #ie: "_proxy_start" socket_dir = display_desc.get("socket_dir") display_as_args = display_desc["display_as_args"] #ie: "--start=xterm :10" socket_info = { "host": host, "port": port, } with nogssapi_context(): from paramiko import SSHConfig, ProxyCommand ssh_config = SSHConfig() user_config_file = os.path.expanduser("~/.ssh/config") sock = None host_config = None if os.path.exists(user_config_file): with open(user_config_file) as f: ssh_config.parse(f) host_config = ssh_config.lookup(host) if host_config: host = host_config.get("hostname", host) username = host_config.get("username", username) port = host_config.get("port", port) proxycommand = host_config.get("proxycommand") if proxycommand: sock = ProxyCommand(proxycommand) from xpra.child_reaper import getChildReaper cmd = getattr(sock, "cmd", []) getChildReaper().add_process(sock.process, "paramiko-ssh-client", cmd, True, True) log("found proxycommand='%s' for host '%s'", proxycommand, host) from paramiko.client import SSHClient ssh_client = SSHClient() ssh_client.load_system_host_keys() ssh_client.connect(host, port, sock=sock) transport = ssh_client.get_transport() do_ssh_paramiko_connect_to( transport, host, username, password, host_config or ssh_config.lookup("*")) chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args) peername = (host, port) conn = SSHProxyCommandConnection(chan, peername, target, socket_info) conn.timeout = SOCKET_TIMEOUT conn.start_stderr_reader() conn.process = (sock.process, "ssh", cmd) from xpra.net import bytestreams from paramiko.ssh_exception import ProxyCommandFailure bytestreams.CLOSED_EXCEPTIONS = tuple( list(bytestreams.CLOSED_EXCEPTIONS) + [ProxyCommandFailure]) return conn from xpra.scripts.main import socket_connect from paramiko.transport import Transport from paramiko import SSHException if "proxy_host" in display_desc: proxy_host = display_desc["proxy_host"] proxy_port = display_desc.get("proxy_port", 22) proxy_username = display_desc.get("proxy_username", username) proxy_password = display_desc.get("proxy_password", password) sock = socket_connect(dtype, proxy_host, proxy_port) middle_transport = Transport(sock) middle_transport.use_compression(False) try: middle_transport.start_client() except SSHException as e: log("start_client()", exc_info=True) raise InitException("SSH negotiation failed: %s" % e) proxy_host_config = ssh_config.lookup(host) do_ssh_paramiko_connect_to( middle_transport, proxy_host, proxy_username, proxy_password, proxy_host_config or ssh_config.lookup("*")) log("Opening proxy channel") chan_to_middle = middle_transport.open_channel( "direct-tcpip", (host, port), ('localhost', 0)) transport = Transport(chan_to_middle) transport.use_compression(False) try: transport.start_client() except SSHException as e: log("start_client()", exc_info=True) raise InitException("SSH negotiation failed: %s" % e) do_ssh_paramiko_connect_to(transport, host, username, password, host_config or ssh_config.lookup("*")) chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args) peername = (host, port) conn = SSHProxyCommandConnection(chan, peername, target, socket_info) conn.timeout = SOCKET_TIMEOUT conn.start_stderr_reader() return conn #plain TCP connection to the server, #we open it then give the socket to paramiko: sock = socket_connect(dtype, host, port) sockname = sock.getsockname() peername = sock.getpeername() log("paramiko socket_connect: sockname=%s, peername=%s", sockname, peername) transport = Transport(sock) transport.use_compression(False) try: transport.start_client() except SSHException as e: log("start_client()", exc_info=True) raise InitException("SSH negotiation failed: %s" % e) do_ssh_paramiko_connect_to(transport, host, username, password, host_config or ssh_config.lookup("*")) chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args) conn = SSHSocketConnection(chan, sock, sockname, peername, target, socket_info) conn.timeout = SOCKET_TIMEOUT conn.start_stderr_reader() return conn