def connect(self, host, port=830, timeout=None, unknown_host_cb=default_unknown_host_cb, username=None, password=None, key_filename=None, allow_agent=True, hostkey_verify=True, look_for_keys=True, ssh_config=None): """Connect via SSH and initialize the NETCONF session. First attempts the publickey authentication method and then password authentication. To disable attempting publickey authentication altogether, call with *allow_agent* and *look_for_keys* as `False`. *host* is the hostname or IP address to connect to *port* is by default 830, but some devices use the default SSH port of 22 so this may need to be specified *timeout* is an optional timeout for socket connect *unknown_host_cb* is called when the server host key is not recognized. It takes two arguments, the hostname and the fingerprint (see the signature of :func:`default_unknown_host_cb`) *username* is the username to use for SSH authentication *password* is the password used if using password authentication, or the passphrase to use for unlocking keys that require it *key_filename* is a filename where a the private key to be used can be found *allow_agent* enables querying SSH agent (if found) for keys *hostkey_verify* enables hostkey verification from ~/.ssh/known_hosts *look_for_keys* enables looking in the usual locations for ssh keys (e.g. :file:`~/.ssh/id_*`) *ssh_config* enables parsing of an OpenSSH configuration file, if set to its path, e.g. :file:`~/.ssh/config` or to True (in this case, use :file:`~/.ssh/config`). """ # Optionaly, parse .ssh/config config = {} if ssh_config is True: ssh_config = "~/.ssh/config" if sys.platform != "win32" else "~/ssh/config" if ssh_config is not None: config = paramiko.SSHConfig() config.parse(open(os.path.expanduser(ssh_config))) config = config.lookup(host) host = config.get("hostname", host) if username is None: username = config.get("user") if key_filename is None: key_filename = config.get("identityfile") if username is None: username = getpass.getuser() sock = None if config.get("proxycommand"): sock = paramiko.proxy.ProxyCommand(config.get("proxycommand")) else: for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res try: sock = socket.socket(af, socktype, proto) sock.settimeout(timeout) except socket.error: continue try: sock.connect(sa) except socket.error: sock.close() continue break else: raise SSHError("Could not open socket to %s:%s" % (host, port)) t = self._transport = paramiko.Transport(sock) t.set_log_channel(logger.name) try: t.start_client() except paramiko.SSHException: raise SSHError('Negotiation failed') # host key verification server_key = t.get_remote_server_key() fingerprint = _colonify(hexlify(server_key.get_fingerprint())) if hostkey_verify: known_host = self._host_keys.check(host, server_key) if not known_host and not unknown_host_cb(host, fingerprint): raise SSHUnknownHostError(host, fingerprint) if key_filename is None: key_filenames = [] elif isinstance(key_filename, basestring): key_filenames = [key_filename] else: key_filenames = key_filename self._auth(username, password, key_filenames, allow_agent, look_for_keys) self._connected = True # there was no error authenticating # TODO: leopoul: Review, test, and if needed rewrite this part subsystem_names = self._device_handler.get_ssh_subsystem_names() for subname in subsystem_names: c = self._channel = self._transport.open_session() self._channel_id = c.get_id() channel_name = "%s-subsystem-%s" % (subname, str(self._channel_id)) c.set_name(channel_name) try: c.invoke_subsystem(subname) except paramiko.SSHException as e: logger.info("%s (subsystem request rejected)", e) handle_exception = self._device_handler.handle_connection_exceptions( self) # Ignore the exception, since we continue to try the different # subsystem names until we find one that can connect. #have to handle exception for each vendor here if not handle_exception: continue self._channel_name = c.get_name() self._post_connect() return raise SSHError( "Could not open connection, possibly due to unacceptable" " SSH subsystem name.")
def connect( self, host, port=830, timeout=None, unknown_host_cb=default_unknown_host_cb, username=None, password=None, key_filename=None, allow_agent=True, look_for_keys=True): """Connect via SSH and initialize the NETCONF session. First attempts the publickey authentication method and then password authentication. To disable attempting publickey authentication altogether, call with *allow_agent* and *look_for_keys* as `False`. *host* is the hostname or IP address to connect to *port* is by default 830, but some devices use the default SSH port of 22 so this may need to be specified *timeout* is an optional timeout for socket connect *unknown_host_cb* is called when the server host key is not recognized. It takes two arguments, the hostname and the fingerprint (see the signature of :func:`default_unknown_host_cb`) *username* is the username to use for SSH authentication *password* is the password used if using password authentication, or the passphrase to use for unlocking keys that require it *key_filename* is a filename where a the private key to be used can be found *allow_agent* enables querying SSH agent (if found) for keys *look_for_keys* enables looking in the usual locations for ssh keys (e.g. :file:`~/.ssh/id_*`) """ if username is None: username = getpass.getuser() sock = None for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res try: sock = socket.socket(af, socktype, proto) sock.settimeout(timeout) except socket.error: continue try: sock.connect(sa) except socket.error: sock.close() continue break else: raise SSHError("Could not open socket to %s:%s" % (host, port)) t = self._transport = paramiko.Transport(sock) t.set_log_channel(logger.name) try: t.start_client() except paramiko.SSHException: raise SSHError('Negotiation failed') # host key verification server_key = t.get_remote_server_key() known_host = self._host_keys.check(host, server_key) fingerprint = _colonify(hexlify(server_key.get_fingerprint())) if not known_host and not unknown_host_cb(host, fingerprint): raise SSHUnknownHostError(host, fingerprint) if key_filename is None: key_filenames = [] elif isinstance(key_filename, basestring): key_filenames = [key_filename] else: key_filenames = key_filename self._auth( username, password, key_filenames, allow_agent, look_for_keys) self._connected = True # there was no error authenticating c = self._channel = self._transport.open_session() c.set_name("netconf") c.invoke_subsystem("netconf") self._post_connect()
try: t.start_client() except paramiko.SSHException: raise SSHError('Negotiation failed') # host key verification server_key = t.get_remote_server_key() #self._host_keys.add(host, "ssh-rsa", server_key) known_host = self._host_keys.check(host, server_key) fingerprint = _colonify(hexlify(server_key.get_fingerprint())) if hostkey_verify: if not known_host and not unknown_host_cb(host, fingerprint): raise SSHUnknownHostError(host, fingerprint) if key_filename is None: key_filenames = [] elif isinstance(key_filename, basestring): key_filenames = [key_filename] else: key_filenames = key_filename self._auth(username, password, key_filenames, allow_agent, look_for_keys) self._connected = True # there was no error authenticatinB # TODO: leopoul: Review, test, and if needed rewrite this part subsystem_names = self._device_handler.get_ssh_subsystem_names() for subname in subsystem_names: c = self._channel = self._transport.open_session() self._channel_id = c.get_id()