2019-12-09 11:44:51 +03:00
/*
* auditd - plugin - clickhouse is an auditd plugin for sending auditd data
* to clickhouse DB .
* Copyright ( C ) 2019 Aleksei Nikiforov < darktemplar @ basealt . ru >
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https : //www.gnu.org/licenses/>.
*
*/
# ifndef AUDITD_PLUGIN_CLICKHOUSE_RECORD_HPP
# define AUDITD_PLUGIN_CLICKHOUSE_RECORD_HPP
# include <memory>
# include <map>
# include <functional>
# include <string>
2019-12-11 17:16:28 +03:00
# include <list>
2019-12-09 11:44:51 +03:00
# include <stdint.h>
# include <boost/optional.hpp>
# include <auparse.h>
# include <libaudit.h>
# include <clickhouse-cpp/columns/column.h>
class AbstractRecordFieldFactory ;
class AbstractRecordField
{
public :
enum class Type
{
Int ,
String ,
2019-12-11 17:16:28 +03:00
InterpretedString ,
InterpretedStringArray
2019-12-09 11:44:51 +03:00
} ;
virtual ~ AbstractRecordField ( ) = default ;
2019-12-11 17:16:28 +03:00
virtual void addOrUpdateValue ( auparse_state_t * record ) = 0 ;
2019-12-09 12:19:58 +03:00
virtual void addToColumn ( const std : : vector < clickhouse : : ColumnRef > & columns ) const = 0 ;
2019-12-09 11:44:51 +03:00
virtual Type getType ( ) const = 0 ;
std : : string getName ( ) const { return m_name ; }
protected :
explicit AbstractRecordField ( const std : : string & name ) ;
AbstractRecordField ( const AbstractRecordField & other ) = default ;
AbstractRecordField & operator = ( const AbstractRecordField & other ) = default ;
std : : string m_name ;
friend class AbstractRecordFieldFactory ;
} ;
class AuditRecord
{
public :
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 :
2019-12-11 17:16:28 +03:00
std : : shared_ptr < AbstractRecordField > createFromAuditRecord ( const std : : string & field_name , auparse_type_t field_type ) ;
2019-12-09 11:44:51 +03:00
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 ;
2019-12-11 17:16:28 +03:00
std : : map < auparse_type_t , std : : function < std : : shared_ptr < AbstractRecordField > ( const std : : string & name ) > > m_factoryMap ;
2019-12-09 11:44:51 +03:00
} ;
class CommonStringRecordField : public AbstractRecordField
{
public :
2019-12-09 12:19:58 +03:00
virtual void addToColumn ( const std : : vector < clickhouse : : ColumnRef > & columns ) const override ;
2019-12-09 11:44:51 +03:00
protected :
explicit CommonStringRecordField ( const std : : string & name ) ;
boost : : optional < std : : string > m_value ;
} ;
class StringRecordField : public CommonStringRecordField
{
public :
2019-12-11 17:16:28 +03:00
static std : : shared_ptr < AbstractRecordField > createRecord ( const std : : string & name ) ;
2019-12-09 11:44:51 +03:00
2019-12-11 17:16:28 +03:00
virtual void addOrUpdateValue ( auparse_state_t * record ) override ;
2019-12-09 11:44:51 +03:00
virtual Type getType ( ) const override ;
protected :
2019-12-11 17:16:28 +03:00
explicit StringRecordField ( const std : : string & name ) ;
2019-12-09 11:44:51 +03:00
} ;
class InterpretedStringRecordField : public CommonStringRecordField
{
public :
2019-12-11 17:16:28 +03:00
static std : : shared_ptr < AbstractRecordField > createRecord ( const std : : string & name ) ;
2019-12-09 11:44:51 +03:00
2019-12-11 17:16:28 +03:00
virtual void addOrUpdateValue ( auparse_state_t * record ) override ;
2019-12-09 11:44:51 +03:00
virtual Type getType ( ) const override ;
protected :
2019-12-11 17:16:28 +03:00
explicit InterpretedStringRecordField ( const std : : string & name ) ;
2019-12-09 11:44:51 +03:00
} ;
2019-12-09 12:19:58 +03:00
class IntegerRecordField : public InterpretedStringRecordField
{
public :
2019-12-11 17:16:28 +03:00
static std : : shared_ptr < AbstractRecordField > createRecord ( const std : : string & name ) ;
2019-12-09 12:19:58 +03:00
2019-12-11 17:16:28 +03:00
virtual void addOrUpdateValue ( auparse_state_t * record ) override ;
2019-12-09 12:19:58 +03:00
virtual void addToColumn ( const std : : vector < clickhouse : : ColumnRef > & columns ) const override ;
virtual Type getType ( ) const override ;
protected :
2019-12-11 17:16:28 +03:00
explicit IntegerRecordField ( const std : : string & name ) ;
2019-12-09 12:19:58 +03:00
boost : : optional < int > m_int_value ;
} ;
2019-12-11 17:16:28 +03:00
class InterpretedStringArrayRecordField : public AbstractRecordField
{
public :
static std : : shared_ptr < AbstractRecordField > createRecord ( const std : : string & name ) ;
virtual void addOrUpdateValue ( auparse_state_t * record ) override ;
virtual void addToColumn ( const std : : vector < clickhouse : : ColumnRef > & columns ) const override ;
virtual Type getType ( ) const override ;
protected :
explicit InterpretedStringArrayRecordField ( const std : : string & name ) ;
std : : list < std : : string > m_value ;
} ;
2019-12-09 11:44:51 +03:00
# endif /* AUDITD_PLUGIN_CLICKHOUSE_RECORD_HPP */