Ejemplo n.º 1
0
    def __init__(self,
                 device,
                 parser,
                 ssh_timeout=DEFAULT_TIMEOUT,
                 ssh_max_bytes=DEFAULT_MAX_BYTES,
                 ssh_max_attempts=DEFAULT_MAX_ATTEMPTS):

        self.network_parser = None

        self.device = device
        self.hostname = device.system_name

        self.ssh_timeout = ssh_timeout
        self.ssh_max_bytes = ssh_max_bytes
        self.ssh_max_attempts = ssh_max_attempts

        self._auth_manager = AuthManager(parser)
class AuthManagerTest(unittest.TestCase):
    mgr = AuthManager(None, MockUsersManager())

    def test_hash_password(self):
        pwd = 'Ezekiel2517'
        expected_hash = 'C27E5A5B42AD5F7C1204E36DE2C569C37496FC41213960A147BE53B1DF2867FC'
        actual_hash = self.mgr.hash_password(pwd)

        assert expected_hash == actual_hash

    def test_compare_hashes(self):
        hash1 = 'C27E5A5B42AD5F7C1204E36DE2C569C37496FC41213960A147BE53B1DF2867FC'
        hash2 = 'C27E5A5B42AD5F7C1204E36DE2C569C37496FC41213960A147BE53B1DF2867FC'

        assert self.mgr.compare_hashes(hash1, hash2) is True
        assert self.mgr.compare_hashes(hash1 + '1', hash2) is False

    def test_check_auth(self):
        username = '******'
        password = '******'

        assert self.mgr.check_auth(username, password) is True
        assert self.mgr.check_auth(username, password + '1') is False
        assert self.mgr.check_auth(username + '1', password) is False

    def test_check_token(self):
        token = 'aGFycnk6RXpla2llbDI1MTc='
        assert self.mgr.check_token(token) is True
        token = 'ZmFrZTpwYXNzd29yZA=='
        assert self.mgr.check_token(token) is False

    def test_generate_token(self):
        username = '******'
        password = '******'

        test_token = self.mgr.generate_token(username, password)
        real_token = 'aGFycnk6RXpla2llbDI1MTc='

        print(test_token)

        assert test_token == real_token
if __name__ == '__main__':
    if len(sys.argv) != 4:
        print "$ stream_tweets_main [destinationFolder] [credentials] [tagList]"
        quit()
    try:
        DATA_DIRECTORY = os.path.join(sys.argv[1])
        LOG_FILE_DIRECTORY = os.path.join(sys.argv[1], 'log')
        CREDENTIALS_FILE_PATH = os.path.join(sys.argv[2])
        TAG_FILE_PATH = os.path.join(sys.argv[3])
        if not os.path.exists(DATA_DIRECTORY):
            os.makedirs(DATA_DIRECTORY)
        if not os.path.exists(LOG_FILE_DIRECTORY):
            os.makedirs(LOG_FILE_DIRECTORY)

        auth_manager = AuthManager(CREDENTIALS_FILE_PATH)
        num_handlers = len(auth_manager.auth_handlers)
        tag_manager = TagManager(TAG_FILE_PATH, num_handlers)
        logger = Logger(LOG_FILE_DIRECTORY)

        for i in xrange(num_handlers):
            listener = CustomListener(i, DATA_DIRECTORY, sys.argv[0], logger)
            stream = CustomStream(listener, auth_manager.auth_handlers[i],
                                  tag_manager.distributed_tag_list[i])
            stream.stream(async=True)
    except IOError:
        print '{0} stopped running...'.format(sys.argv[0])
    except:
        logger.log(500, 0, 'Some run-time error has occurred. Restarting...')
        os.system('python {0} {1} {2} {3}'.format(sys.argv[0], sys.argv[1],
                                                  sys.argv[2], sys.argv[3]))
def main(args):
    CREDENTIALS_FILE_PATH = os.path.join(args.c)
    auth_manager = AuthManager(CREDENTIALS_FILE_PATH)
    TweetsCollector(args.i, args.o, auth_manager)
