From 2a7579bf86351bb16e20514c6086eb32c3ae81bc Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 10 Dec 2012 19:00:22 +0800 Subject: [PATCH] wall filter refactor --- .../java/com/alibaba/druid/sql/SQLUtils.java | 20 ++++--- .../alibaba/druid/wall/WallCheckResult.java | 29 ++++++++++ .../com/alibaba/druid/wall/WallConfig.java | 19 +++++++ .../com/alibaba/druid/wall/WallFilter.java | 47 ++++++++-------- .../alibaba/druid/wall/WallFilterMBean.java | 2 +- .../com/alibaba/druid/wall/WallProvider.java | 56 +++++++++++-------- 6 files changed, 120 insertions(+), 53 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/wall/WallCheckResult.java diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index 16af336f4a..f7413ba42c 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -145,14 +145,7 @@ public class SQLUtils { try { List statementList = toStatementList(sql, dbType); - StringBuilder out = new StringBuilder(); - SQLASTOutputVisitor visitor = createFormatOutputVisitor(out, statementList, dbType); - - for (SQLStatement stmt : statementList) { - stmt.accept(visitor); - } - - return out.toString(); + return toSQLString(statementList, dbType); } catch (SQLParseException ex) { LOG.warn("format error", ex); return sql; @@ -162,6 +155,17 @@ public class SQLUtils { } } + public static String toSQLString(List statementList, String dbType) { + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = createFormatOutputVisitor(out, statementList, dbType); + + for (SQLStatement stmt : statementList) { + stmt.accept(visitor); + } + + return out.toString(); + } + public static SQLASTOutputVisitor createFormatOutputVisitor(Appendable out, List statementList, String dbType) { if (JdbcUtils.ORACLE.equals(dbType) || JdbcUtils.ALI_ORACLE.equals(dbType)) { diff --git a/src/main/java/com/alibaba/druid/wall/WallCheckResult.java b/src/main/java/com/alibaba/druid/wall/WallCheckResult.java new file mode 100644 index 0000000000..858dabab76 --- /dev/null +++ b/src/main/java/com/alibaba/druid/wall/WallCheckResult.java @@ -0,0 +1,29 @@ +package com.alibaba.druid.wall; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLStatement; + +public class WallCheckResult { + + private final List violations = new ArrayList(2); + private final List statementList = new ArrayList(2); + + public WallCheckResult(){ + + } + + public WallCheckResult(Violation violation){ + this.violations.add(violation); + } + + public List getViolations() { + return violations; + } + + public List getStatementList() { + return statementList; + } + +} diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index 6b177d6a5c..d37b9324b5 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -71,10 +71,29 @@ public class WallConfig implements WallConfigMBean { private boolean inited; + private String guardTablePattern; + private String guardField; + public WallConfig(){ } + public String getGuardTablePattern() { + return guardTablePattern; + } + + public void setGuardTablePattern(String guardTablePattern) { + this.guardTablePattern = guardTablePattern; + } + + public String getGuardField() { + return guardField; + } + + public void setGuardField(String guardField) { + this.guardField = guardField; + } + public boolean isAllowDoPrivileged() { return allowDoPrivileged; } diff --git a/src/main/java/com/alibaba/druid/wall/WallFilter.java b/src/main/java/com/alibaba/druid/wall/WallFilter.java index c4dd49d413..8629e834ef 100644 --- a/src/main/java/com/alibaba/druid/wall/WallFilter.java +++ b/src/main/java/com/alibaba/druid/wall/WallFilter.java @@ -61,7 +61,7 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { this.dbType = JdbcUtils.getDbType(dataSource.getRawJdbcUrl(), ""); } } - + if (dbType == null) { dbType = JdbcUtils.getDbType(dataSource.getUrl(), null); } @@ -153,21 +153,21 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { @Override public void statement_addBatch(FilterChain chain, StatementProxy statement, String sql) throws SQLException { - check(sql); + sql = check(sql); chain.statement_addBatch(statement, sql); } @Override public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareStatement(connection, sql); } @Override public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql, int autoGeneratedKeys) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareStatement(connection, sql, autoGeneratedKeys); } @@ -175,7 +175,7 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareStatement(connection, sql, resultSetType, resultSetConcurrency); } @@ -183,7 +183,7 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareStatement(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability); } @@ -191,21 +191,21 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { @Override public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql, int[] columnIndexes) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareStatement(connection, sql, columnIndexes); } @Override public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql, String[] columnNames) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareStatement(connection, sql, columnNames); } @Override public CallableStatementProxy connection_prepareCall(FilterChain chain, ConnectionProxy connection, String sql) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareCall(connection, sql); } @@ -213,7 +213,7 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { public CallableStatementProxy connection_prepareCall(FilterChain chain, ConnectionProxy connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareCall(connection, sql, resultSetType, resultSetConcurrency); } @@ -221,7 +221,7 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { public CallableStatementProxy connection_prepareCall(FilterChain chain, ConnectionProxy connection, String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - check(sql); + sql = check(sql); return chain.connection_prepareCall(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability); } @@ -229,67 +229,68 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { @Override public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_execute(statement, sql); } @Override public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_execute(statement, sql, autoGeneratedKeys); } @Override public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, int columnIndexes[]) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_execute(statement, sql, columnIndexes); } @Override public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, String columnNames[]) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_execute(statement, sql, columnNames); } @Override public ResultSetProxy statement_executeQuery(FilterChain chain, StatementProxy statement, String sql) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_executeQuery(statement, sql); } @Override public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_executeUpdate(statement, sql); } @Override public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_executeUpdate(statement, sql, autoGeneratedKeys); } @Override public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int columnIndexes[]) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_executeUpdate(statement, sql, columnIndexes); } @Override public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, String columnNames[]) throws SQLException { - check(sql); + sql = check(sql); return chain.statement_executeUpdate(statement, sql, columnNames); } - public void check(String sql) throws SQLException { - List violations = provider.check(sql); + public String check(String sql) throws SQLException { + WallCheckResult checkResult = provider.check(sql); + List violations = checkResult.getViolations(); if (violations.size() > 0) { if (isLogViolation()) { @@ -305,6 +306,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { } } } + + return sql; } } diff --git a/src/main/java/com/alibaba/druid/wall/WallFilterMBean.java b/src/main/java/com/alibaba/druid/wall/WallFilterMBean.java index 3f75ab1f63..4e3ef49208 100644 --- a/src/main/java/com/alibaba/druid/wall/WallFilterMBean.java +++ b/src/main/java/com/alibaba/druid/wall/WallFilterMBean.java @@ -36,5 +36,5 @@ public interface WallFilterMBean { Set getProviderWhiteList(); - void check(String sql) throws SQLException; + String check(String sql) throws SQLException; } diff --git a/src/main/java/com/alibaba/druid/wall/WallProvider.java b/src/main/java/com/alibaba/druid/wall/WallProvider.java index 6e1c888fd2..e694bc8512 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProvider.java +++ b/src/main/java/com/alibaba/druid/wall/WallProvider.java @@ -16,11 +16,8 @@ package com.alibaba.druid.wall; import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.List; import java.util.Set; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -112,22 +109,24 @@ public abstract class WallProvider { public abstract SQLStatementParser createParser(String sql); public abstract WallVisitor createWallVisitor(); - + public abstract ExportParameterVisitor createExportParameterVisitor(); public boolean checkValid(String sql) { - return check(sql).size() == 0; + return check(sql).getViolations().isEmpty(); } - public List check(String sql) { + public WallCheckResult check(String sql) { + WallCheckResult result = new WallCheckResult(); + if (config.isAllowDoPrivileged() && privileged.get() == Boolean.TRUE) { - return Collections.emptyList(); + return result; } // first step, check whiteList boolean isWhite = whiteContains(sql); if (isWhite) { - return Collections.emptyList(); + return result; } SQLStatementParser parser = createParser(sql); @@ -136,34 +135,36 @@ public abstract class WallProvider { parser.getLexer().setAllowComment(false); // permit comment } - List statementList = new ArrayList(); - try { - parser.parseStatementList(statementList); + parser.parseStatementList(result.getStatementList()); } catch (Exception e) { - return Collections. singletonList(new SyntaxErrorViolation(e, sql)); + result.getViolations().add(new SyntaxErrorViolation(e, sql)); + return result; } if (parser.getLexer().token() != Token.EOF) { - return Collections. singletonList(new IllegalSQLObjectViolation(sql)); - } - - if (statementList.size() == 0) { - return Collections.emptyList(); + result.getViolations().add(new IllegalSQLObjectViolation(sql)); + return result; } - if (statementList.size() > 1 && !config.isMultiStatementAllow()) { - return Collections. singletonList(new IllegalSQLObjectViolation(sql)); + if (result.getStatementList().size() == 0) { + return result; } - SQLStatement stmt = statementList.get(0); + if (result.getStatementList().size() > 1 && !config.isMultiStatementAllow()) { + result.getViolations().add(new IllegalSQLObjectViolation(sql)); + return result; + } + + SQLStatement stmt = result.getStatementList().get(0); WallVisitor visitor = createWallVisitor(); try { stmt.accept(visitor); } catch (ParserException e) { - return Collections. singletonList(new IllegalSQLObjectViolation(sql)); + result.getViolations().add(new IllegalSQLObjectViolation(sql)); + return result; } if (visitor.getViolations().size() == 0) { @@ -172,7 +173,8 @@ public abstract class WallProvider { } } - return visitor.getViolations(); + result.getViolations().addAll(visitor.getViolations()); + return result; } public static T doPrivileged(PrivilegedAction action) { @@ -183,4 +185,14 @@ public abstract class WallProvider { privileged.set(null); } } + + private static final ThreadLocal guardValueLocal = new ThreadLocal(); + + public static void setGuardValue(Object value) { + guardValueLocal.set(value); + } + + public static Object getGuardValue() { + return guardValueLocal; + } }