Masking: Add parameter for warnings

The masking filter can now be instructed to warn in case a masking
rule matches a column of a type that is not masked.
This commit is contained in:
Johan Wikman
2017-01-11 15:08:25 +02:00
parent e79e82b0a9
commit 9a95e79dd6
10 changed files with 140 additions and 10 deletions

View File

@ -1,6 +1,7 @@
if (JANSSON_FOUND)
add_library(masking SHARED
maskingfilter.cc
maskingfilterconfig.cc
maskingfiltersession.cc
maskingrules.cc
)

View File

@ -77,6 +77,8 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
MXS_NOTICE("Masking module %s initialized.", VERSION_STRING);
typedef MaskingFilter::Config Config;
static MXS_MODULE info =
{
MXS_MODULE_API_FILTER,
@ -90,8 +92,11 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
NULL, /* Thread init. */
NULL, /* Thread finish. */
{
{"rules_file", MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED},
{MXS_END_MODULE_PARAMS}
{ Config::rules_file_name, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED },
{ Config::warn_type_mismatch_name,
MXS_MODULE_PARAM_ENUM, Config::warn_type_mismatch_default,
MXS_MODULE_OPT_NONE, Config::warn_type_mismatch_values },
{ MXS_END_MODULE_PARAMS }
}
};
@ -114,12 +119,15 @@ MaskingFilter::~MaskingFilter()
}
// static
MaskingFilter* MaskingFilter::create(const char* zName, char** pzOptions, CONFIG_PARAMETER* ppParams)
MaskingFilter* MaskingFilter::create(const char* zName, char** pzOptions, CONFIG_PARAMETER* pParams)
{
MaskingFilter* pFilter = NULL;
MaskingFilter::Config config(zName);
process_params(pzOptions, ppParams, config);
config.set_warn_type_mismatch(Config::get_warn_type_mismatch(pParams));
process_params(pzOptions, pParams, config);
auto_ptr<MaskingRules> sRules = MaskingRules::load(config.rules_file().c_str());
if (sRules.get())

View File

@ -39,6 +39,7 @@ public:
void reload(DCB* pOut);
const Config& config() const { return m_config; }
SMaskingRules rules() const;
private:

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
*
* Change Date: 2019-07-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include "maskingfilterconfig.hh"
namespace
{
const char config_name_rules_file[] = "rules_file";
const char config_name_warn_type_mismatch[] = "warn_type_mismatch";
const char config_value_never[] = "never";
const char config_value_always[] = "always";
}
//static
const char* MaskingFilterConfig::rules_file_name = config_name_rules_file;
//static
const char* MaskingFilterConfig::warn_type_mismatch_name = config_name_warn_type_mismatch;
//static
const MXS_ENUM_VALUE MaskingFilterConfig::warn_type_mismatch_values[] =
{
{ config_value_never, MaskingFilterConfig::WARN_NEVER },
{ config_value_always, MaskingFilterConfig::WARN_ALWAYS },
{ NULL }
};
//static
const char* MaskingFilterConfig::warn_type_mismatch_default = config_value_never;
//static
MaskingFilterConfig::warn_type_mismatch_t
MaskingFilterConfig::get_warn_type_mismatch(const CONFIG_PARAMETER* pParams)
{
int warn = config_get_enum(pParams, warn_type_mismatch_name, warn_type_mismatch_values);
return static_cast<warn_type_mismatch_t>(warn);
}

View File

@ -13,22 +13,42 @@
*/
#include <maxscale/cppdefs.hh>
#include <maxscale/config.h>
#include <maxscale/modinfo.h>
#include <string>
class MaskingFilterConfig
{
public:
enum warn_type_mismatch_t
{
WARN_NEVER,
WARN_ALWAYS
};
static const char* rules_file_name;
static const char* warn_type_mismatch_name;
static const MXS_ENUM_VALUE warn_type_mismatch_values[];
static const char* warn_type_mismatch_default;
MaskingFilterConfig(const char* zName)
: m_name(zName)
, m_warn_type_mismatch(WARN_NEVER)
{}
~MaskingFilterConfig() {}
const std::string& name() const { return m_name; }
const std::string& rules_file() const { return m_rules_file; }
const std::string& name() const { return m_name; }
const std::string& rules_file() const { return m_rules_file; }
warn_type_mismatch_t warn_type_mismatch() const { return m_warn_type_mismatch; }
void set_rules_file(const std::string& s) { m_rules_file = s; }
void set_warn_type_mismatch(warn_type_mismatch_t w) { m_warn_type_mismatch = w; }
static warn_type_mismatch_t get_warn_type_mismatch(const CONFIG_PARAMETER* pParams);
private:
std::string m_name;
std::string m_rules_file;
std::string m_name;
std::string m_rules_file;
warn_type_mismatch_t m_warn_type_mismatch;
};

View File

@ -178,6 +178,17 @@ void MaskingFilterSession::handle_eof(GWBUF* pPacket)
}
}
namespace
{
void warn_of_type_mismatch(const MaskingRules::Rule& rule)
{
MXS_WARNING("The rule targeting \"%s\" matches a column "
"that is not of string type.", rule.match().c_str());
}
}
void MaskingFilterSession::handle_row(GWBUF* pPacket)
{
MXS_NOTICE("handle_row");
@ -213,7 +224,10 @@ void MaskingFilterSession::handle_row(GWBUF* pPacket)
LEncString s = value.as_string();
pRule->rewrite(s);
}
else if (m_filter.config().warn_type_mismatch() == Config::WARN_ALWAYS)
{
warn_of_type_mismatch(*pRule);
}
}
++i;
}
@ -238,6 +252,10 @@ void MaskingFilterSession::handle_row(GWBUF* pPacket)
LEncString s = value.as_string();
pRule->rewrite(s);
}
else if (m_filter.config().warn_type_mismatch() == Config::WARN_ALWAYS)
{
warn_of_type_mismatch(*pRule);
}
}
++i;
}

View File

@ -20,10 +20,13 @@
#include "maskingrules.hh"
class MaskingFilter;
class MaskingFilterConfig;
class MaskingFilterSession : public maxscale::FilterSession
{
public:
typedef MaskingFilterConfig Config;
~MaskingFilterSession();
static MaskingFilterSession* create(SESSION* pSession, const MaskingFilter* pFilter);

View File

@ -614,6 +614,19 @@ auto_ptr<MaskingRules::Rule> MaskingRules::Rule::create_from(json_t* pRule)
return sRule;
}
string MaskingRules::Rule::match() const
{
string s;
s += m_database.empty() ? "*" : m_database;
s += ".";
s += m_table.empty() ? "*" : m_table;
s += ".";
s += m_column;
return s;
}
namespace
{

View File

@ -88,6 +88,8 @@ public:
const std::vector<SAccount>& exempted);
~Rule();
std::string match() const;
const std::string& column() const { return m_column; }
const std::string& table() const { return m_table; }
const std::string& database() const { return m_database; }