WallFilter support postgres

This commit is contained in:
wenshao
2013-03-19 09:15:22 +08:00
parent c75c44e9ee
commit fc2f5efca3
7 changed files with 778 additions and 3 deletions
@@ -0,0 +1,87 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.dialect.postgresql.visitor;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils;
public class PGExportParameterVisitor extends PGASTVisitorAdapter implements ExportParameterVisitor {
private final List<Object> parameters;
public PGExportParameterVisitor() {
this(new ArrayList<Object>());
}
public PGExportParameterVisitor(List<Object> parameters){
this.parameters = parameters;
}
public List<Object> getParameters() {
return parameters;
}
@Override
public boolean visit(SQLSelectItem x) {
return false;
}
@Override
public boolean visit(SQLOrderBy x) {
return false;
}
@Override
public boolean visit(SQLSelectGroupByClause x) {
return false;
}
@Override
public boolean visit(SQLMethodInvokeExpr x) {
ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters());
return true;
}
@Override
public boolean visit(SQLInListExpr x) {
ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList());
return true;
}
@Override
public boolean visit(SQLBetweenExpr x) {
ExportParameterVisitorUtils.exportParameter(this.parameters, x);
return true;
}
public boolean visit(SQLBinaryOpExpr x) {
ExportParameterVisitorUtils.exportParameter(this.parameters, x);
return true;
}
}
@@ -45,7 +45,7 @@ public class WallConfig implements WallConfigMBean {
private boolean insertAllow = true;
private boolean mergeAllow = true;
private boolean minusAllow = false;
private boolean intersectAllow = false;
private boolean intersectAllow = false;
private boolean multiStatementAllow = false;
@@ -73,6 +73,10 @@ public class WallConfig implements WallConfigMBean {
protected final Set<String> denyVariants = new ConcurrentSkipListSet<String>();
protected final Set<String> denyObjects = new ConcurrentSkipListSet<String>();
protected final Set<String> permitFunctions = new ConcurrentSkipListSet<String>();
protected final Set<String> permitTables = new ConcurrentSkipListSet<String>();
protected final Set<String> permitSchemas = new ConcurrentSkipListSet<String>();
protected final Set<String> readOnlyTables = new ConcurrentSkipListSet<String>();
private String dir;
@@ -91,11 +95,11 @@ public class WallConfig implements WallConfigMBean {
public WallConfig(){
}
public boolean isIntersectAllow() {
return intersectAllow;
}
public void setIntersectAllow(boolean intersectAllow) {
this.intersectAllow = intersectAllow;
}
@@ -204,6 +208,10 @@ public class WallConfig implements WallConfigMBean {
loadResource(this.denyTables, dir + "/deny-table.txt");
loadResource(this.denyObjects, dir + "/deny-object.txt");
loadResource(this.readOnlyTables, dir + "/readonly-table.txt");
loadResource(this.permitFunctions, dir + "/permit-function.txt");
loadResource(this.permitTables, dir + "/permit-table.txt");
loadResource(this.permitSchemas, dir + "/permit-schema.txt");
}
public boolean isNoneBaseStatementAllow() {
@@ -444,6 +452,18 @@ public class WallConfig implements WallConfigMBean {
return this.readOnlyTables.contains(tableName);
}
public Set<String> getPermitFunctions() {
return permitFunctions;
}
public Set<String> getPermitTables() {
return permitTables;
}
public Set<String> getPermitSchemas() {
return permitSchemas;
}
public boolean isMustParameterized() {
return mustParameterized;
}
@@ -37,6 +37,7 @@ import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.wall.spi.MySqlWallProvider;
import com.alibaba.druid.wall.spi.OracleWallProvider;
import com.alibaba.druid.wall.spi.PGWallProvider;
import com.alibaba.druid.wall.spi.SQLServerWallProvider;
import com.alibaba.druid.wall.violation.SyntaxErrorViolation;
@@ -90,6 +91,12 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
}
provider = new SQLServerWallProvider(config);
} else if (JdbcUtils.POSTGRESQL.equals(dbType)) {
if (config == null) {
config = new WallConfig(PGWallProvider.DEFAULT_CONFIG_DIR);
}
provider = new PGWallProvider(config);
} else {
throw new IllegalStateException("dbType not support : " + dbType + ", url " + dataSource.getUrl());
}
@@ -0,0 +1,55 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.wall.spi;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGExportParameterVisitor;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallVisitor;
public class PGWallProvider extends WallProvider {
public final static String DEFAULT_CONFIG_DIR = "META-INF/druid/wall/postgres";
public PGWallProvider(){
this(new WallConfig(DEFAULT_CONFIG_DIR));
}
public PGWallProvider(WallConfig config){
super(config, JdbcConstants.POSTGRESQL);
}
@Override
public SQLStatementParser createParser(String sql) {
return new PGSQLStatementParser(sql);
}
@Override
public WallVisitor createWallVisitor() {
return new PGWallVisitor(this);
}
@Override
public ExportParameterVisitor createExportParameterVisitor() {
return new PGExportParameterVisitor();
}
}
@@ -0,0 +1,228 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.wall.spi;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitorAdapter;
import com.alibaba.druid.wall.Violation;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallVisitor;
import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;
public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor {
private final WallConfig config;
private final WallProvider provider;
private final List<Violation> violations = new ArrayList<Violation>();
public PGWallVisitor(WallProvider provider){
this.config = provider.getConfig();
this.provider = provider;
}
public WallProvider getProvider() {
return provider;
}
public WallConfig getConfig() {
return config;
}
public void addViolation(Violation violation) {
this.violations.add(violation);
}
public List<Violation> getViolations() {
return violations;
}
public boolean visit(SQLIdentifierExpr x) {
String name = x.getName();
name = WallVisitorUtils.form(name);
if (config.isVariantCheck() && config.getDenyVariants().contains(name)) {
getViolations().add(new IllegalSQLObjectViolation(toSQL(x)));
}
return true;
}
public boolean visit(SQLPropertyExpr x) {
WallVisitorUtils.check(this, x);
return true;
}
public boolean visit(SQLInListExpr x) {
WallVisitorUtils.check(this, x);
return true;
}
public boolean visit(SQLBinaryOpExpr x) {
WallVisitorUtils.check(this, x);
return true;
}
@Override
public boolean visit(SQLMethodInvokeExpr x) {
WallVisitorUtils.checkFunction(this, x);
return true;
}
public boolean visit(OracleSelectTableReference x) {
return WallVisitorUtils.check(this, x);
}
public boolean visit(SQLExprTableSource x) {
WallVisitorUtils.check(this, x);
if (x.getExpr() instanceof SQLName) {
return false;
}
return true;
}
public boolean visit(SQLSelectGroupByClause x) {
WallVisitorUtils.checkHaving(this, x.getHaving());
return true;
}
@Override
public boolean visit(SQLSelectQueryBlock x) {
WallVisitorUtils.checkSelelct(this, x);
return true;
}
@Override
public boolean visit(SQLUnionQuery x) {
WallVisitorUtils.checkUnion(this, x);
return true;
}
@Override
public String toSQL(SQLObject obj) {
return SQLUtils.toOracleString(obj);
}
@Override
public boolean isDenyTable(String name) {
if (!config.isTableCheck()) {
return false;
}
name = WallVisitorUtils.form(name);
if (name.startsWith("v$") || name.startsWith("v_$")) {
return true;
}
return !this.provider.checkDenyTable(name);
}
public void preVisit(SQLObject x) {
if (!(x instanceof SQLStatement)) {
return;
}
if (config.isNoneBaseStatementAllow()) {
return;
}
boolean allow = false;
if (x instanceof SQLInsertStatement) {
allow = true;
} else if (x instanceof SQLSelectStatement) {
allow = true;
} else if (x instanceof SQLDeleteStatement) {
allow = true;
} else if (x instanceof SQLUpdateStatement) {
allow = true;
} else if (x instanceof OracleMultiInsertStatement) {
allow = true;
} else if (x instanceof OracleMergeStatement) {
allow = true;
} else if (x instanceof SQLCallStatement) {
allow = true;
} else if (x instanceof SQLTruncateStatement) {
allow = config.isTruncateAllow();
}
if (!allow) {
violations.add(new IllegalSQLObjectViolation(toSQL(x)));
}
}
@Override
public boolean visit(SQLSelectStatement x) {
if (!config.isSelelctAllow()) {
this.getViolations().add(new IllegalSQLObjectViolation(this.toSQL(x)));
return false;
}
return true;
}
@Override
public boolean visit(SQLInsertStatement x) {
WallVisitorUtils.checkInsert(this, x);
return true;
}
@Override
public boolean visit(SQLDeleteStatement x) {
WallVisitorUtils.checkDelete(this, x);
return true;
}
@Override
public boolean visit(SQLUpdateStatement x) {
WallVisitorUtils.checkUpdate(this, x);
return true;
}
@Override
public boolean visit(SQLSelectItem x) {
WallVisitorUtils.check(this, x);
return true;
}
}
@@ -0,0 +1,219 @@
abs
acos
adddate
addtime
aes_decrypt
aes_encrypt
ascii
asin
atan
atan2
avg
bin
binary
bit_and
bit_count
bit_length
bit_or
bit_xor
cast
ceil
ceiling
char_length
char
character_length
charset
coalesce
coercibility
collation
compress
concat_ws
concat
conv
convert_tz
convert
cos
cot
count(distinct)
count
crc32
curdate
current_date
current_time
current_timestamp
curtime
date_add
date_format
date_sub
date
datediff
day
dayname
dayofmonth
dayofweek
dayofyear
decode
default
degrees
des_decrypt
des_encrypt
div
elt
encode
encrypt
exp
export_set
extract
extractvalue
field
find_in_set
floor
format
found_rows
from_base64
from_days
from_unixtime
get_format
greatest
group_concat
gtid_subset
gtid_subtract
hex
hour
if
ifnull
inet_aton
inet_ntoa
inet6_aton
inet6_ntoa
insert
instr
interval
is_free_lock
is_ipv4_compat
is_ipv4_mapped
is_ipv4
is_ipv6
is_used_lock
last_day
last_insert_id
lcase
least
left
length
ln
localtime
localtimestamp
locate
log10
log2
log
lower
lpad
ltrim
make_set
makedate
maketime
master_pos_wait
match
max
md5
microsecond
mid
min
minute
mod
month
monthname
name_const
not
now
nullif
oct
octet_length
old_password
ord
password
period_add
period_diff
pi
position
pow
power
procedure
quarter
quote
radians
rand
regexp
release_lock
repeat
replace
reverse
right
rlike
round
row_count
rpad
rtrim
sec_to_time
second
sha1
sha2
sign
sin
sleep
soundex
sounds
space
sqrt
std
stddev_pop
stddev_samp
stddev
str_to_date
strcmp
subdate
substr
substring_index
substring
subtime
sum
sysdate
tan
time_format
time_to_sec
time
timediff
timestamp
timestampadd
timestampdiff
to_base64
to_days
to_seconds
trim
truncate
ucase
uncompress
uncompressed_length
unhex
unix_timestamp
updatexml
upper
utc_date
utc_time
utc_timestamp
uuid_short
uuid
validate_password_strength
values
var_pop
var_samp
variance
wait_until_sql_thread_after_gtids
week
weekday
weekofyear
weight_string
year
yearweek
@@ -0,0 +1,159 @@
abs
acos
asin
atan
atan2
bitand
ceil
cos
cosh
exp
floor
ln
log
mod
nanvl
power
remainder
round
sign
sin
sinh
sqrt
tan
tanh
trunc
width_bucket
CHR
CONCAT
INITCAP
LOWER
LPAD
LTRIM
NLS_INITCAP
NLS_LOWER
NLSSORT
NLS_UPPER
REGEXP_REPLACE
REGEXP_SUBSTR
REPLACE
RPAD
RTRIM
SOUNDEX
SUBSTR
TRANSLATE
TREAT
TRIM
UPPER
NLS_CHARSET_DECL_LEN
NLS_CHARSET_ID
NLS_CHARSET_NAME
ASCII
INSTR
LENGTH
REGEXP_INSTR
ADD_MONTHS
CURRENT_DATE
CURRENT_TIMESTAMP
DBTIMEZONE
EXTRACT
FROM_TZ
LAST_DAY
LOCALTIMESTAMP
MONTHS_BETWEEN
NEW_TIME
NEXT_DAY
NUMTODSINTERVAL
NUMTOYMINTERVAL
ROUND
SESSIONTIMEZONE
SYS_EXTRACT_UTC
SYSDATE
SYSTIMESTAMP
TO_CHAR
TO_TIMESTAMP
TO_TIMESTAMP_TZ
TO_DSINTERVAL
TO_YMINTERVAL
TRUNC
TZ_OFFSET
GREATEST
LEAST
ASCIISTR
BIN_TO_NUM
CAST
CHARTOROWID
COMPOSE
CONVERT
DECOMPOSE
HEXTORAW
NUMTODSINTERVAL
NUMTOYMINTERVAL
RAWTOHEX
RAWTONHEX
ROWIDTOCHAR
ROWIDTONCHAR
SCN_TO_TIMESTAMP
TIMESTAMP_TO_SCN
TO_BINARY_DOUBLE
TO_BINARY_FLOAT
TO_CHAR
TO_CLOB
TO_DATE
TO_DSINTERVAL
TO_LOB
TO_MULTI_BYTE
TO_NCHAR
TO_NCLOB
TO_NUMBER
TO_DSINTERVAL
TO_SINGLE_BYTE
TO_TIMESTAMP
TO_TIMESTAMP_TZ
TO_YMINTERVAL
TO_YMINTERVAL
TRANSLATE
UNISTR
BFILENAME
EMPTY_BLOB
EMPTY_CLOB
CARDINALITY
COLLECT
POWERMULTISET
POWERMULTISET_BY_CARDINALITY
SET
SYS_CONNECT_BY_PATH
CLUSTER_ID
CLUSTER_PROBABILITY
CLUSTER_SET
FEATURE_ID
FEATURE_SET
FEATURE_VALUE
PREDICTION
PREDICTION_BOUNDS
PREDICTION_COST
PREDICTION_DETAILS
PREDICTION_PROBABILITY
PREDICTION_SET
DECODE
DUMP
ORA_HASH
VSIZE
COALESCE
LNNVL
NULLIF
NVL
NVL2