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:
@ -76,7 +76,7 @@ type=service
|
||||
filters=Mask-SSN
|
||||
```
|
||||
|
||||
# Filter Parameter
|
||||
## Filter Parameters
|
||||
|
||||
The masking filter has one mandatory parameter - `rules_file`.
|
||||
|
||||
@ -90,6 +90,18 @@ MariaDB MaxScale.
|
||||
rules_file=/path/to/rules-file
|
||||
```
|
||||
|
||||
#### `warn_type_mismatch`
|
||||
|
||||
With this optional parameter the masking filter can be instructed to log
|
||||
a warning if a masking rule matches a column that is not of one of the
|
||||
allowed types.
|
||||
|
||||
The values that can be used are `never` and `always`, with `never` being
|
||||
the default.
|
||||
```
|
||||
warn_type_mismatch=always
|
||||
```
|
||||
|
||||
# Rules
|
||||
|
||||
The masking rules are expressed as a JSON object.
|
||||
|
@ -1,6 +1,7 @@
|
||||
if (JANSSON_FOUND)
|
||||
add_library(masking SHARED
|
||||
maskingfilter.cc
|
||||
maskingfilterconfig.cc
|
||||
maskingfiltersession.cc
|
||||
maskingrules.cc
|
||||
)
|
||||
|
@ -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,7 +92,10 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{"rules_file", MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED},
|
||||
{ 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())
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
|
||||
void reload(DCB* pOut);
|
||||
|
||||
const Config& config() const { return m_config; }
|
||||
SMaskingRules rules() const;
|
||||
|
||||
private:
|
||||
|
52
server/modules/filter/masking/maskingfilterconfig.cc
Normal file
52
server/modules/filter/masking/maskingfilterconfig.cc
Normal 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);
|
||||
}
|
@ -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; }
|
||||
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;
|
||||
warn_type_mismatch_t m_warn_type_mismatch;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
||||
|
@ -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; }
|
||||
|
Reference in New Issue
Block a user