Ejemplo n.º 5
0
class NetworkExplorer(object):
    """
    This class will communicate with its assigned device in order to get
    the device's networking information such as its LLDP neighbors.
    """

    def __init__(self,
                 device,
                 parser,
                 ssh_timeout=DEFAULT_TIMEOUT,
                 ssh_max_bytes=DEFAULT_MAX_BYTES,
                 ssh_max_attempts=DEFAULT_MAX_ATTEMPTS):

        self.network_parser = None

        self.device = device
        self.hostname = device.system_name

        self.ssh_timeout = ssh_timeout
        self.ssh_max_bytes = ssh_max_bytes
        self.ssh_max_attempts = ssh_max_attempts

        self._auth_manager = AuthManager(parser)

    def explore_lldp(self, explored_devices, queue):
        """
        Explores a device using the LLDP protocol in order to add its
        valid neighbors in the queue.

        :param explored_devices: The dict of the devices already explored
        :type explored_devices: {str : Device}
        :param queue: The queue of the next devices to explore
        :type queue: Queue()
        """

        try:
            self._open_ssh_connection()
        except NoAuthRequested as e:
            logging.info("[%s] No auth requested", self.hostname)
            self.device.status = DeviceStatus.NO_AUTH_REQUESTED
            return
        except paramiko.AuthenticationException as pae:
            logging.error("[%s] Authentication failed: %s", self.hostname, pae)
            self.device.status = DeviceStatus.AUTH_FAILED
            return
        except Exception as e:
            logging.error("[%s] Could not open SSH connection: %s",
                          self.hostname, e)
            self.device.status = DeviceStatus.UNREACHABLE
            return
        finally:
            if self.device.mac_address:
                explored_devices[self.device.mac_address] = self.device

        # Determining the type of the current device from the switch banner
        banner = self._receive_ssh_output()
        self.network_parser = NetworkOutputParser.get_parser_type(banner)

        if self.network_parser is None:
            logging.warning(
                "[%s] Unsupported device type. Prompt was: %s",
                self.hostname, banner)
            return

        # Preparing the switch, such as removing pagination
        self._prepare_switch()

        # Building current device's informations if missing
        if self.device is None or self.device.mac_address is None:
            local_report = self._get_lldp_local_report()
            try:
                self.device = self.network_parser.\
                    parse_device_from_lldp_local_info(local_report)
                if not self.device.mac_address:
                    raise ValueError()
            except Exception as e:
                logging.error(
                    "[%s] Unable to parse lldp local report using %s: %s",
                    self.hostname,
                    self.network_parser.__class__.__name__,
                    e)
                return

        neighbors = self._build_lldp_neighbors()

        self._assign_vlans_to_interfaces()

        self._assign_trunks_to_device()

        self._assign_vms_to_device()

        self._close_ssh_connection()

        explored_devices[self.device.mac_address] = self.device

        for neighbor in neighbors:
            valid = neighbor.is_valid_lldp_device()
            explored = neighbor.mac_address in explored_devices

            if valid and not explored:
                explored_devices[neighbor.mac_address] = neighbor
                queue.put(neighbor)

    def _build_lldp_neighbors(self):
        """
        Obtain the list of all lldp neighbors
        """
        neighbors_result = self._get_lldp_neighbors()

        # With lldpd on Linux, the lldp summary already contains all details
        if self.network_parser.lldp_neighbors_detail_cmd is None:
            neighbors = self.network_parser\
                .parse_devices_from_lldp_remote_info(self.device,
                                                     neighbors_result)
            return neighbors

        self.device.interfaces = self.network_parser\
            .parse_interfaces_from_lldp_remote_info(neighbors_result)

        if len(self.device.interfaces) == 0:
            neighbors = []
            return neighbors

        lldp_neighbors_details = []
        for interface in self.device.interfaces.values():
            if interface.is_valid_lldp_interface():
                port = interface.local_port
                detail = self._get_lldp_neighbor_detail(port)
                lldp_neighbors_details.append(detail)

        neighbors = self.network_parser.parse_devices_from_lldp_remote_info(
            self.device, lldp_neighbors_details)

        return neighbors

    def _assign_vlans_to_interfaces(self):
        """
        Parse the vlans result and assign them to the interfaces.
        """
        vlans_result = self._get_vlans()

        if vlans_result is None:
            return

        vlans = self.network_parser.parse_vlans(vlans_result)

        # Some devices do not need to parse vlans from the global info and
        # can assign the vlans directly to interfaces from the first result
        if len(vlans) == 0:
            self.network_parser.associate_vlans_to_interfaces(
                self.device.interfaces, vlans_result)

        # Other devices need to get specific information from each vlan before
        # assigning it one by one to the interfaces
        for vlan in vlans.values():
            detail_str = self.network_parser.get_vlan_detail_str(vlan)
            specific_result = self._get_vlan_detail(detail_str)
            self.network_parser.associate_vlan_to_interfaces(
                self.device.interfaces, vlan, specific_result)

    def _assign_trunks_to_device(self):
        trunks_result = self._get_trunks()

        if trunks_result is None:
            return

        trunks = self.network_parser.parse_trunks(self.device.interfaces,
                                                  trunks_result)
        self.device.trunks = trunks

    def _assign_vms_to_device(self):
        vms_result = self._get_virtual_machines()

        if vms_result is None:
            return

        vms = self.network_parser.parse_vms_list(vms_result)

        self.device.virtual_machines = vms

    def _get_lldp_local_report(self):
        command = self.network_parser.lldp_local_cmd
        return self._send_ssh_command(command)

    def _get_lldp_neighbors(self):
        command = self.network_parser.lldp_neighbors_cmd
        return self._send_ssh_command(command)

    def _get_lldp_neighbor_detail(self, port):
        command = self.network_parser.lldp_neighbors_detail_cmd.format(port)
        return self._send_ssh_command(command)

    def _get_trunks(self):
        command = self.network_parser.trunks_list_cmd
        return self._send_ssh_command(command)

    def _get_vlans(self):
        command = self.network_parser.vlans_global_cmd
        return self._send_ssh_command(command)

    def _get_vlan_detail(self, vlan_id):
        command = self.network_parser.vlans_specific_cmd.format(vlan_id)
        return self._send_ssh_command(command)

    def _get_virtual_machines(self):
        command = self.network_parser.vms_list_cmd
        return self._send_ssh_command(command)

    def _open_ssh_connection(self):
        """
        Opens a SSH connection with the device
        """

        kwargs = self._auth_manager.get_params(self.hostname, self.device.type)

        kwargs.update({
            "hostname": self.hostname,
            "look_for_keys": False,
            "allow_agent": False,
            "timeout": self.ssh_timeout})

        nb_attempts = 0
        while nb_attempts <= 3:
            try:
                self.ssh = paramiko.SSHClient()
                self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                self.ssh.connect(**kwargs)
            except paramiko.AuthenticationException as pae:
                raise  # Do not retry if authentication failed
            except Exception as e:
                nb_attempts += 1
            else:
                break

        self.shell = self.ssh.invoke_shell()
        self.shell.set_combine_stderr(True)

        logging.info("[%s] SSH connection established", self.hostname)
        time.sleep(1)

    def _close_ssh_connection(self):
        """
        Closes the connection with the current device. That connection must
        have been opened beforehand.
        """
        try:
            self.shell.close()
            self.ssh.close()
            logging.debug("[%s] SSH connection closed", self.hostname)
        except Exception as e:
            logging.error("[%s] Could not close ssh connection: %s",
                          self.hostname, e)

    def _send_ssh_command(self, command):
        """
        Sends a command to the device in order to retrieve the output data.

        :param command: The command to execute (must end by a '\\n')
        :type command: str
        :return: Returns the (clean) result from the command's output
        :rtype: str
        """
        if command is None:
            return None

        try:
            logging.debug("[%s] Sending: %s", self.hostname, repr(command))
            self.shell.send(command)

            receive_buffer = ""
            wait_string = self.network_parser.wait_string
            length_when_mark_detected = 0
            empty_buffer_count = 0

            while True:
                temp_buffer = self._receive_ssh_output()
                receive_buffer += temp_buffer
                if not temp_buffer:
                    empty_buffer_count += 1
                else:
                    empty_buffer_count = 0

                if wait_string in receive_buffer[length_when_mark_detected:]:
                    length_when_mark_detected = len(receive_buffer)

                if length_when_mark_detected > 0 and empty_buffer_count == 3:
                    break

                time.sleep(0.1)

            logging.debug("[%s] Got response (len=%d)", self.hostname,
                          length_when_mark_detected)

            return receive_buffer

        except Exception as e:
            logging.warning("[%s] Could not send command '%s': %s",
                            self.hostname, command, e)

    def _receive_ssh_output(self):
        """
        Receives the raw output from the device after a command has been
        sent and cleans it before returning.

        :return: Returns the cleaned output of the device
        :rtype: str
        """
        if self.shell.recv_ready():
            raw_output = self.shell.recv(self.ssh_max_bytes)
            return self._remove_ansi_escape_codes(raw_output.decode('utf8'))
        else:
            return ""

    def _remove_ansi_escape_codes(self, string):
        """
        Cleans a string by removing all ANSI and VT100 escape characters
        using a regular expression.

        :param string: The string to clean
        :type string: str
        :return: Returns the cleaned string
        :rtype: str
        """
        expression = r"\[\d{1,2}\;\d{1,2}[a-zA-Z]?\d?|\[\??\d{1,2}[a-zA-Z]"
        ansi_escape = re.compile(expression)
        return ansi_escape.sub('', string.replace(u"\u001b", ""))

    def _prepare_switch(self):
        """
        Sends the preparation commands to the device such as pressing
        a key to skip the banner or as removing pagination.
        """
        for cmd in self.network_parser.preparation_cmds:
            time.sleep(0.5)
            self._send_ssh_command(cmd)
Ejemplo n.º 6
0
from flask import Flask, jsonify, request, abort, render_template
from database_connector import DatabaseConnector
from auth_manager import AuthManager
from accounts_manager import AccountsManager
from transactions_manager import TransactionsManager
import time


database_connector = DatabaseConnector()
auth_manager = AuthManager(database_connector)
accounts_manager = AccountsManager(database_connector)
transactions_manager = TransactionsManager(database_connector, accounts_manager)

app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0


@app.route('/auth', methods=['POST'])
def get_token():
    """
    HTTP POST /auth:
    {
        username: username,
        password: password
    }
    """
    if 'username' not in request.form or 'password' not in request.form:
        abort(400, 'Username or password missing from form-data. ')

    username = request.form['username']
    password = request.form['password']