Esempio n. 1
0
    def establish_connection(self,
                             sleep_time=3,
                             verbose=True,
                             timeout=8,
                             use_keys=False,
                             key_file=None,
                             width=None,
                             height=None):
        '''
        Special Fortinet handler for SSH connection
        '''
        # Create instance of SSHClient object
        self.remote_conn_pre = paramiko.SSHClient()

        # Automatically add untrusted hosts (make sure appropriate for your environment)
        self.remote_conn_pre.set_missing_host_key_policy(
            paramiko.AutoAddPolicy())

        # initiate SSH connection
        try:
            self.remote_conn_pre.connect(hostname=self.ip,
                                         port=self.port,
                                         username=self.username,
                                         password=self.password,
                                         look_for_keys=use_keys,
                                         allow_agent=False,
                                         timeout=timeout)
        except socket.error:
            msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.ip, port=self.port)
            raise NetMikoTimeoutException(msg)
        except paramiko.ssh_exception.AuthenticationException as auth_err:
            msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.ip, port=self.port)
            msg += '\n' + str(auth_err)
            raise NetMikoAuthenticationException(msg)

        if verbose:
            print("SSH connection established to {0}:{1}".format(
                self.ip, self.port))

        # Since Fortinet paging setting is global use terminal settings instead (if necessary)
        if width and height:
            self.remote_conn = self.remote_conn_pre.invoke_shell(term='vt100',
                                                                 width=width,
                                                                 height=height)
        else:
            self.remote_conn = self.remote_conn_pre.invoke_shell()

        if verbose:
            print("Interactive SSH session established")

        # Strip the initial router prompt
        time.sleep(sleep_time)
        return self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
Esempio n. 2
0
 def wait_for_recv_ready(self, delay_factor=.1, max_loops=100, send_newline=False):
     """Wait for data to be in the buffer so it can be received."""
     i = 0
     time.sleep(delay_factor)
     while i <= max_loops:
         if self.remote_conn.recv_ready():
             return True
         else:
             time.sleep(delay_factor)
             i += 1
     raise NetMikoTimeoutException("Timed out waiting for recv_ready")
Esempio n. 3
0
 def _timeout_exceeded(self, start, msg='Timeout exceeded!'):
     """
     Raise NetMikoTimeoutException if waiting too much in the
     serving queue.
     """
     if not start:
         # Must provide a comparison time
         return False
     if time.time() - start > self.session_timeout:
         # session_timeout exceeded
         raise NetMikoTimeoutException(msg)
     return False
Esempio n. 4
0
    def establish_connection(self, width=None, height=None):
        """
        Establish SSH connection to the network device

        Timeout will generate a NetMikoTimeoutException
        Authentication failure will generate a NetMikoAuthenticationException

        width and height are needed for Fortinet paging setting.
        """
        if self.protocol == 'telnet':
            self.remote_conn = telnetlib.Telnet(self.host,
                                                port=self.port,
                                                timeout=self.timeout)
            self.telnet_login()
        elif self.protocol == 'serial':
            self.remote_conn = serial.Serial(**self.serial_settings)
            self.serial_login()
        elif self.protocol == 'ssh':
            ssh_connect_params = self._connect_params_dict()
            self.remote_conn_pre = self._build_ssh_client()

            # initiate SSH connection
            try:
                self.remote_conn_pre.connect(**ssh_connect_params)
            except socket.error:
                msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
                    device_type=self.device_type, ip=self.host, port=self.port)
                raise NetMikoTimeoutException(msg)
            except paramiko.ssh_exception.AuthenticationException as auth_err:
                msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
                    device_type=self.device_type, ip=self.host, port=self.port)
                msg += self.RETURN + str(auth_err)
                raise NetMikoAuthenticationException(msg)

            if self.verbose:
                print("SSH connection established to {0}:{1}".format(
                    self.host, self.port))

            # Use invoke_shell to establish an 'interactive session'
            if width and height:
                self.remote_conn = self.remote_conn_pre.invoke_shell(
                    term='vt100', width=width, height=height)
            else:
                self.remote_conn = self.remote_conn_pre.invoke_shell()

            self.remote_conn.settimeout(self.timeout)
            if self.keepalive:
                self.remote_conn.transport.set_keepalive(self.keepalive)
            self.special_login_handler()
            if self.verbose:
                print("Interactive SSH session established")
        return ""
    def establish_connection(self,
                             sleep_time=3,
                             verbose=True,
                             timeout=8,
                             use_keys=False):
        '''
        Establish SSH connection to the network device

        Timeout will generate a NetMikoTimeoutException
        Authentication failure will generate a NetMikoAuthenticationException

        use_keys is a boolean that allows ssh-keys to be used for authentication
        '''

        # Create instance of SSHClient object
        self.remote_conn_pre = paramiko.SSHClient()

        # Automatically add untrusted hosts (make sure appropriate for your environment)
        self.remote_conn_pre.set_missing_host_key_policy(
            paramiko.AutoAddPolicy())

        # initiate SSH connection
        try:
            self.remote_conn_pre.connect(hostname=self.ip,
                                         port=self.port,
                                         username=self.username,
                                         password=self.password,
                                         look_for_keys=use_keys,
                                         allow_agent=False,
                                         timeout=timeout)
        except socket.error:
            msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.ip, port=self.port)
            raise NetMikoTimeoutException(msg)
        except paramiko.ssh_exception.AuthenticationException as auth_err:
            msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.ip, port=self.port)
            msg += '\n' + str(auth_err)
            raise NetMikoAuthenticationException(msg)

        if verbose:
            print("SSH connection established to {0}:{1}".format(
                self.ip, self.port))

        # Use invoke_shell to establish an 'interactive session'
        self.remote_conn = self.remote_conn_pre.invoke_shell()
        if verbose:
            print("Interactive SSH session established")

        # Strip the initial router prompt
        time.sleep(sleep_time)
        return self.remote_conn.recv(MAX_BUFFER).decode('utf-8')
