sqreen 0.7.01461158029-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +22 -0
- data/README.md +77 -0
- data/Rakefile +40 -0
- data/lib/sqreen.rb +67 -0
- data/lib/sqreen/binding_accessor.rb +184 -0
- data/lib/sqreen/ca.crt +72 -0
- data/lib/sqreen/callback_tree.rb +78 -0
- data/lib/sqreen/callbacks.rb +120 -0
- data/lib/sqreen/capped_queue.rb +23 -0
- data/lib/sqreen/condition_evaluator.rb +169 -0
- data/lib/sqreen/conditionable.rb +50 -0
- data/lib/sqreen/configuration.rb +151 -0
- data/lib/sqreen/context.rb +22 -0
- data/lib/sqreen/deliveries/batch.rb +80 -0
- data/lib/sqreen/deliveries/simple.rb +36 -0
- data/lib/sqreen/detect.rb +14 -0
- data/lib/sqreen/detect/shell_injection.rb +61 -0
- data/lib/sqreen/detect/sql_injection.rb +115 -0
- data/lib/sqreen/event.rb +16 -0
- data/lib/sqreen/events/attack.rb +60 -0
- data/lib/sqreen/events/remote_exception.rb +53 -0
- data/lib/sqreen/exception.rb +31 -0
- data/lib/sqreen/frameworks.rb +40 -0
- data/lib/sqreen/frameworks/generic.rb +243 -0
- data/lib/sqreen/frameworks/rails.rb +155 -0
- data/lib/sqreen/frameworks/rails3.rb +36 -0
- data/lib/sqreen/frameworks/sinatra.rb +34 -0
- data/lib/sqreen/frameworks/sqreen_test.rb +26 -0
- data/lib/sqreen/instrumentation.rb +504 -0
- data/lib/sqreen/log.rb +116 -0
- data/lib/sqreen/metrics.rb +6 -0
- data/lib/sqreen/metrics/average.rb +39 -0
- data/lib/sqreen/metrics/base.rb +41 -0
- data/lib/sqreen/metrics/collect.rb +22 -0
- data/lib/sqreen/metrics/sum.rb +20 -0
- data/lib/sqreen/metrics_store.rb +94 -0
- data/lib/sqreen/parsers/sql.rb +98 -0
- data/lib/sqreen/parsers/sql_tokenizer.rb +266 -0
- data/lib/sqreen/parsers/unix.rb +110 -0
- data/lib/sqreen/payload_creator.rb +132 -0
- data/lib/sqreen/performance_notifications.rb +86 -0
- data/lib/sqreen/performance_notifications/log.rb +36 -0
- data/lib/sqreen/performance_notifications/metrics.rb +36 -0
- data/lib/sqreen/performance_notifications/newrelic.rb +36 -0
- data/lib/sqreen/remote_command.rb +82 -0
- data/lib/sqreen/rule_attributes.rb +25 -0
- data/lib/sqreen/rule_callback.rb +97 -0
- data/lib/sqreen/rules.rb +116 -0
- data/lib/sqreen/rules_callbacks.rb +29 -0
- data/lib/sqreen/rules_callbacks/binding_accessor_metrics.rb +79 -0
- data/lib/sqreen/rules_callbacks/count_http_codes.rb +18 -0
- data/lib/sqreen/rules_callbacks/crawler_user_agent_matches.rb +24 -0
- data/lib/sqreen/rules_callbacks/crawler_user_agent_matches_metrics.rb +25 -0
- data/lib/sqreen/rules_callbacks/execjs.rb +136 -0
- data/lib/sqreen/rules_callbacks/headers_insert.rb +20 -0
- data/lib/sqreen/rules_callbacks/inspect_rule.rb +20 -0
- data/lib/sqreen/rules_callbacks/matcher_rule.rb +103 -0
- data/lib/sqreen/rules_callbacks/rails_parameters.rb +14 -0
- data/lib/sqreen/rules_callbacks/record_request_context.rb +23 -0
- data/lib/sqreen/rules_callbacks/reflected_xss.rb +40 -0
- data/lib/sqreen/rules_callbacks/regexp_rule.rb +36 -0
- data/lib/sqreen/rules_callbacks/shell.rb +33 -0
- data/lib/sqreen/rules_callbacks/shell_env.rb +32 -0
- data/lib/sqreen/rules_callbacks/sql.rb +41 -0
- data/lib/sqreen/rules_callbacks/system_shell.rb +25 -0
- data/lib/sqreen/rules_callbacks/url_matches.rb +25 -0
- data/lib/sqreen/rules_callbacks/user_agent_matches.rb +22 -0
- data/lib/sqreen/rules_signature.rb +142 -0
- data/lib/sqreen/runner.rb +312 -0
- data/lib/sqreen/runtime_infos.rb +127 -0
- data/lib/sqreen/session.rb +340 -0
- data/lib/sqreen/stats.rb +18 -0
- data/lib/sqreen/version.rb +6 -0
- metadata +143 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rules_callbacks/regexp_rule'
|
5
|
+
require 'sqreen/rules_callbacks/matcher_rule'
|
6
|
+
|
7
|
+
require 'sqreen/rules_callbacks/record_request_context'
|
8
|
+
require 'sqreen/rules_callbacks/rails_parameters'
|
9
|
+
|
10
|
+
require 'sqreen/rules_callbacks/headers_insert'
|
11
|
+
|
12
|
+
require 'sqreen/rules_callbacks/inspect_rule'
|
13
|
+
|
14
|
+
require 'sqreen/rules_callbacks/shell'
|
15
|
+
require 'sqreen/rules_callbacks/system_shell'
|
16
|
+
require 'sqreen/rules_callbacks/shell_env'
|
17
|
+
|
18
|
+
require 'sqreen/rules_callbacks/sql'
|
19
|
+
|
20
|
+
require 'sqreen/rules_callbacks/url_matches'
|
21
|
+
require 'sqreen/rules_callbacks/user_agent_matches'
|
22
|
+
require 'sqreen/rules_callbacks/crawler_user_agent_matches'
|
23
|
+
|
24
|
+
require 'sqreen/rules_callbacks/reflected_xss'
|
25
|
+
require 'sqreen/rules_callbacks/execjs'
|
26
|
+
|
27
|
+
require 'sqreen/rules_callbacks/binding_accessor_metrics'
|
28
|
+
require 'sqreen/rules_callbacks/count_http_codes'
|
29
|
+
require 'sqreen/rules_callbacks/crawler_user_agent_matches_metrics'
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
require 'sqreen/binding_accessor'
|
6
|
+
require 'sqreen/events/remote_exception'
|
7
|
+
|
8
|
+
module Sqreen
|
9
|
+
module Rules
|
10
|
+
# Publish metrics about data taken from the binding accessor
|
11
|
+
class BindingAccessorMetrics < RuleCB
|
12
|
+
# Exception thrown when no expression are present
|
13
|
+
class NoExpressions < Sqreen::Exception
|
14
|
+
def initialize(expr)
|
15
|
+
super("No valid expressions defined in #{expr.inspect}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(klass, method, rule_hash)
|
20
|
+
super(klass, method, rule_hash)
|
21
|
+
@expr = {}
|
22
|
+
build_expressions(rule_hash[Attrs::CALLBACKS])
|
23
|
+
end
|
24
|
+
|
25
|
+
PRE_CB = 'pre'.freeze
|
26
|
+
POST_CB = 'post'.freeze
|
27
|
+
FAILING_CB = 'failing'.freeze
|
28
|
+
|
29
|
+
def pre?
|
30
|
+
@expr[PRE_CB]
|
31
|
+
end
|
32
|
+
|
33
|
+
def post?
|
34
|
+
@expr[POST_CB]
|
35
|
+
end
|
36
|
+
|
37
|
+
def failing?
|
38
|
+
@expr[FAILING_CB]
|
39
|
+
end
|
40
|
+
|
41
|
+
def pre(inst, *args, &_block)
|
42
|
+
return unless pre?
|
43
|
+
|
44
|
+
add_metrics(PRE_CB, inst, args)
|
45
|
+
end
|
46
|
+
|
47
|
+
def post(rv, inst, *args, &_block)
|
48
|
+
return unless post?
|
49
|
+
|
50
|
+
add_metrics(POST_CB, inst, args, rv)
|
51
|
+
end
|
52
|
+
|
53
|
+
def failing(exception, inst, *args, &_block)
|
54
|
+
return unless failing?
|
55
|
+
|
56
|
+
add_metrics(FAILING_CB, inst, args, exception)
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def add_metrics(name, inst, args, rv = nil)
|
62
|
+
category, key, value, = @expr[name].map do |accessor|
|
63
|
+
accessor.resolve(binding, framework, inst, args, @data, rv)
|
64
|
+
end
|
65
|
+
record_observation(category, key, value)
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_expressions(callbacks)
|
70
|
+
raise NoExpressions, callbacks if callbacks.nil? || callbacks.empty?
|
71
|
+
[PRE_CB, POST_CB, FAILING_CB].each do |c|
|
72
|
+
next if callbacks[c].nil? || callbacks[c].size < 3
|
73
|
+
@expr[c] = callbacks[c].map { |req| BindingAccessor.new(req, true) }
|
74
|
+
end
|
75
|
+
raise NoExpressions, callbacks if @expr.empty?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
# Save request context for handling further down
|
9
|
+
class CountHTTPCodes < RuleCB
|
10
|
+
METRIC_CATEGORY = 'http_code'.freeze
|
11
|
+
def post(rv, _inst, *_args, &_block)
|
12
|
+
return unless rv.is_a?(Array) && !rv.empty?
|
13
|
+
record_observation(METRIC_CATEGORY, rv[0], 1)
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rules_callbacks/matcher_rule'
|
5
|
+
require 'sqreen/frameworks'
|
6
|
+
|
7
|
+
module Sqreen
|
8
|
+
module Rules
|
9
|
+
# FIXME: Factor with UserAgentMatchesCB
|
10
|
+
# Look for crawlers
|
11
|
+
class CrawlerUserAgentMatchesCB < MatcherRuleCB
|
12
|
+
def pre(_inst, *_args, &_block)
|
13
|
+
ua = framework.client_user_agent
|
14
|
+
return unless ua
|
15
|
+
found = match(ua)
|
16
|
+
return unless found
|
17
|
+
Sqreen.log.debug { "Found UA #{ua} - found: #{found}" }
|
18
|
+
infos = { :found => found }
|
19
|
+
record_event(infos)
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rules_callbacks/matcher_rule'
|
5
|
+
require 'sqreen/frameworks'
|
6
|
+
|
7
|
+
module Sqreen
|
8
|
+
module Rules
|
9
|
+
# Look for crawlers and post them in metrics
|
10
|
+
class CrawlerUserAgentMatchesMetricsCB < MatcherRuleCB
|
11
|
+
CRAWLER_CATEGORY = 'crawler'.freeze
|
12
|
+
|
13
|
+
def pre(_inst, *_args, &_block)
|
14
|
+
ua = framework.client_user_agent
|
15
|
+
return unless ua
|
16
|
+
ua = ua.freeze
|
17
|
+
found = match(ua)
|
18
|
+
return unless found
|
19
|
+
Sqreen.log.debug { "Found UA #{ua} - found: #{found}" }
|
20
|
+
record_observation(CRAWLER_CATEGORY, ua, 1)
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
if defined?(::JRUBY_VERSION)
|
5
|
+
require 'rhino'
|
6
|
+
else
|
7
|
+
require 'therubyracer'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'execjs'
|
11
|
+
|
12
|
+
require 'sqreen/rule_callback'
|
13
|
+
require 'sqreen/binding_accessor'
|
14
|
+
require 'sqreen/events/remote_exception'
|
15
|
+
|
16
|
+
module Sqreen
|
17
|
+
module Rules
|
18
|
+
# Exec js callbacks
|
19
|
+
class ExecJSCB < RuleCB
|
20
|
+
def initialize(klass, method, rule_hash)
|
21
|
+
super(klass, method, rule_hash)
|
22
|
+
callbacks = @rule['callbacks']
|
23
|
+
|
24
|
+
if callbacks['pre'].nil? &&
|
25
|
+
callbacks['post'].nil? &&
|
26
|
+
callbacks['failing'].nil?
|
27
|
+
raise(Sqreen::Exception, 'no JS CB provided')
|
28
|
+
end
|
29
|
+
|
30
|
+
build_runnable(callbacks)
|
31
|
+
@compiled = ExecJS.compile(@source)
|
32
|
+
end
|
33
|
+
|
34
|
+
def pre?
|
35
|
+
@js_pre
|
36
|
+
end
|
37
|
+
|
38
|
+
def post?
|
39
|
+
@js_post
|
40
|
+
end
|
41
|
+
|
42
|
+
def failing?
|
43
|
+
@js_failing
|
44
|
+
end
|
45
|
+
|
46
|
+
def pre(inst, *args, &_block)
|
47
|
+
return unless pre?
|
48
|
+
|
49
|
+
call_callback('pre', inst, args)
|
50
|
+
end
|
51
|
+
|
52
|
+
def post(rv, inst, *args, &_block)
|
53
|
+
return unless post?
|
54
|
+
|
55
|
+
call_callback('post', inst, args, rv)
|
56
|
+
end
|
57
|
+
|
58
|
+
def failing(rv, inst, *args, &_block)
|
59
|
+
return unless failing?
|
60
|
+
|
61
|
+
call_callback('failing', inst, args, rv)
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
def record_and_continue?(ret)
|
67
|
+
case ret
|
68
|
+
when NilClass
|
69
|
+
return false
|
70
|
+
when Hash
|
71
|
+
ret.keys.each do |k|
|
72
|
+
ret[(begin
|
73
|
+
k.to_sym
|
74
|
+
rescue
|
75
|
+
k
|
76
|
+
end)] = ret[k] end
|
77
|
+
record_event(ret[:record]) unless ret[:record].nil?
|
78
|
+
return !ret[:call].nil?
|
79
|
+
else
|
80
|
+
raise Sqreen::Exception, "Invalid return type #{ret.inspect}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def call_callback(name, inst, args, rv = nil)
|
85
|
+
ret = nil
|
86
|
+
args_override = nil
|
87
|
+
arguments = nil
|
88
|
+
loop do
|
89
|
+
arguments = (args_override || @argument_requirements[name]).map do |accessor|
|
90
|
+
accessor.resolve(binding, framework, inst, args, @data, rv)
|
91
|
+
end
|
92
|
+
Sqreen.log.debug { [name, arguments].inspect }
|
93
|
+
ret = @compiled.call("callbacks.#{name}", *arguments)
|
94
|
+
return ret unless record_and_continue?(ret)
|
95
|
+
name = ret[:call]
|
96
|
+
rv = ret[:data]
|
97
|
+
args_override = ret[:args]
|
98
|
+
args_override = build_accessor(args_override) if args_override
|
99
|
+
end
|
100
|
+
rescue => e
|
101
|
+
Sqreen.log.error "we catch a JScb exception: #{e.inspect}"
|
102
|
+
Sqreen.log.error e.backtrace
|
103
|
+
record_exception(e, :cb => name, :args => arguments)
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def build_accessor(reqs)
|
108
|
+
reqs.map do |req|
|
109
|
+
BindingAccessor.new(req, true)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def build_runnable(callbacks)
|
114
|
+
@argument_requirements = {}
|
115
|
+
@source = 'var callbacks = {'
|
116
|
+
@js_pre = !callbacks['pre'].nil?
|
117
|
+
@js_post = !callbacks['post'].nil?
|
118
|
+
@js_failing = !callbacks['failing'].nil?
|
119
|
+
callbacks.each do |name, args_or_func|
|
120
|
+
@source << name
|
121
|
+
@source << ': '
|
122
|
+
if args_or_func.is_a?(Array)
|
123
|
+
@source << args_or_func.pop
|
124
|
+
@argument_requirements[name] = build_accessor(args_or_func)
|
125
|
+
else
|
126
|
+
@source << args_or_func
|
127
|
+
@argument_requirements[name] = []
|
128
|
+
end
|
129
|
+
@source << ",\n"
|
130
|
+
end
|
131
|
+
@source << "\n"
|
132
|
+
@source << '}'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
SQREEN_HEADER_NAME = 'X-Protected-By'.freeze
|
9
|
+
SQREEN_HEADER_VALUE = 'Sqreen'.freeze
|
10
|
+
|
11
|
+
# Display sqreen presence
|
12
|
+
class HeadersInsertCB < RuleCB
|
13
|
+
def post(rv, _inst, *_args, &_block)
|
14
|
+
return unless rv && rv.respond_to?(:[]) && rv[1].is_a?(Hash)
|
15
|
+
rv[1][SQREEN_HEADER_NAME] = SQREEN_HEADER_VALUE
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
class InspectRuleCB < RuleCB
|
9
|
+
def pre(_inst, *args, &_block)
|
10
|
+
Sqreen.log.debug { "<< #{@klass} #{@method} #{Thread.current}" }
|
11
|
+
Sqreen.log.debug { args.join ' ' }
|
12
|
+
end
|
13
|
+
|
14
|
+
def post(_rv, _inst, *_args, &_block)
|
15
|
+
Sqreen.log.debug { ">> #{@klass} #{@method} #{Thread.current}" }
|
16
|
+
byebug if defined? byebug and @data.is_a?(Hash) and @data[:break] == 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.io/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/rule_callback'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Rules
|
8
|
+
# A configurable matcher rule
|
9
|
+
class MatcherRuleCB < RuleCB
|
10
|
+
def initialize(*args)
|
11
|
+
super(*args)
|
12
|
+
prepare
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.prepare_re_pattern(value, options, case_sensitive)
|
16
|
+
res = 0
|
17
|
+
res |= Regexp::MULTILINE if options.include?('multiline')
|
18
|
+
res |= Regexp::IGNORECASE unless case_sensitive
|
19
|
+
Regexp.compile(value, res)
|
20
|
+
end
|
21
|
+
|
22
|
+
def prepare
|
23
|
+
@string = {}
|
24
|
+
@regex_patterns = []
|
25
|
+
|
26
|
+
patterns = @data['values']
|
27
|
+
if patterns.nil?
|
28
|
+
msg = "no key 'values' in data (had #{@data.keys})"
|
29
|
+
raise Sqreen::Exception, msg
|
30
|
+
end
|
31
|
+
|
32
|
+
@funs = {
|
33
|
+
'anywhere' => lambda { |value, str| str.include?(value) },
|
34
|
+
'starts_with' => lambda { |value, str| str.start_with?(value) },
|
35
|
+
'ends_with' => lambda { |value, str| str.end_with?(value) },
|
36
|
+
'equals' => lambda { |value, str| str == value },
|
37
|
+
}
|
38
|
+
|
39
|
+
patterns.each do |entry|
|
40
|
+
next unless entry
|
41
|
+
type = entry['type']
|
42
|
+
val = entry['value']
|
43
|
+
opts = entry['options']
|
44
|
+
opt = (opts && opts.first && opts.first != '') ? opts.first : 'anywhere'
|
45
|
+
case_sensitive = entry['case_sensitive'] || false
|
46
|
+
case type
|
47
|
+
when 'string'
|
48
|
+
if case_sensitive
|
49
|
+
case_type = :cs
|
50
|
+
else
|
51
|
+
case_type = :ci
|
52
|
+
val = val.downcase
|
53
|
+
end
|
54
|
+
|
55
|
+
unless @funs.keys.include?(opt)
|
56
|
+
Sqreen.log.debug { "Error: unknown string option '#{opt}' " }
|
57
|
+
next
|
58
|
+
end
|
59
|
+
@string[opt] = { :ci => [], :cs => [] } unless @string.key?(opt)
|
60
|
+
@string[opt][case_type] << val
|
61
|
+
|
62
|
+
when 'regex'
|
63
|
+
pattern = MatcherRuleCB.prepare_re_pattern(val, opt, case_sensitive)
|
64
|
+
next unless pattern
|
65
|
+
@regex_patterns << pattern
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if [@regex_patterns, @string].map { |s| s == 0 }.all?
|
70
|
+
msg = "no key 'regex' nor 'match' in data (had #{@data.keys})"
|
71
|
+
raise Sqreen::Exception, msg
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def match(str)
|
76
|
+
return if str.nil? || str.empty?
|
77
|
+
istr = str.downcase
|
78
|
+
|
79
|
+
@string.each do |type, cases|
|
80
|
+
fun = @funs[type]
|
81
|
+
if fun.nil?
|
82
|
+
Sqreen.log.debug { "no matching function found for type #{type}" }
|
83
|
+
end
|
84
|
+
cases.each do |case_type, patterns|
|
85
|
+
input_str = if case_type == :ci
|
86
|
+
istr
|
87
|
+
else
|
88
|
+
str
|
89
|
+
end
|
90
|
+
patterns.each do |pat|
|
91
|
+
return pat if fun.call(pat, input_str)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
@regex_patterns.each do |p|
|
97
|
+
return p if p.match(str)
|
98
|
+
end
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|