コード例 #1
0
class RawLogParser:
    def __init__(self, args_dict):
        self.args_dict = args_dict
        self.logger = CustomLogger(self.args_dict)

    def parse(self, line):
        # This regex takes a raw log and parses it into a few elements
        # time, server, process, and arbitrary remainder
        pattern = r'^(\w+ +\d+ \d+:\d+:\d+) ([a-zA-Z0-9\.]+) (\w+\[\d+\]): conn=(\d+) (.*)$'
        match = re.search(pattern, line)

        if match:
            return {
                'time': match.group(1),
                'server': match.group(2),
                'process': match.group(3),
                'conn': match.group(4),
                'rest': match.group(5)
            }
        else:
            # raise Exception('Failed to parse raw line: {}'.format(line))
            if self.args_dict['verbose']:
                self.logger.log(
                    "ERROR: Failed to parse raw line: {}".format(line),
                    error=True)
            return None
コード例 #2
0
 def test_default_json(self, capsys):
     logger = CustomLogger(TEST_CUSTOM_LOGGER_ARGS_DICT)
     event = {"category": "ldap", "details": "abc's"}
     logger.log(event)
     out, err = capsys.readouterr()
     assert out == '{"category": "ldap", "details": "abc\'s"}\n'
     assert err == ""
コード例 #3
0
 def __init__(self, conn_id, args_dict):
     self.conn_id = conn_id
     self.time = ""
     self.server = ""
     self.process = ""
     self.operations = {}
     self.tls_status = False
     self.file_descriptors = []
     self.logger = CustomLogger(args_dict)
     self.authenticated_status = False
     self.user = ""
コード例 #4
0
    def test_file_with_existant_file(self):
        filename = "test_file_with_existant_file.txt"
        args_dict = {
            'output_stdout': False,
            'input_type': 'file',
            'output_file': True,
            'output_syslog': False,
            'host': '0.0.0.0',
            'daemonize': False,
            'input_file_name': None,
            'noconfig': False,
            'output_file_name': filename,
            'output_stderr': False,
            'config': 'humanizer_settings.json',
            'port': '1514',
            'syslog_facility': 'LOG_LOCAL5',
            'verbose': True
        }

        # Clean up to make sure we don't have an existing file
        try:
            os.remove(filename)
        except Exception as e:
            pass

        with open(filename, "w") as f:
            f.write('"hello world"\n')

        # Check to see if the content of the file is what we are expecting
        with open(filename) as f:
            s = f.read()
            assert s == '"hello world"\n'

        # Try to log to a file that does exist and make sure it creates it
        logger = CustomLogger(args_dict)
        assert os.path.isfile(filename) == True
        logger.log("hello world")
        assert os.path.isfile(filename) == True

        # Check to see if the content of the file is what we are expecting
        with open(filename) as f:
            s = f.read()
            assert s == '"hello world"\n"hello world"\n'

        # Clean up
        try:
            os.remove(filename)
        except Exception as e:
            pass
コード例 #5
0
    def __init__(self, args_dict):
        self.args_dict = args_dict
        if self.args_dict['host']:
            self.host = self.args_dict['host']
        if self.args_dict['port']:
            self.port = self.args_dict['port']
        self.logger = CustomLogger(self.args_dict)

        # Override a parser with appropriate args_dict optioned instance
        global syslog_server_parser
        syslog_server_parser = Parser(None, self.args_dict)
コード例 #6
0
    def test_stderr(self, capsys):
        args_dict = {
            'output_stdout': False,
            'output_stderr': True,
            'input_type': 'file',
            'output_file': False,
            'output_syslog': False,
            'host': '0.0.0.0',
            'daemonize': False,
            'input_file_name': None,
            'noconfig': False,
            'output_file_name': 'humanizer.log',
            'config': 'humanizer_settings.json',
            'port': '1514',
            'syslog_facility': 'LOG_LOCAL5'
        }

        logger = CustomLogger(args_dict)
        logger.log("hello world")
        out, err = capsys.readouterr()
        assert out == ""
        assert err == '"hello world"\n'
コード例 #7
0
 def test_file_with_no_file(self):
     args_dict = {
         'output_stdout': False,
         'input_type': 'file',
         'output_file': True,
         'output_syslog': False,
         'host': '0.0.0.0',
         'daemonize': False,
         'input_file_name': None,
         'noconfig': False,
         'output_file_name': None,
         'output_stderr': False,
         'config': 'humanizer_settings.json',
         'port': '1514',
         'syslog_facility': 'LOG_LOCAL5',
         'verbose': True
     }
     logger = CustomLogger(args_dict)
     with pytest.raises(Exception) as excinfo:
         logger.log("hello world")
     assert str(
         excinfo.value
     ) == 'log_type of "file" was chosen, but no log file specified'