Esempio n. 6
0
 def read_until_pattern(self, pattern='', re_flags=0):
     """Read channel until pattern detected. Return ALL data available."""
     output = ''
     if not pattern:
         pattern = self.base_prompt
     pattern = re.escape(pattern)
     while True:
         try:
             output += self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
             if re.search(pattern, output, flags=re_flags):
                 return output
         except socket.timeout:
             raise NetMikoTimeoutException("Timed-out reading channel, data not available.")
Esempio n. 7
0
 def read_until_prompt_or_pattern(self, pattern='', re_flags=0):
     """Read until either self.base_prompt or pattern is detected. Return ALL data available."""
     output = ''
     if not pattern:
         pattern = self.base_prompt
     pattern = re.escape(pattern)
     base_prompt_pattern = re.escape(self.base_prompt)
     while True:
         try:
             output += self.read_channel()
             if re.search(pattern, output, flags=re_flags) or re.search(base_prompt_pattern,
                                                                        output, flags=re_flags):
                 return output
         except socket.timeout:
             raise NetMikoTimeoutException("Timed-out reading channel, data not available.")
Esempio n. 8
0
 def wait_for_recv_ready_newline(self, delay_factor=.1, max_loops=20):
     """Wait for data to be in the buffer so it can be received."""
     i = 0
     time.sleep(delay_factor)
     while i <= max_loops:
         if self.remote_conn.recv_ready():
             return True
         else:
             self.remote_conn.sendall('\n')
             delay_factor = delay_factor * 1.1
             if delay_factor >= 8:
                 delay_factor = 8
             time.sleep(delay_factor)
             i += 1
     raise NetMikoTimeoutException("Timed out waiting for recv_ready")
Esempio n. 9
0
    def _timeout_exceeded(self, start, msg='Timeout exceeded!'):
        """Raise NetMikoTimeoutException if waiting too much in the serving queue.

        :param start: Initial start time to see if session lock timeout has been exceeded
        :type start: float (from time.time() call i.e. epoch time)

        :param msg: Exception message if timeout was exceeded
        :type msg: str
        """
        if not start:
            # Must provide a comparison time
            return False
        if time.time() - start > self.session_timeout:
            # session_timeout exceeded
            raise NetMikoTimeoutException(msg)
        return False
