Rework code for type match checking

This commit is contained in:
Aleksei Nikiforov 2019-12-12 15:01:59 +03:00
parent 4de04f70b9
commit 0aca43be6f
2 changed files with 102 additions and 95 deletions

View File

@ -20,78 +20,116 @@
#include "auditd-record.hpp"
#include <functional>
#include <set>
#include <clickhouse-cpp/columns/array.h>
#include <clickhouse-cpp/columns/nullable.h>
#include <clickhouse-cpp/columns/numeric.h>
#include <clickhouse-cpp/columns/string.h>
#define register_record_type(audit_type, record_type) \
static const AbstractRecordFieldFactory::AuditRecordFieldRegister<record_type> record_register_##audit_type(audit_type)
namespace {
register_record_type(AUPARSE_TYPE_UNCLASSIFIED, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_UID, IntegerRecordField);
register_record_type(AUPARSE_TYPE_GID, IntegerRecordField);
register_record_type(AUPARSE_TYPE_SYSCALL, IntegerRecordField);
register_record_type(AUPARSE_TYPE_ARCH, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_EXIT, IntegerRecordField);
register_record_type(AUPARSE_TYPE_ESCAPED, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_PERM, IntegerRecordField);
register_record_type(AUPARSE_TYPE_MODE, IntegerRecordField);
register_record_type(AUPARSE_TYPE_SOCKADDR, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_FLAGS, IntegerRecordField);
register_record_type(AUPARSE_TYPE_PROMISC, IntegerRecordField);
register_record_type(AUPARSE_TYPE_CAPABILITY, IntegerRecordField);
register_record_type(AUPARSE_TYPE_SUCCESS, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_A0, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_A1, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_A2, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_A3, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_SIGNAL, IntegerRecordField);
register_record_type(AUPARSE_TYPE_LIST, IntegerRecordField);
register_record_type(AUPARSE_TYPE_TTY_DATA, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_SESSION, IntegerRecordField);
register_record_type(AUPARSE_TYPE_CAP_BITMAP, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_NFPROTO, IntegerRecordField);
register_record_type(AUPARSE_TYPE_ICMPTYPE, IntegerRecordField);
register_record_type(AUPARSE_TYPE_PROTOCOL, IntegerRecordField);
register_record_type(AUPARSE_TYPE_ADDR, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_PERSONALITY, IntegerRecordField);
register_record_type(AUPARSE_TYPE_SECCOMP, IntegerRecordField);
register_record_type(AUPARSE_TYPE_OFLAG, IntegerRecordField);
register_record_type(AUPARSE_TYPE_MMAP, IntegerRecordField);
register_record_type(AUPARSE_TYPE_MODE_SHORT, IntegerRecordField);
register_record_type(AUPARSE_TYPE_MAC_LABEL, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_PROCTITLE, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_HOOK, IntegerRecordField);
register_record_type(AUPARSE_TYPE_NETACTION, IntegerRecordField);
register_record_type(AUPARSE_TYPE_MACPROTO, IntegerRecordField);
register_record_type(AUPARSE_TYPE_IOCTL_REQ, IntegerRecordField);
register_record_type(AUPARSE_TYPE_ESCAPED_KEY, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_ESCAPED_FILE, InterpretedStringRecordField);
register_record_type(AUPARSE_TYPE_FANOTIFY, InterpretedStringRecordField);
#undef register_record_type
AbstractRecordFieldFactory& AbstractRecordFieldFactory::instance()
std::map<auparse_type_t, std::function<bool(const std::string &)> >& get_audit_type_check_instance()
{
static AbstractRecordFieldFactory instance;
static std::map<auparse_type_t, std::function<bool(const std::string &)> > instance;
return instance;
}
std::shared_ptr<AbstractRecordField> AbstractRecordFieldFactory::createFromAuditRecord(const std::string &field_name, auparse_type_t field_type)
class AuditTypeCheckRegister
{
AbstractRecordFieldFactory &inst = instance();
auto record_type_factory = inst.m_factoryMap.find(field_type);
if ((record_type_factory != inst.m_factoryMap.end()) && (record_type_factory->second))
public:
AuditTypeCheckRegister(auparse_type_t type, const std::function<bool(const std::string &)> &func)
{
return record_type_factory->second(field_name);
get_audit_type_check_instance()[type] = func;
}
};
std::function<bool(const std::string &)> integer_record_type_check_function()
{
return [](const std::string &value) -> bool {
std::set<std::string> allowed_values = {
"integer"
};
return (allowed_values.find(value) != allowed_values.end());
};
}
std::function<bool(const std::string &)> interpreted_string_record_type_check_function()
{
return [](const std::string &value) -> bool {
std::set<std::string> allowed_values = {
"string",
"string_array"
};
return (allowed_values.find(value) != allowed_values.end());
};
}
} // unnamed namespace
#define register_record_type(audit_type, check_function) \
static const AuditTypeCheckRegister audit_type_check_register_##audit_type(audit_type, check_function)
register_record_type(AUPARSE_TYPE_UNCLASSIFIED, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_UID, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_GID, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_SYSCALL, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_ARCH, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_EXIT, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_ESCAPED, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_PERM, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_MODE, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_SOCKADDR, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_FLAGS, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_PROMISC, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_CAPABILITY, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_SUCCESS, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_A0, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_A1, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_A2, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_A3, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_SIGNAL, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_LIST, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_TTY_DATA, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_SESSION, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_CAP_BITMAP, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_NFPROTO, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_ICMPTYPE, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_PROTOCOL, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_ADDR, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_PERSONALITY, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_SECCOMP, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_OFLAG, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_MMAP, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_MODE_SHORT, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_MAC_LABEL, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_PROCTITLE, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_HOOK, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_NETACTION, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_MACPROTO, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_IOCTL_REQ, integer_record_type_check_function());
register_record_type(AUPARSE_TYPE_ESCAPED_KEY, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_ESCAPED_FILE, interpreted_string_record_type_check_function());
register_record_type(AUPARSE_TYPE_FANOTIFY, interpreted_string_record_type_check_function());
#undef register_record_type
bool check_field_type(auparse_type_t field_type, const std::string &database_type, const std::string &database_field_name)
{
const auto &check_instance = get_audit_type_check_instance();
auto check_type_function = check_instance.find(field_type);
if (check_type_function != check_instance.end())
{
return check_type_function->second(database_type);
}
else
{
// fallback to string
fprintf(stderr, "Warning: unknown record type for record name \"%s\"\n", field_name.c_str());
return InterpretedStringRecordField::createRecord(field_name);
fprintf(stderr, "Warning: unknown record type for record name \"%s\"\n", database_field_name.c_str());
return interpreted_string_record_type_check_function()(database_type);
}
}