コード例 #8
0
 def __init__(self, args_dict):
     self.args_dict = args_dict
     self.logger = CustomLogger(self.args_dict)
コード例 #9
0
class Connection:
    def __init__(self, conn_id, args_dict):
        self.conn_id = conn_id
        self.time = ""
        self.server = ""
        self.process = ""
        self.operations = {}
        self.tls_status = False
        self.file_descriptors = []
        self.logger = CustomLogger(args_dict)
        self.authenticated_status = False
        self.user = ""

    def dict(self):
        return {
            "conn_id": self.conn_id,
            "time": self.time,
            "client": self.client(),
            "server": self.server,
            "tls": self.tls(),
            "authenticated": self.authenticated(),
            "user": self.user
        }

    def reconstitute(self, event_dict):
        combined_dict = {}
        combined_dict.update(self.dict())
        combined_dict.update(event_dict)
        return combined_dict

    def authenticated(self):
        mail_regex = r'.*mail=([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)'
        uid_regex = r'.*uid=([a-zA-Z0-9._-]+)'

        # requirements: single operation where we have a BIND verb followed by an LDAP_SUCCESS
        for operation in self.operations.values():
            for request in operation.requests:
                if request.get("verb") == "BIND":
                    # Set user (even if they aren't authenticated, so we can track attempts)
                    for detail in request.get("details"):
                        mail_match_object = re.match(mail_regex, detail)
                        if mail_match_object:
                            self.user = mail_match_object.group(1)

                        uid_match_object = re.match(uid_regex, detail)
                        if uid_match_object:
                            self.user = uid_match_object.group(1)

                    # Set status if that user was successful
                    if operation.response_verb == "RESULT" and operation.error == "LDAP_SUCCESS":
                        self.authenticated_status = True

        return self.authenticated_status

    def tls(self):
        for file_descriptor in self.file_descriptors:
            if file_descriptor.verb == "TLS" and file_descriptor.details.startswith(
                    "established"):
                self.tls_status = True

        return self.tls_status

    def closed(self):
        for file_descriptor in self.file_descriptors:
            if file_descriptor.verb == "closed":
                return True

        return False

    def client(self):
        for file_descriptor in self.file_descriptors:
            if file_descriptor.verb == "ACCEPT":
                pattern = r'from IP=(\d+\.\d+\.\d+\.\d+):'
                match = re.search(pattern, file_descriptor.details)
                if match:
                    return match.group(1)

        return ""

    def add_operation(self, rest):
        # Expecting something like:
        # op=1 BIND dn="uid=bind-generateusers,ou=logins,dc=example" mech=SIMPLE ssf=0
        #
        pattern = r'^op=(\d+) (.*)$'
        match = re.search(pattern, rest)

        if match:
            op_id = match.group(1)
            operation = self.operations.get(int(op_id))

            # if an existing operation, update it's context
            if operation:
                operation.add_event(match.group(2))
            # if a new operation, add it to our operations list
            else:
                operation = Operation(int(op_id))
                operation.add_event(match.group(2))
                self.operations[int(op_id)] = operation

            if operation.loggable():
                self.logger.log(self.reconstitute(operation.dict()))
        else:
            raise Exception('Malformed operation: {}'.format(rest))

    def add_file_descriptor(self, rest):
        # Expecting something like:
        # fd=34 ACCEPT from IP=192.168.1.1:56822 (IP=0.0.0.0:389)
        #
        pattern = r'^fd=(\d+) (.*)$'
        match = re.search(pattern, rest)

        if match:
            file_descriptor = FileDescriptor(int(match.group(1)))
            file_descriptor.add_event(match.group(2))
            self.file_descriptors.append(file_descriptor)

            if file_descriptor.loggable():
                self.logger.log(self.reconstitute(file_descriptor.dict()))
        else:
            raise Exception('Malformed file file_descriptor: {}'.format(rest))

    # Something happened, this method's job is to update the context
    def add_event(self, event):
        self.time = event['time']
        self.server = event['server']
        self.process = event['process']
        self.add_rest(event['rest'])

    def add_rest(self, rest):
        if rest.startswith('op'):
            self.add_operation(rest)
        elif rest.startswith('fd'):
            self.add_file_descriptor(rest)
        else:
            raise Exception('Unsupported option: {}'.format(rest))
コード例 #10
0
 def test_stdout(self, capsys):
     logger = CustomLogger(TEST_CUSTOM_LOGGER_ARGS_DICT)
     logger.log("hello world")
     out, err = capsys.readouterr()
     assert out == '"hello world"\n'
     assert err == ""
コード例 #11
0
 def test_creation(self):
     logger = CustomLogger(TEST_CUSTOM_LOGGER_ARGS_DICT)
     assert isinstance(logger, CustomLogger)