Esempio n. 10
0
    def establish_connection(self, sleep_time=3, verbose=True, timeout=8, use_keys=False,
                             key_file=None, width=None, height=None):
        """Special Fortinet handler for SSH connection"""
        self.remote_conn_pre = paramiko.SSHClient()
        self.remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            self.remote_conn_pre.connect(hostname=self.ip, port=self.port,
                                         username=self.username, password=self.password,
                                         look_for_keys=use_keys, allow_agent=False,
                                         timeout=timeout)
        except socket.error:
            msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.ip, port=self.port)
            raise NetMikoTimeoutException(msg)
        except paramiko.ssh_exception.AuthenticationException as auth_err:
            msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.ip, port=self.port)
            msg += '\n' + str(auth_err)
            raise NetMikoAuthenticationException(msg)

        if verbose:
            print("SSH connection established to {0}:{1}".format(self.ip, self.port))

        # Since Fortinet paging setting is global use terminal settings instead (if necessary)
        if width and height:
            self.remote_conn = self.remote_conn_pre.invoke_shell(term='vt100',
                                                                 width=width,
                                                                 height=height)
        else:
            self.remote_conn = self.remote_conn_pre.invoke_shell()

        if verbose:
            print("Interactive SSH session established")

        i = 0
        while i <= 100:
            time.sleep(.1)
            if self.remote_conn.recv_ready():
                return self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
            else:
                # Send a newline if no data is present
                self.remote_conn.sendall('\n')
                i += 1

        return ""
Esempio n. 11
0
 def enable(self, cmd='sudo su', pattern='ssword', re_flags=re.IGNORECASE):
     """Attempt to become root."""
     delay_factor = self.select_delay_factor(delay_factor=0)
     output = ""
     if not self.check_enable_mode():
         self.write_channel(self.normalize_cmd(cmd))
         time.sleep(.3 * delay_factor)
         try:
             output += self.read_channel()
             if re.search(pattern, output, flags=re_flags):
                 self.write_channel(self.normalize_cmd(self.secret))
             self.set_base_prompt()
         except socket.timeout:
             raise NetMikoTimeoutException(
                 "Timed-out reading channel, data not available.")
         if not self.check_enable_mode():
             raise ValueError("Failed to enter enable mode.")
     return output
Esempio n. 12
0
 def enable(self, cmd='sudo su', pattern='ssword', re_flags=re.IGNORECASE):
     """Attempt to become root."""
     output = ""
     if not self.check_enable_mode():
         self.remote_conn.sendall(self.normalize_cmd(cmd))
         time.sleep(.3)
         pattern = re.escape(pattern)
         try:
             output += self.remote_conn.recv(MAX_BUFFER).decode(
                 'utf-8', 'ignore')
             if re.search(pattern, output, flags=re_flags):
                 self.remote_conn.sendall(self.normalize_cmd(self.secret))
             self.set_base_prompt()
         except socket.timeout:
             raise NetMikoTimeoutException(
                 "Timed-out reading channel, data not available.")
         if not self.check_enable_mode():
             raise ValueError("Failed to enter enable mode.")
     return output
Esempio n. 13
0
 def enable(self, cmd="sudo su", pattern="ssword", re_flags=re.IGNORECASE):
     """Attempt to become root."""
     delay_factor = self.select_delay_factor(delay_factor=0)
     output = ""
     if not self.check_enable_mode():
         self.write_channel(self.normalize_cmd(cmd))
         time.sleep(0.3 * delay_factor)
         try:
             output += self.read_channel()
             if re.search(pattern, output, flags=re_flags):
                 self.write_channel(self.normalize_cmd(self.secret))
             self.set_base_prompt()
         except socket.timeout:
             raise NetMikoTimeoutException(
                 "Timed-out reading channel, data not available.")
         if not self.check_enable_mode():
             msg = ("Failed to enter enable mode. Please ensure you pass "
                    "the 'secret' argument to ConnectHandler.")
             raise ValueError(msg)
     return output
Esempio n. 14
0
 def _test_channel_read(self, count=40):
     """Try to read the channel (generally post login) verify you receive data back."""
     i = 0
     delay_factor = self.select_delay_factor(delay_factor=0)
     main_delay = delay_factor * .1
     time.sleep(main_delay * 10)
     new_data = ""
     while i <= count:
         new_data = self._read_channel_timing()
         if new_data:
             break
         else:
             self.write_channel('\n')
             main_delay = main_delay * 1.1
             if main_delay >= 8:
                 main_delay = 8
             time.sleep(main_delay)
             i += 1
     # check if data was ever present
     if new_data:
         return ""
     else:
         raise NetMikoTimeoutException("Timed out waiting for data")