View File

@ -36,7 +36,7 @@
#include <clickhouse-cpp/columns/column.h>
class AbstractRecordFieldFactory;
bool check_field_type(auparse_type_t field_type, const std::string &database_type, const std::string &database_field_name);
class AbstractRecordField
{
@ -63,47 +63,16 @@ protected:
AbstractRecordField& operator=(const AbstractRecordField &other) = default;
std::string m_name;
friend class AbstractRecordFieldFactory;
};
class AuditRecord
struct AuditRecord
{
public:
time_t time;
uint64_t milliseconds;
uint64_t serial;
std::string node; // skip processing node from record fields
private:
time_t m_seconds;
uint64_t m_milliseconds;
uint64_t m_serial;
std::string m_node; // skip processing node from record fields
std::map<std::string, std::shared_ptr<AbstractRecordField> > m_fields;
};
class AbstractRecordFieldFactory
{
public:
std::shared_ptr<AbstractRecordField> createFromAuditRecord(const std::string &field_name, auparse_type_t field_type);
static AbstractRecordFieldFactory& instance();
template <typename RecordFieldType>
class AuditRecordFieldRegister
{
public:
explicit AuditRecordFieldRegister(auparse_type_t type)
{
AbstractRecordFieldFactory::instance().m_factoryMap[type] = &RecordFieldType::createRecord;
}
};
protected:
AbstractRecordFieldFactory() = default;
AbstractRecordFieldFactory(const AbstractRecordFieldFactory &other) = delete;
AbstractRecordFieldFactory& operator=(const AbstractRecordFieldFactory &other) = delete;
std::map<auparse_type_t, std::function<std::shared_ptr<AbstractRecordField>(const std::string &name)> > m_factoryMap;
std::map<std::string, std::shared_ptr<AbstractRecordField> > fields;
};
class CommonStringRecordField: public AbstractRecordField