def _annotate_hosts_with_ssh_config_info(): from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [ config.lookup(host).get('identityfile', None) for host in env.hosts ] env.key_filename = [ expanduser(key) for key in keys if key is not None ] env.hosts = [hostinfo(host, config) for host in env.hosts]
def __init__(self, hostname, configpath=None): ssh_config = SSHConfig() if not hostname: print(red('"hostname" must be defined')) sys.exit(1) parsed = self.parse_host(hostname) hostname = parsed.get('hostname') username = parsed.get('username') if configpath: if not isinstance(configpath, (list, tuple)): configpath = [configpath] for path in configpath: self._load_config(path, hostname) with (Path.home() / '.ssh/config').open() as fd: ssh_config.parse(fd) ssh_config = ssh_config.lookup(hostname) self.hostname = ssh_config['hostname'] self.username = username or ssh_config.get('user', getuser()) self.open() self.formatter = Formatter() self.sudo = '' self.cd = None self.screen = None self.env = {} self._sftp = None
def create_worker(host): config = SSHConfig() proxy = None if os.path.exists(os.path.expanduser('~/.ssh/config')): config.parse(open(os.path.expanduser('~/.ssh/config'))) if host.hostname is not None and \ 'proxycommand' in config.lookup(host.hostname): proxy = ProxyCommand(config.lookup(host.hostname)['proxycommand']) # proxy = paramiko.ProxyCommand("ssh -o StrictHostKeyChecking=no [email protected] nc 118.138.239.241 22") worker = SSHClient() worker.load_system_host_keys() worker.set_missing_host_key_policy(AutoAddPolicy()) worker.hostname = host.hostname # store all this for later reference (e.g., logging, reconnection) worker.username = host.username worker.password = host.password worker.proxy = proxy if not host.key_filename is None: worker.pkey = RSAKey.from_private_key_file(host.key_filename, host.key_password) else: worker.pkey = None # time.sleep(4) # worker.connect(hostname=host.hostname, username=host.username, password=host.password, key_filename=host.key_filename, sock=proxy, timeout=3600) worker.connect(hostname=host.hostname, username=host.username, password=host.password, pkey=worker.pkey, sock=proxy) return worker
def ssh_hosts(): paths = [] configs = {} try: import pwd for pw in pwd.getpwall(): config_path = path.join(pw.pw_dir, '.ssh', 'config') if path.isfile(config_path): paths.append((pw.pw_name, config_path)) except ImportError: config_path = path.expanduser(path.join('~', '.ssh', 'config')) if path.isfile(config_path): import getpass paths = [(getpass.getuser(), config_path)] for user, config_path in paths: ssh_config = SSHConfig() try: with open(config_path) as config: ssh_config.parse(config) except OSError: continue configs[user] = { host: ssh_config.lookup(host) for host in ssh_config.get_hostnames() } configs.update(ssh_putty_hosts()) return configs
def __init__(self, hostname, configpath=None, dry_run=False): ssh_config = SSHConfig() if not hostname: print(red('"hostname" must be defined')) sys.exit(1) parsed = self.parse_host(hostname) hostname = parsed.get('hostname') username = parsed.get('username') if configpath: if not isinstance(configpath, (list, tuple)): configpath = [configpath] for path in configpath: self._load_config(path, hostname) with (Path.home() / '.ssh/config').open() as fd: ssh_config.parse(fd) ssh_config = ssh_config.lookup(hostname) self.dry_run = dry_run self.hostname = config.hostname or ssh_config['hostname'] self.username = (username or config.username or ssh_config.get('user', getuser())) self.formatter = Formatter() self.key_filenames = [] if config.key_filename: self.key_filenames.append(config.key_filename) if 'identityfile' in ssh_config: self.key_filenames.extend(ssh_config['identityfile']) self.sudo = '' self.cd = None self.screen = None self.env = {} self._sftp = None self.proxy_command = ssh_config.get('proxycommand', config.proxy_command) self.open()
def does_not_affect_explicit_object(self, method): sc = SSHConfig() c = Config(ssh_config=sc, overrides={"load_ssh_configs": False}) # Implicit loading still doesn't happen...sanity check assert not method.called # Real test: the obj we passed in is present as usual assert c.base_ssh_config is sc
def parse_ssh_config(file_obj): """ Provided only as a backward-compatible wrapper around `.SSHConfig`. """ config = SSHConfig() config.parse(file_obj) return config
def create_worker(host): config = SSHConfig() proxy = None if os.path.exists(os.path.expanduser('~/.ssh/config')): with open(os.path.expanduser('~/.ssh/config')) as f: config.parse(f) if host.hostname is not None and 'proxycommand' in config.lookup( host.hostname): proxy = ProxyCommand(config.lookup(host.hostname)['proxycommand']) worker = SSHClient() worker.load_system_host_keys() worker.set_missing_host_key_policy(AutoAddPolicy()) # store data for later reference worker.host = host.hostname worker.username = host.username worker.password = host.password worker.key_filename = host.key_filename worker.connect(hostname=host.hostname, username=host.username, password=host.password, key_filename=host.key_filename, sock=proxy) return worker
def _annotate_hosts_with_ssh_config_info(): ''' Parse .ssh/config to get correct keys (avoids "Too many authentication failures"). env.hosts must be set. http://markpasc.typepad.com/blog/2010/04/loading-ssh-config-settings-for-fabric.html ''' from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [config.lookup(host).get('identityfile', None) for host in env.hosts] env.key_filename = [expanduser(key[0]) for key in keys if key is not None] env.hosts = [hostinfo(host, config) for host in env.hosts]
def _get_ssh_config(key): if not _ssh_config: ssh_config = SSHConfig() path = os.path.expanduser('~/.ssh/config') if os.path.exists(path): with open(path) as open_file: ssh_config.parse(open_file) # Create a fake hostname like "dev.myproject.ssha" to allow users to # set options in ~/.ssh/config based on the environment and project. hostname_parts = (get('config.name'), get('ssha.name'), 'ssha') hostname = '.'.join(filter(None, hostname_parts)) result = ssh_config.lookup(hostname) if 'identityfile' not in result: result['identityfile'] = [ '~/.ssh/id_rsa', '~/.ssh/id_dsa', '~/.ssh/id_ecdsa', '~/.ssh/id_ed25519', ] if 'user' not in result: user = os.environ.get('USER') if user: result['user'] = user _ssh_config.update(result) return _ssh_config.get(key, [])
def load_repo_data(): # TODO: Allow to override the current working directory, e.g. via --dir cwd = os.getcwd() repo = Repo(cwd) tracking_branch = repo.active_branch.tracking_branch() if tracking_branch: repo_branch = tracking_branch.remote_head remote_name = tracking_branch.remote_name repo_hash = tracking_branch.commit.hexsha repo_url = repo.remote(remote_name).url repo_url_parsed = giturlparse.parse(repo_url) if repo_url_parsed.protocol == "ssh": ssh_config_path = os.path.expanduser('~/.ssh/config') if os.path.exists(ssh_config_path): fp = open(ssh_config_path, 'r') config = SSHConfig() config.parse(fp) repo_url = repo_url.replace( repo_url_parsed.resource, config.lookup(repo_url_parsed.resource)['hostname']) # TODO: Detect and pass private key too fp.close() # TODO: Doesn't support unstaged changes repo_diff = repo.git.diff(repo_hash) return repo_url, repo_branch, repo_hash, repo_diff else: sys.exit( f"No tracked branch configured for branch {repo.active_branch.name}" )
def getSSHInfoForHost(host): """ Inspired by: http://markpasc.typepad.com/blog/2010/04/loading-ssh-config-settings-for-fabric.html """ from os.path import expanduser from paramiko.config import SSHConfig key = None key_filename = None host = host def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) key = config.lookup(host).get('identityfile', None) if key != None: key_filename = expanduser(key) host = hostinfo(host, config) return key_filename, host
def __init__(self, *args, **kwargs): """ Creates a new Fabric-specific config object. For most API details, see `invoke.config.Config.__init__`. Parameters new to this subclass are listed below. :param ssh_config: Custom/explicit `paramiko.config.SSHConfig` object. If given, prevents loading of any SSH config files. Default: ``None``. :param str runtime_ssh_path: Runtime SSH config path to load. Prevents loading of system/user files if given. Default: ``None``. :param str system_ssh_path: Location of the system-level SSH config file. Default: ``/etc/ssh/ssh_config``. :param str user_ssh_path: Location of the user-level SSH config file. Default: ``~/.ssh/config``. :param bool lazy: Has the same meaning as the parent class' ``lazy``, but additionally controls whether SSH config file loading is deferred (requires manually calling `load_ssh_config` sometime.) For example, one may need to wait for user input before calling `set_runtime_ssh_path`, which will inform exactly what `load_ssh_config` does. """ # Tease out our own kwargs. # TODO: consider moving more stuff out of __init__ and into methods so # there's less of this sort of splat-args + pop thing? Eh. ssh_config = kwargs.pop("ssh_config", None) lazy = kwargs.get("lazy", False) self.set_runtime_ssh_path(kwargs.pop("runtime_ssh_path", None)) system_path = kwargs.pop("system_ssh_path", "/etc/ssh/ssh_config") self._set(_system_ssh_path=system_path) self._set(_user_ssh_path=kwargs.pop("user_ssh_path", "~/.ssh/config")) # Record whether we were given an explicit object (so other steps know # whether to bother loading from disk or not) # This needs doing before super __init__ as that calls our post_init explicit = ssh_config is not None self._set(_given_explicit_object=explicit) # Arrive at some non-None SSHConfig object (upon which to run .parse() # later, in _load_ssh_file()) if ssh_config is None: ssh_config = SSHConfig() self._set(base_ssh_config=ssh_config) # Now that our own attributes have been prepared & kwargs yanked, we # can fall up into parent __init__() super(Config, self).__init__(*args, **kwargs) # And finally perform convenience non-lazy bits if needed if not lazy: self.load_ssh_config()
def ssh_config(host): from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) key = config.lookup(host).get('identityfile', None) key_filename = expanduser(key) env.key_filename = [key_filename] if key_filename else [] return hostinfo(host, config)
def loadSshConfig(self): if self._sshConfig is None: self._sshConfigStr = self._vagrant.ssh_config(vm_name=self.host) configObj = StringIO(self._sshConfigStr) self._sshConfig = SSHConfig() # noinspection PyTypeChecker self._sshConfig.parse(configObj) self._sshHostConfig = self._sshConfig.lookup(self.host)
def hosts(self): """Retrieve host instances from ssh config.""" config = SSHConfig() with Path(self.user_config).open() as fileobj: config.parse(fileobj) hostnames = [i for i in config.get_hostnames() if self.is_endhost(i)] return [self.transform_to_instances(i, config.lookup(i)) for i in hostnames]
def load_ssh_config(self, host): ssh_config = SSHConfig() for path in (os.path.expanduser('~/.ssh/config'), '/etc/ssh/ssh_config'): if os.path.isfile(path): with open(path) as fd: ssh_config.parse(fd) return ssh_config.lookup(host)
def parse_ssh_config(file_obj): """ Provided only as a backward-compatible wrapper around `.SSHConfig`. .. deprecated:: 2.7 Use `SSHConfig.from_file` instead. """ config = SSHConfig() config.parse(file_obj) return config
def from_ssh_config(cls, host, config_file=os.path.expanduser("~/.ssh/config")): if os.path.isfile(config_file): ssh_config = SSHConfig() with open(config_file) as f: ssh_config.parse(f) user_config = ssh_config.lookup(host) if 'proxycommand' in user_config: return cls(user_config['proxycommand']) return None
def _clone_init_kwargs(self, *args, **kw): # Parent kwargs kwargs = super(Config, self)._clone_init_kwargs(*args, **kw) # Transmit our internal SSHConfig via explicit-obj kwarg, thus # bypassing any file loading. (Our extension of clone() above copies # over other attributes as well so that the end result looks consistent # with reality.) new_config = SSHConfig() # TODO: as with other spots, this implies SSHConfig needs a cleaner # public API re: creating and updating its core data. new_config._config = copy.deepcopy(self.base_ssh_config._config) return dict(kwargs, ssh_config=new_config)
def __init__(self, containers_file, extra_ssh_config_file): with open(conf.containers_file()) as infile: containers = yaml.load(infile) self._containers = [] self._container_default_config = {} self._ssh_config = SSHConfig() if extra_ssh_config_file is not None: with open(extra_ssh_config_file) as ssh_config_file: self._ssh_config.parse(ssh_config_file) self._missing_host_key_policy = AutoAddPolicy() for container_config in containers: if container_config['Host'] == '*': self._container_default_config = container_config break for container_config in containers: if container_config['Host'] == '*': continue container_host = container_config['Host'] ssh_host_config = self._ssh_config.lookup(container_host) ip_address = self._get_hostname_option(container_config) container = { 'Hostname': container_host, 'Id': container_host, 'Name': container_host, 'Labels': { 'interface': container_config['Interface'], 'type': container_config['Type'] }, 'State': { 'Running': 'running' }, 'NetworkSettings': { 'IPAddress': ip_address, 'MacAddress': None, 'Ports': None }, 'Config': container_config } self._containers.append(container) self.next_exec_id = 0 self.ssh_connections = {} self.execs = {}
def __init__(self, gerrit_host_alias): ssh_config = SSHConfig() user_ssh_config_file = os.path.expanduser("~/.ssh/config") if os.path.exists(user_ssh_config_file): with open(user_ssh_config_file) as f: ssh_config.parse(f) gerrit_host_name = ssh_config.lookup(gerrit_host_alias).get("hostname") auth = HTTPBasicAuthFromNetrc("https://{}/".format(gerrit_host_alias)) self.gerrit_api_client = GerritRestAPI("https://{}/".format(gerrit_host_name), auth)
def __init__(self, host): self.host = host config_file = open(expanduser('.tmp/ssh_config')) config = SSHConfig() config.parse(config_file) ip = config.lookup(host).get('hostname', None) port = config.lookup(host).get('port', 22) pk = config.lookup(host).get('identityfile', None) self.ssh = paramiko.SSHClient() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.ssh.connect(hostname=ip, port=int(port), username=SSH_USERNAME, key_filename=pk) s = self.ssh.get_transport().open_session() paramiko.agent.AgentRequestHandler(s)
def __init__(self, host, credential=None, stdout_queue=None, stderr_queue=None): self._password = None self.host = host self.credential = credential self.stdout_queue = stdout_queue self.stderr_queue = stderr_queue self.client = SSHClient() self.client.set_missing_host_key_policy(AutoAddPolicy()) self.config = SSHConfig() self.forward_agent = False self.parse_config_if_exists()
def __init__(self, hostname, username=None, password=None, transport=None, port=None, ssh_config_file=None): self.hostname = hostname c_args = dict() c_args['username'] = os.getenv('EOS_USER') or os.getenv( 'USER') or username c_args['password'] = os.getenv('EOS_PASSWORD') or os.getenv( 'PASSWORD') or password if port: c_args['port'] = port ssh_config_file = ssh_config_file or os.getenv('EOS_SSH_CONFIG') if ssh_config_file: ssh_config = SSHConfig() ssh_config.parse(open(ssh_config_file)) found = ssh_config.lookup(hostname) if 'user' in found: c_args['username'] = found['user'] if 'hostname' in found: c_args['host'] = found['hostname'] if 'localforward' in found: port = int(first(found['localforward']).split()[0]) c_args['port'] = port c_args['host'] = 'localhost' else: c_args['host'] = hostname c_args['transport'] = transport or self.DEFAULT_TRANSPORT self.api = pyeapi.connect(**c_args)
def __init__(self, hostname, user=None, filename=None): #set defaults if filename == None: filename = os.path.expanduser('~/.ssh/config') #read config file ssh_config = SSHConfig() with open(filename) as config_file: ssh_config.parse(config_file) self.update(ssh_config.lookup(hostname)) self.defaults = { 'port': 22, 'user': getpass.getuser(), 'hostname': hostname, 'hostkeyalias': hostname } if user != None: self['user'] = user
def annotate_from_sshconfig(env): """ Adds support for reading the host names, users and ports from ~/ssh/config Replaces the hosts defined in ssh config with actual host names, so that Fabric can take the advantage from it .. IMPORTANT:: This does not support /etc/ssh/ssh_config yet! """ from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host # Look for user config, if found, parse it and update roledefs. Otherwise just ignore it (it is not required at all) try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [ config.lookup(host).get('identityfile', None) for host in api.env.hosts ] env.key_filename = [expanduser(key) for key in keys if key is not None] env.hosts = [hostinfo(host, config) for host in env.hosts] for role, rolehosts in env.roledefs.items(): env.roledefs[role] = [hostinfo(host, config) for host in rolehosts]
def open_gateway(self): """ Obtain a socket-like object from `gateway`. :returns: A ``direct-tcpip`` `paramiko.channel.Channel`, if `gateway` was a `.Connection`; or a `~paramiko.proxy.ProxyCommand`, if `gateway` was a string. .. versionadded:: 2.0 """ # ProxyCommand is faster to set up, so do it first. if isinstance(self.gateway, string_types): # Leverage a dummy SSHConfig to ensure %h/%p/etc are parsed. # TODO: use real SSH config once loading one properly is # implemented. ssh_conf = SSHConfig() dummy = "Host {}\n ProxyCommand {}" ssh_conf.parse(StringIO(dummy.format(self.host, self.gateway))) return ProxyCommand(ssh_conf.lookup(self.host)["proxycommand"]) # Handle inner-Connection gateway type here. # TODO: logging self.gateway.open() # TODO: expose the opened channel itself as an attribute? (another # possible argument for separating the two gateway types...) e.g. if # someone wanted to piggyback on it for other same-interpreter socket # needs... # TODO: and the inverse? allow users to supply their own socket/like # object they got via $WHEREEVER? # TODO: how best to expose timeout param? reuse general connection # timeout from config? return self.gateway.transport.open_channel( kind="direct-tcpip", dest_addr=(self.host, int(self.port)), # NOTE: src_addr needs to be 'empty but not None' values to # correctly encode into a network message. Theoretically Paramiko # could auto-interpret None sometime & save us the trouble. src_addr=("", 0), )
def __init__(self, hostname, port=22, username=None, config_path=None): self.hostname = hostname self.client = SSHClient() self.client.load_system_host_keys() self.client.set_missing_host_key_policy(AutoAddPolicy()) if config_path is None: config_path = os.path.join(os.path.expanduser('~'), '.ssh', 'config') self.config = SSHConfig() with open(config_path) as config_file: self.config.parse(config_file) if hostname in self.config.get_hostnames(): host_cfg = self.config.lookup(hostname) full_hostname = host_cfg.get('hostname', hostname) if username is None: username = host_cfg.get('user', None) # If none, it will try the user running the server. else: full_hostname = hostname self.client.connect(full_hostname, port, username=username)
def __init__(self, hostname: str, root: Path, port: int, username: str, password: str, key: Union[PathLike, Sequence[PathLike]]): ssh = SSHClient() ssh.load_system_host_keys() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) config_path = Path('~/.ssh/config').expanduser() if config_path.exists(): with open(config_path) as f: config = SSHConfig() config.parse(f) host = config.lookup(hostname) hostname = host.get('hostname', hostname) port = host.get('port', port) username = host.get('user', username) key = host.get('identityfile', key) [self.hostname, self.port, self.username, self.password, self.key] = hostname, port, username, password, key self.root = root self.ssh = ssh