Esempio n. 15
0
    def establish_connection(self, width=None, height=None):
        """
        Establish SSH connection to the network device

        Timeout will generate a NetMikoTimeoutException
        Authentication failure will generate a NetMikoAuthenticationException

        width and height are needed for Fortinet paging setting.
        """
        if self.protocol == 'telnet':
            self.remote_conn = telnetlib.Telnet(self.host,
                                                port=self.port,
                                                timeout=self.timeout)
            self.telnet_login()
        elif self.protocol == 'ssh':

            # Convert Paramiko connection parameters to a dictionary
            ssh_connect_params = self._connect_params_dict()

            # Check if using SSH 'config' file mainly for SSH proxy support
            if self.ssh_config_file:
                self._use_ssh_config(ssh_connect_params)

            # Create instance of SSHClient object
            self.remote_conn_pre = paramiko.SSHClient()

            # Load host_keys for better SSH security
            if self.system_host_keys:
                self.remote_conn_pre.load_system_host_keys()
            if self.alt_host_keys and path.isfile(self.alt_key_file):
                self.remote_conn_pre.load_host_keys(self.alt_key_file)

            # Default is to automatically add untrusted hosts (make sure appropriate for your env)
            self.remote_conn_pre.set_missing_host_key_policy(self.key_policy)

            # initiate SSH connection
            try:
                self.remote_conn_pre.connect(**ssh_connect_params)
            except socket.error:
                msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
                    device_type=self.device_type, ip=self.host, port=self.port)
                raise NetMikoTimeoutException(msg)
            except paramiko.ssh_exception.AuthenticationException as auth_err:
                msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
                    device_type=self.device_type, ip=self.host, port=self.port)
                msg += '\n' + str(auth_err)
                raise NetMikoAuthenticationException(msg)

            if self.verbose:
                print("SSH connection established to {0}:{1}".format(
                    self.host, self.port))

            # Use invoke_shell to establish an 'interactive session'
            if width and height:
                self.remote_conn = self.remote_conn_pre.invoke_shell(
                    term='vt100', width=width, height=height)
            else:
                self.remote_conn = self.remote_conn_pre.invoke_shell()

            self.remote_conn.settimeout(self.timeout)
            self.special_login_handler()
            if self.verbose:
                print("Interactive SSH session established")

        # make sure you can read the channel
        i = 0
        delay_factor = self.select_delay_factor(delay_factor=0)
        main_delay = delay_factor * .1
        time.sleep(main_delay)
        while i <= 40:
            new_data = self.read_channel()
            if new_data:
                break
            else:
                self.write_channel('\n')
                main_delay = main_delay * 1.1
                if main_delay >= 8:
                    main_delay = 8
                time.sleep(main_delay)
                i += 1
        # check if data was ever present
        if new_data:
            return ""
        else:
            raise NetMikoTimeoutException("Timed out waiting for data")
Esempio n. 16
0
    def _read_channel_expect(self, pattern='', re_flags=0, max_loops=150):
        """Function that reads channel until pattern is detected.

        pattern takes a regular expression.

        By default pattern will be self.base_prompt

        Note: this currently reads beyond pattern. In the case of SSH it reads MAX_BUFFER.
        In the case of telnet it reads all non-blocking data.

        There are dependencies here like determining whether in config_mode that are actually
        depending on reading beyond pattern.

        :param pattern: Regular expression pattern used to identify the command is done \
        (defaults to self.base_prompt)
        :type pattern: str (regular expression)

        :param re_flags: regex flags used in conjunction with pattern to search for prompt \
        (defaults to no flags)
        :type re_flags: re module flags

        :param max_loops: max number of iterations to read the channel before raising exception.
            Will default to be based upon self.timeout.
        :type max_loops: int

        """
        output = ''
        if not pattern:
            pattern = re.escape(self.base_prompt)
        log.debug("Pattern is: {}".format(pattern))

        i = 1
        loop_delay = .1
        # Default to making loop time be roughly equivalent to self.timeout (support old max_loops
        # argument for backwards compatibility).
        if max_loops != 150:
            max_loops = self.timeout / loop_delay
        while i < max_loops:
            if self.protocol == 'ssh':
                try:
                    # If no data available will wait timeout seconds trying to read
                    self._lock_netmiko_session()
                    new_data = self.remote_conn.recv(MAX_BUFFER)
                    if len(new_data) == 0:
                        raise EOFError(
                            "Channel stream closed by remote device.")
                    new_data = new_data.decode('utf-8', 'ignore')
                    log.debug(
                        "_read_channel_expect read_data: {}".format(new_data))
                    output += new_data
                except socket.timeout:
                    raise NetMikoTimeoutException(
                        "Timed-out reading channel, data not available.")
                finally:
                    self._unlock_netmiko_session()
            elif self.protocol == 'telnet' or 'serial':
                output += self.read_channel()
            if re.search(pattern, output, flags=re_flags):
                log.debug("Pattern found: {} {}".format(pattern, output))
                return output
            time.sleep(loop_delay * self.global_delay_factor)
            i += 1
        raise NetMikoTimeoutException(
            "Timed-out reading channel, pattern not found in output: {}".
            format(pattern))
