tcell_agent 0.2.2 → 0.2.4
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 +4 -4
- data/bin/tcell_agent +97 -32
- data/lib/tcell_agent.rb +4 -4
- data/lib/tcell_agent/agent.rb +68 -13
- data/lib/tcell_agent/agent/event_processor.rb +256 -79
- data/lib/tcell_agent/agent/fork_pipe_manager.rb +114 -0
- data/lib/tcell_agent/agent/policy_manager.rb +28 -16
- data/lib/tcell_agent/agent/policy_types.rb +3 -4
- data/lib/tcell_agent/agent/route_manager.rb +45 -0
- data/lib/tcell_agent/agent/static_agent.rb +48 -10
- data/lib/tcell_agent/api.rb +0 -2
- data/lib/tcell_agent/appsensor/path_traversal.rb +1 -1
- data/lib/tcell_agent/configuration.rb +19 -6
- data/lib/tcell_agent/instrumentation.rb +123 -0
- data/lib/tcell_agent/logger.rb +4 -1
- data/lib/tcell_agent/policies/content_security_policy.rb +44 -8
- data/lib/tcell_agent/policies/dataloss_policy.rb +122 -65
- data/lib/tcell_agent/rails.rb +19 -10
- data/{config/initializers/authlogic_auth.rb → lib/tcell_agent/rails/auth/authlogic.rb} +1 -0
- data/{config/initializers/devise_auth.rb → lib/tcell_agent/rails/auth/devise.rb} +2 -81
- data/lib/tcell_agent/rails/dlp.rb +40 -36
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +2 -2
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +8 -2
- data/lib/tcell_agent/rails/routes.rb +15 -19
- data/lib/tcell_agent/routes/table.rb +35 -0
- data/lib/tcell_agent/sensor_events/app_sensor.rb +22 -33
- data/lib/tcell_agent/sensor_events/discovery.rb +30 -0
- data/lib/tcell_agent/sensor_events/dlp.rb +9 -4
- data/lib/tcell_agent/sensor_events/sensor.rb +3 -0
- data/lib/tcell_agent/sensor_events/server_agent.rb +30 -6
- data/lib/tcell_agent/sensor_events/util/utils.rb +5 -1
- data/lib/tcell_agent/start_background_thread.rb +27 -22
- data/lib/tcell_agent/utils/queue_with_timeout.rb +65 -1
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/instrumentation_spec.rb +198 -0
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +37 -2
- data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +81 -8
- data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +3 -3
- data/spec/spec_helper.rb +16 -0
- metadata +11 -11
- data/config/initializers/init.rb +0 -8
- data/lib/tcell_agent/dataloss.rb +0 -0
- data/lib/tcell_agent/policies/add_script_tag_policy.rb +0 -47
- data/lib/tcell_agent/rails/devise.rb +0 -0
- data/spec/lib/tcell_agent/policies/add_script_tag_policy_spec.rb +0 -37
@@ -0,0 +1,114 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
require "tcell_agent/logger"
|
5
|
+
|
6
|
+
module TCellAgent
|
7
|
+
class Agent
|
8
|
+
class ForkPipeManager
|
9
|
+
attr_accessor :readp
|
10
|
+
attr_accessor :writep
|
11
|
+
|
12
|
+
@@parent_id = Process.pid
|
13
|
+
def initialize(&block)
|
14
|
+
begin
|
15
|
+
@readp, @writep = IO.pipe('ASCII-8BIT', 'ASCII-8BIT', binmode: true)
|
16
|
+
if defined?(::Encoding::ASCII_8BIT)
|
17
|
+
@writep.set_encoding(::Encoding::ASCII_8BIT)
|
18
|
+
end
|
19
|
+
if is_parent?
|
20
|
+
self.start_listener(&block)
|
21
|
+
end
|
22
|
+
rescue Exception=>init_exception
|
23
|
+
TCellAgent.logger.error("Could not start listener for pipe to forks")
|
24
|
+
TCellAgent.logger.error(init_exception.message)
|
25
|
+
TCellAgent.logger.debug(init_exception.backtrace)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def is_parent?
|
29
|
+
@@parent_id == Process.pid
|
30
|
+
end
|
31
|
+
def start_listener(&block)
|
32
|
+
Thread.new {
|
33
|
+
while true do
|
34
|
+
begin
|
35
|
+
packed_bytes = @readp.read(4)
|
36
|
+
event_length = packed_bytes.unpack("L>").first
|
37
|
+
packed_event = @readp.read(event_length)
|
38
|
+
event = Marshal.load(packed_event)
|
39
|
+
if block
|
40
|
+
block.call(event)
|
41
|
+
end
|
42
|
+
rescue Exception=>block_exception
|
43
|
+
TCellAgent.logger.error("Could not decode block")
|
44
|
+
TCellAgent.logger.error(block_exception.message)
|
45
|
+
TCellAgent.logger.debug(block_exception.backtrace)
|
46
|
+
sleep 0.5
|
47
|
+
end
|
48
|
+
end
|
49
|
+
}
|
50
|
+
end
|
51
|
+
def send_to_parent(event)
|
52
|
+
if is_parent?
|
53
|
+
#puts "Sending in pipe the wrong way"
|
54
|
+
return
|
55
|
+
else
|
56
|
+
begin
|
57
|
+
packed_event = Marshal.dump(event)
|
58
|
+
packed_bytes = [packed_event.bytesize].pack("L>")
|
59
|
+
@writep.write(packed_bytes+packed_event)
|
60
|
+
rescue Exception=>block_exception
|
61
|
+
TCellAgent.logger.error("Could not write to pipe")
|
62
|
+
TCellAgent.logger.error(block_exception.message)
|
63
|
+
TCellAgent.logger.debug(block_exception.backtrace)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@@event_pipe_manager = ForkPipeManager.new { |event|
|
69
|
+
begin
|
70
|
+
TCellAgent.send_event(event)
|
71
|
+
rescue Exception=>block_exception
|
72
|
+
TCellAgent.logger.error("Could handle send_event_block")
|
73
|
+
TCellAgent.logger.error(block_exception.message)
|
74
|
+
TCellAgent.logger.debug(block_exception.backtrace)
|
75
|
+
end
|
76
|
+
}
|
77
|
+
@@metrics_pipe_manager = ForkPipeManager.new { |val|
|
78
|
+
begin
|
79
|
+
switch_on = val.fetch("_type","")
|
80
|
+
case switch_on
|
81
|
+
when "increment_route"
|
82
|
+
TCellAgent.increment_route(
|
83
|
+
val.fetch("route_id",nil),
|
84
|
+
val.fetch("response_time",nil)
|
85
|
+
)
|
86
|
+
when "discover_database_fields"
|
87
|
+
TCellAgent.discover_database_fields(
|
88
|
+
val.fetch("route_id",nil),
|
89
|
+
val.fetch("database",nil),
|
90
|
+
val.fetch("schema",nil),
|
91
|
+
val.fetch("table",nil),
|
92
|
+
val.fetch("fields",nil)
|
93
|
+
)
|
94
|
+
else
|
95
|
+
# Log this?
|
96
|
+
end
|
97
|
+
rescue Exception=>block_exception
|
98
|
+
TCellAgent.logger.error("Could handle metrics_pipe_block")
|
99
|
+
TCellAgent.logger.error(block_exception.message)
|
100
|
+
TCellAgent.logger.debug(block_exception.backtrace)
|
101
|
+
end
|
102
|
+
}
|
103
|
+
def self.is_parent_process?
|
104
|
+
@@event_pipe_manager.is_parent?
|
105
|
+
end
|
106
|
+
def self.send_to_metrics_pipe(hash_value)
|
107
|
+
@@metrics_pipe_manager.send_to_parent(hash_value)
|
108
|
+
end
|
109
|
+
def self.send_to_event_pipe(event)
|
110
|
+
@@event_pipe_manager.send_to_parent(event)
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
# See the file "LICENSE" for the full license governing this code.
|
2
4
|
|
3
5
|
require "tcell_agent/logger"
|
@@ -14,7 +16,6 @@ require "tcell_agent/policies/http_redirect_policy"
|
|
14
16
|
require "tcell_agent/policies/secure_headers_policy"
|
15
17
|
require "tcell_agent/policies/honeytokens_policy"
|
16
18
|
require "tcell_agent/policies/appsensor_policy"
|
17
|
-
require "tcell_agent/policies/add_script_tag_policy"
|
18
19
|
|
19
20
|
require "tcell_agent/sensor_events/server_agent"
|
20
21
|
|
@@ -28,21 +29,32 @@ require 'json'
|
|
28
29
|
module TCellAgent
|
29
30
|
class Agent
|
30
31
|
|
32
|
+
def ensure_policy_polling_running
|
33
|
+
return if policy_polling_running?
|
34
|
+
@policy_polling_worker_mutex.synchronize do
|
35
|
+
return if policy_polling_running?
|
36
|
+
start_policy_polling
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def policy_polling_running?
|
41
|
+
@policy_polling_thread && @policy_polling_thread.alive?
|
42
|
+
end
|
43
|
+
|
31
44
|
def start_policy_polling
|
32
45
|
if TCellAgent.configuration.fetch_policies_from_tcell == true
|
33
46
|
TCellAgent.logger.debug("starting background polling thread")
|
34
|
-
@
|
47
|
+
@policy_polling_thread = Thread.new do
|
35
48
|
last_poll_time = 0
|
36
|
-
tapi = TCellApi.new
|
37
49
|
last_run = Time.now
|
38
50
|
loop do
|
39
51
|
begin
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
52
|
+
policy_jsons = @@policy_tapi.pollAPI(last_poll_time)
|
53
|
+
if policy_jsons == nil
|
54
|
+
TCellAgent.logger.error("Policy was nil")
|
55
|
+
sleep(10.0)
|
56
|
+
next
|
57
|
+
elsif policy_jsons.key?("last_timestamp")
|
46
58
|
if policy_jsons["last_timestamp"] != 0
|
47
59
|
last_poll_time = policy_jsons["last_timestamp"]
|
48
60
|
end
|
@@ -53,20 +65,19 @@ module TCellAgent
|
|
53
65
|
end
|
54
66
|
processPolicyJson(policy_jsons)
|
55
67
|
rescue Exception => e
|
56
|
-
TCellAgent.logger.error("
|
68
|
+
TCellAgent.logger.error("exception while handling connection: #{e.message}")
|
57
69
|
TCellAgent.logger.debug(e.backtrace)
|
58
|
-
TCellAgent.logger.debug("Sleeping
|
59
|
-
sleep(
|
70
|
+
TCellAgent.logger.debug("Sleeping 30 seconds because the tCell.io request failed...")
|
71
|
+
sleep(30) #wait a minute before trying again
|
60
72
|
end
|
61
|
-
# A little rate limiting
|
62
73
|
if (Time.now - last_run) < 1
|
63
|
-
TCellAgent.logger.debug("Rate limiting: sleeping
|
64
|
-
sleep(
|
74
|
+
TCellAgent.logger.debug("Rate limiting: sleeping 10 seconds")
|
75
|
+
sleep(10)
|
65
76
|
end
|
66
77
|
last_run = Time.now
|
67
78
|
end
|
68
79
|
end
|
69
|
-
end
|
80
|
+
end
|
70
81
|
end
|
71
82
|
|
72
83
|
def processPolicyJson(policy_jsons, cache_the_policy=true)
|
@@ -97,6 +108,7 @@ module TCellAgent
|
|
97
108
|
|
98
109
|
def cache(policy_name, policy)
|
99
110
|
cache_filename = TCellAgent.configuration.cache_filename
|
111
|
+
FileUtils.mkdir_p(File.dirname(cache_filename))
|
100
112
|
if TCellAgent.configuration.app_id
|
101
113
|
cache_filename = cache_filename + '.' + TCellAgent.configuration.app_id
|
102
114
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
# See the file "LICENSE" for the full license governing this code.
|
2
4
|
|
3
5
|
require "tcell_agent/policies/content_security_policy"
|
@@ -8,7 +10,6 @@ require "tcell_agent/policies/http_redirect_policy"
|
|
8
10
|
require "tcell_agent/policies/secure_headers_policy"
|
9
11
|
require "tcell_agent/policies/honeytokens_policy"
|
10
12
|
require "tcell_agent/policies/appsensor_policy"
|
11
|
-
require "tcell_agent/policies/add_script_tag_policy"
|
12
13
|
require "tcell_agent/policies/login_fraud_policy"
|
13
14
|
require "tcell_agent/policies/dataloss_policy"
|
14
15
|
|
@@ -20,9 +21,8 @@ module TCellAgent
|
|
20
21
|
HttpTx = "http-tx"
|
21
22
|
HttpRedirect = "http-redirect"
|
22
23
|
AppSensor = "appsensor"
|
23
|
-
AddScriptTag = "add-jsagent-script-tag"
|
24
24
|
HoneyTokens = "exp-honeytokens"
|
25
|
-
LoginFraud = "
|
25
|
+
LoginFraud = "login"
|
26
26
|
DataLoss = "dlp"
|
27
27
|
|
28
28
|
ClassMap = {
|
@@ -32,7 +32,6 @@ module TCellAgent
|
|
32
32
|
HttpTx=>TCellAgent::Policies::HttpTxPolicy,
|
33
33
|
HttpRedirect=>TCellAgent::Policies::HttpRedirectPolicy,
|
34
34
|
AppSensor=>TCellAgent::Policies::AppSensorPolicy,
|
35
|
-
AddScriptTag=>TCellAgent::Policies::AddScriptTagPolicy,
|
36
35
|
HoneyTokens=>TCellAgent::Policies::HoneytokensPolicy,
|
37
36
|
LoginFraud=>TCellAgent::Policies::LoginFraudPolicy,
|
38
37
|
DataLoss=>TCellAgent::Policies::DataLossPolicy
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# See the file "LICENSE" for the full license governing this code.
|
4
|
+
|
5
|
+
require "tcell_agent/logger"
|
6
|
+
require "tcell_agent/version"
|
7
|
+
require "tcell_agent/api"
|
8
|
+
require "tcell_agent/configuration"
|
9
|
+
|
10
|
+
require "tcell_agent/routes/table"
|
11
|
+
require "tcell_agent/sensor_events/discovery"
|
12
|
+
require "tcell_agent"
|
13
|
+
|
14
|
+
module TCellAgent
|
15
|
+
class Agent
|
16
|
+
def discover_database_field(route_id, database, schema, table, field)
|
17
|
+
if (@route_table.routes[route_id].database[database][schema][table][field].discovered != true)
|
18
|
+
@route_table.routes[route_id].database[database][schema][table][field].discovered = true
|
19
|
+
event = (TCellAgent::SensorEvents::DiscoveryEvent.new(route_id)).for_database(database, schema, table, field)
|
20
|
+
TCellAgent.send_event(event)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
def discover_database_fields(route_id, database, schema, table, fields)
|
24
|
+
if TCellAgent::Agent.is_parent_process? == false
|
25
|
+
TCellAgent.queue_metric({"_type"=>"discover_database_fields",
|
26
|
+
"route_id"=>route_id,
|
27
|
+
"database"=>database,
|
28
|
+
"schema"=>schema,
|
29
|
+
"table"=>table,
|
30
|
+
"fields"=>fields})
|
31
|
+
return
|
32
|
+
end
|
33
|
+
discovered_fields = fields.select { |field|
|
34
|
+
@route_table.routes[route_id].database[database][schema][table][field].discovered != true
|
35
|
+
}
|
36
|
+
if (discovered_fields.length > 0)
|
37
|
+
discovered_fields.each { |field|
|
38
|
+
@route_table.routes[route_id].database[database][schema][table][field].discovered = true
|
39
|
+
}
|
40
|
+
event = (TCellAgent::SensorEvents::DiscoveryEvent.new(route_id)).for_database_fields(database, schema, table, fields)
|
41
|
+
TCellAgent.send_event(event)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,22 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
# See the file "LICENSE" for the full license governing this code.
|
2
4
|
require 'tcell_agent/sensor_events/metrics'
|
5
|
+
require 'monitor'
|
3
6
|
|
4
7
|
module TCellAgent
|
5
|
-
|
6
|
-
|
8
|
+
@@instance_lock = Mutex.new
|
9
|
+
@@my_thread_agent = nil
|
10
|
+
|
11
|
+
def self.thread_agent
|
12
|
+
if(self.thread_agent_defined? == false)
|
13
|
+
@@instance_lock.synchronize do
|
14
|
+
if(self.thread_agent_defined? == false)
|
15
|
+
@@my_thread_agent= TCellAgent::Agent.new(Process.pid)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
@@my_thread_agent
|
7
20
|
end
|
8
|
-
|
9
|
-
|
10
|
-
|
21
|
+
|
22
|
+
def self.thread_agent_defined?
|
23
|
+
@@my_thread_agent != nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# setter
|
27
|
+
def self.thread_agent=some_agent
|
28
|
+
@@instance_lock.synchronize do
|
29
|
+
@@my_thread_agent = some_agent
|
11
30
|
end
|
12
31
|
end
|
32
|
+
|
33
|
+
#class << self
|
34
|
+
# attr_accessor :thread_agent
|
35
|
+
#end
|
36
|
+
def self.send_event(event)
|
37
|
+
self.thread_agent.queueSensorEvent(event)
|
38
|
+
end
|
39
|
+
def self.queue_metric(event)
|
40
|
+
self.thread_agent._queue_metric(event)
|
41
|
+
end
|
13
42
|
def self.policy(policy_type)
|
14
|
-
|
15
|
-
self.thread_agent.policies.fetch(policy_type, nil)
|
16
|
-
end
|
43
|
+
self.thread_agent.policies.fetch(policy_type, nil)
|
17
44
|
end
|
18
45
|
def self.increment_route(route_id, response_time)
|
19
|
-
|
20
|
-
|
46
|
+
self.thread_agent.increment_route(route_id, response_time)
|
47
|
+
end
|
48
|
+
def self.discover_database_field(route_id, database, schema, table, field)
|
49
|
+
self.thread_agent.discover_database_field(route_id, database, schema, table, field)
|
50
|
+
end
|
51
|
+
def self.discover_database_fields(route_id, database, schema, table, fields)
|
52
|
+
self.thread_agent.discover_database_fields(route_id, database, schema, table, fields)
|
53
|
+
end
|
54
|
+
def self.stop_agent
|
55
|
+
self.thread_agent.stop_agent = true
|
56
|
+
end
|
57
|
+
def self.ensure_event_processor_running
|
58
|
+
self.thread_agent.ensure_event_processor_running
|
21
59
|
end
|
22
60
|
end
|
data/lib/tcell_agent/api.rb
CHANGED
@@ -30,7 +30,6 @@ module TCellAgent
|
|
30
30
|
TCellAgent.logger.debug("tCell.io Could not add agent string: " + e.message)
|
31
31
|
end
|
32
32
|
response = RestClient.get full_url,request_headers
|
33
|
-
new_timestamp = last_timestamp
|
34
33
|
TCellAgent.logger.debug "tCell.io API Response: " + response
|
35
34
|
response_json = JSON.parse(response)
|
36
35
|
if (response_json && response_json.has_key?("result"))
|
@@ -50,7 +49,6 @@ module TCellAgent
|
|
50
49
|
if (last_timestamp && last_timestamp != "")
|
51
50
|
full_url = full_url + "?last_timestamp=" + last_timestamp.to_s
|
52
51
|
end
|
53
|
-
TCellAgent.logger.debug("tCell.io Old API Request: " + full_url)
|
54
52
|
response = RestClient.get full_url
|
55
53
|
TCellAgent.logger.debug "tCell.io API Response: " + response
|
56
54
|
response_json = JSON.parse(response)
|
@@ -11,7 +11,7 @@ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
|
11
11
|
module TCellAgent
|
12
12
|
class AppSensor
|
13
13
|
PATH_TRAVERSAL_REGEXES = [
|
14
|
-
Regexp.new("(?:(?:\\\/|\\\\)?\\.+(\\\/|\\\\)(
|
14
|
+
Regexp.new("(?:(?:\\\/|\\\\)?\\.+(\\\/|\\\\)(?:\\.*))|(?:\\w+\\.exe\\??\\s)|(?:;\\s*\\w+\\s*\\\/[\\w*-]+\\\/)|(?:\\d\\.\\dx\\|)|(?:%(?:c0\\.|af\\.|5c\\.))|(?:\\\/(?:%2e){2})"),
|
15
15
|
Regexp.new("(?:%c0%ae\\\/)|(?:(?:\\\/|\\\\)(home|conf|usr|etc|proc|opt|s?bin|local|dev|tmp|kern|[br]oot|sys|system|windows|winnt|program|%[a-z_-]{3,}%)(?:\\\/|\\\\))|(?:(?:\\\/|\\\\)inetpub|localstart\\.asp|boot\\.ini)"),
|
16
16
|
Regexp.new("(?:etc\\\/\\W*passwd)")
|
17
17
|
]
|
@@ -37,13 +37,17 @@ module TCellAgent
|
|
37
37
|
def initialize(filename="config/tcell_agent.config", useapp=nil)
|
38
38
|
@version = 0
|
39
39
|
@exp_config_settings = true
|
40
|
-
|
40
|
+
@demomode = false
|
41
41
|
|
42
42
|
@fetch_policies_from_tcell = true
|
43
43
|
@instrument_for_events = true
|
44
44
|
@enabled = true
|
45
|
-
@cache_filename = "tcell/tcell_agent.cache"
|
46
|
-
@default_log_filename = "tcell/tcell_agent.log"
|
45
|
+
@cache_filename = "tcell/cache/tcell_agent.cache"
|
46
|
+
@default_log_filename = "tcell/logs/tcell_agent.log"
|
47
|
+
|
48
|
+
@event_batch_size_limit = 25
|
49
|
+
@event_time_limit_seconds = 55
|
50
|
+
|
47
51
|
read_config_using_env
|
48
52
|
read_config_from_file(filename)
|
49
53
|
|
@@ -51,8 +55,6 @@ module TCellAgent
|
|
51
55
|
@tcell_input_url ||= "https://input.tcell.io/api/v1"
|
52
56
|
@js_agent_api_base_url ||= nil
|
53
57
|
@js_agent_url ||= "https://api.tcell.io/tcellagent.min.js"
|
54
|
-
@event_batch_size_limit = 25
|
55
|
-
@event_time_limit_seconds = 30
|
56
58
|
|
57
59
|
begin
|
58
60
|
@host_identifier = (Socket.gethostname() || "localhost")
|
@@ -74,6 +76,11 @@ module TCellAgent
|
|
74
76
|
@hmac_key = ENV["TCELL_HMAC_KEY"]
|
75
77
|
@tcell_api_url = ENV["TCELL_API_URL"]
|
76
78
|
@tcell_input_url = ENV["TCELL_INPUT_URL"]
|
79
|
+
@demomode = ENV["TCELL_DEMOMODE"] || @demomode
|
80
|
+
if @demomode
|
81
|
+
@event_batch_size_limit = 2
|
82
|
+
@event_time_limit_seconds = 5
|
83
|
+
end
|
77
84
|
end
|
78
85
|
def read_config_from_file(filename)
|
79
86
|
if File.file?(filename)
|
@@ -127,7 +134,13 @@ module TCellAgent
|
|
127
134
|
# Causes old event url to be used
|
128
135
|
@company = app_data["company"]
|
129
136
|
|
130
|
-
|
137
|
+
if @demomode != true
|
138
|
+
@demomode = app_data.fetch('demomode', false)
|
139
|
+
end
|
140
|
+
if @demomode
|
141
|
+
@event_batch_size_limit = 2
|
142
|
+
@event_time_limit_seconds = 5
|
143
|
+
end
|
131
144
|
else
|
132
145
|
puts " ********* ********* ********* *********"
|
133
146
|
puts "* tCell.io *"
|
@@ -16,6 +16,129 @@ module TCellAgent
|
|
16
16
|
attr_accessor :user_id
|
17
17
|
attr_accessor :route_id
|
18
18
|
attr_accessor :uri
|
19
|
+
attr_accessor :database_filters
|
20
|
+
def self.filterx(sanitize_string, event_flag, replace_flag, term)
|
21
|
+
send_event = false
|
22
|
+
sanitize_string.gsub!(term) {|m|
|
23
|
+
if replace_flag
|
24
|
+
m = "[redacted]"
|
25
|
+
send_event = true
|
26
|
+
elsif event_flag
|
27
|
+
# m = "[hash]"
|
28
|
+
send_event = true
|
29
|
+
end
|
30
|
+
m
|
31
|
+
}
|
32
|
+
return send_event
|
33
|
+
end
|
34
|
+
def initialize
|
35
|
+
@database_filters = Hash.new{|h,k| h[k] = Set.new}
|
36
|
+
end
|
37
|
+
def add_response_db_filter(term, action_obj, database, schema, table, field)
|
38
|
+
if (term != nil and term != '')
|
39
|
+
self.database_filters[term].add([database, schema, table, field, action_obj])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
def filter_body(body)
|
43
|
+
dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
|
44
|
+
if dlp_policy and self.session_id
|
45
|
+
session_id_actions = dlp_policy.get_actions_for_session_id
|
46
|
+
if session_id_actions
|
47
|
+
send_flag = TCellData.filterx(body, session_id_actions.body_event, session_id_actions.body_redact, self.session_id)
|
48
|
+
if send_flag
|
49
|
+
TCellAgent.send_event(
|
50
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
51
|
+
self.route_id,
|
52
|
+
self.uri,
|
53
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY
|
54
|
+
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
self.database_filters.sort_by {|term,properties| -term.length }.each do |term, properties|
|
60
|
+
action_infos = self.database_filters[term]
|
61
|
+
replace_actions = (action_infos.select {|action_info| action_info[4].body_redact == true })
|
62
|
+
event_actions = (action_infos.select {|action_info| (action_info[4].body_redact != true && action_info[4].body_event == true) })
|
63
|
+
send_flag = TCellData.filterx(body, event_actions.length > 0, replace_actions.length > 0, term)
|
64
|
+
if send_flag
|
65
|
+
replace_actions.each do |action_info|
|
66
|
+
database, schema, table, field, action_obj = action_info
|
67
|
+
TCellAgent.send_event(
|
68
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
69
|
+
self.route_id,
|
70
|
+
self.uri,
|
71
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY,
|
72
|
+
action_obj.action_id
|
73
|
+
).for_database(database, schema, table, field)
|
74
|
+
)
|
75
|
+
end
|
76
|
+
event_actions.each do |action_info|
|
77
|
+
database, schema, table, field, action_obj = action_info
|
78
|
+
TCellAgent.send_event(
|
79
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
80
|
+
self.route_id,
|
81
|
+
self.uri,
|
82
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY,
|
83
|
+
action_obj.action_id
|
84
|
+
).for_database(database, schema, table, field)
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
return body
|
90
|
+
end
|
91
|
+
|
92
|
+
def filter_log(log_msg)
|
93
|
+
dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
|
94
|
+
if dlp_policy and self.session_id
|
95
|
+
session_id_actions = dlp_policy.get_actions_for_session_id
|
96
|
+
if session_id_actions
|
97
|
+
send_flag = TCellData.filterx(log_msg, session_id_actions.log_event, session_id_actions.log_redact, self.session_id)
|
98
|
+
if send_flag
|
99
|
+
TCellAgent.send_event(
|
100
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
101
|
+
self.route_id,
|
102
|
+
self.uri,
|
103
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG
|
104
|
+
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
self.database_filters.sort_by {|term,properties| -term.length }.each do |term, properties|
|
110
|
+
action_infos = self.database_filters[term]
|
111
|
+
replace_actions = (action_infos.select {|action_info| action_info[4].log_redact == true })
|
112
|
+
event_actions = (action_infos.select {|action_info| (action_info[4].log_redact != true && action_info[4].log_event == true) })
|
113
|
+
send_flag = TCellData.filterx(log_msg, event_actions.length > 0, replace_actions.length > 0, term)
|
114
|
+
if send_flag
|
115
|
+
replace_actions.each do |action_info|
|
116
|
+
database, schema, table, field, action_obj = action_info
|
117
|
+
TCellAgent.send_event(
|
118
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
119
|
+
self.route_id,
|
120
|
+
self.uri,
|
121
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG,
|
122
|
+
action_obj.action_id
|
123
|
+
).for_database(database, schema, table, field)
|
124
|
+
)
|
125
|
+
end
|
126
|
+
event_actions.each do |action_info|
|
127
|
+
database, schema, table, field, action_obj = action_info
|
128
|
+
TCellAgent.send_event(
|
129
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
130
|
+
self.route_id,
|
131
|
+
self.uri,
|
132
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG,
|
133
|
+
action_obj.action_id
|
134
|
+
).for_database(database, schema, table, field)
|
135
|
+
)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
return log_msg
|
140
|
+
end
|
141
|
+
|
19
142
|
end
|
20
143
|
|
21
144
|
def self.instrument_frameworks
|