Esempio n. 17
0
    def establish_connection(self,
                             sleep_time=3,
                             verbose=True,
                             timeout=8,
                             use_keys=False):
        '''
        Establish SSH connection to the network device

        Timeout will generate a NetmikoTimeoutException
        Authentication failure will generate a NetmikoAuthenticationException

        WLC presents with the following on login

        login as: user

        (Cisco Controller)

        User: user

        Password:****
       
        Manually send username/password to work around this. 
        '''

        # Create instance of SSHClient object
        self.remote_conn_pre = paramiko.SSHClient()

        # Automatically add untrusted hosts (make sure appropriate for your environment)
        self.remote_conn_pre.set_missing_host_key_policy(
            paramiko.AutoAddPolicy())

        # initiate SSH connection
        if verbose:
            print "SSH connection established to {0}:{1}".format(
                self.ip, self.port)

        try:
            self.remote_conn_pre.connect(hostname=self.ip,
                                         port=self.port,
                                         username=self.username,
                                         password=self.password,
                                         look_for_keys=use_keys,
                                         allow_agent=False,
                                         timeout=timeout)
        except socket.error as e:
            msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.ip, port=self.port)
            raise NetMikoTimeoutException(msg)
        except paramiko.ssh_exception.AuthenticationException as e:
            msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.ip, port=self.port)
            msg += '\n' + str(e)
            raise NetMikoAuthenticationException(msg)

        # Use invoke_shell to establish an 'interactive session'
        self.remote_conn = self.remote_conn_pre.invoke_shell()

        # Handle WLCs extra
        self.remote_conn.send(self.username + '\n')
        time.sleep(.2)
        self.remote_conn.send(self.password + '\n')
        if verbose:
            print "Interactive SSH session established"

        # Strip the initial router prompt
        time.sleep(sleep_time)
        return self.remote_conn.recv(MAX_BUFFER)
Esempio n. 18
0
    def establish_connection(self,
                             sleep_time=3,
                             verbose=True,
                             timeout=8,
                             use_keys=False,
                             key_file=None):
        """
        Establish SSH connection to the network device

        Timeout will generate a NetMikoTimeoutException
        Authentication failure will generate a NetMikoAuthenticationException

        use_keys is a boolean that allows ssh-keys to be used for authentication
        """

        # Convert Paramiko connection parameters to a dictionary
        ssh_connect_params = self._connect_params_dict(use_keys=use_keys,
                                                       key_file=key_file,
                                                       timeout=timeout)

        # Check if using SSH 'config' file mainly for SSH proxy support (updates ssh_connect_params)
        if self.ssh_config_file:
            self._use_ssh_config(ssh_connect_params)

        # Create instance of SSHClient object
        self.remote_conn_pre = paramiko.SSHClient()

        # Load host_keys for better SSH security
        if self.system_host_keys:
            self.remote_conn_pre.load_system_host_keys()
        if self.alt_host_keys and path.isfile(self.alt_key_file):
            self.remote_conn_pre.load_host_keys(self.alt_key_file)

        # Default is to automatically add untrusted hosts (make sure appropriate for your env)
        self.remote_conn_pre.set_missing_host_key_policy(self.key_policy)

        # initiate SSH connection
        try:
            self.remote_conn_pre.connect(**ssh_connect_params)
        except socket.error:
            msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.host, port=self.port)
            raise NetMikoTimeoutException(msg)
        except paramiko.ssh_exception.AuthenticationException as auth_err:
            msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
                device_type=self.device_type, ip=self.host, port=self.port)
            msg += '\n' + str(auth_err)
            raise NetMikoAuthenticationException(msg)

        if verbose:
            print("SSH connection established to {0}:{1}".format(
                self.host, self.port))

        # Use invoke_shell to establish an 'interactive session'
        self.remote_conn = self.remote_conn_pre.invoke_shell()
        self.remote_conn.settimeout(timeout)
        self.special_login_handler()
        if verbose:
            print("Interactive SSH session established")

        time.sleep(.1)
        if self.wait_for_recv_ready_newline():
            return self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
        return ""