tcell_agent 0.2.6 → 0.2.7

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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tcell_agent/agent.rb +2 -1
  3. data/lib/tcell_agent/agent/event_processor.rb +58 -9
  4. data/lib/tcell_agent/agent/fork_pipe_manager.rb +18 -15
  5. data/lib/tcell_agent/agent/static_agent.rb +4 -1
  6. data/lib/tcell_agent/configuration.rb +6 -4
  7. data/lib/tcell_agent/devise.rb +40 -40
  8. data/lib/tcell_agent/instrumentation.rb +125 -59
  9. data/lib/tcell_agent/policies/dataloss_policy.rb +74 -17
  10. data/lib/tcell_agent/policies/login_fraud_policy.rb +39 -36
  11. data/lib/tcell_agent/rails.rb +5 -14
  12. data/lib/tcell_agent/rails/auth/devise.rb +1 -0
  13. data/lib/tcell_agent/rails/dlp.rb +1 -1
  14. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +21 -1
  15. data/lib/tcell_agent/rails/middleware/context_middleware.rb +5 -3
  16. data/lib/tcell_agent/rails/middleware/global_middleware.rb +16 -7
  17. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +8 -9
  18. data/lib/tcell_agent/rails/on_start.rb +101 -0
  19. data/lib/tcell_agent/rails/routes.rb +80 -71
  20. data/lib/tcell_agent/sensor_events/app_sensor.rb +45 -14
  21. data/lib/tcell_agent/sensor_events/metrics.rb +119 -17
  22. data/lib/tcell_agent/sensor_events/server_agent.rb +8 -1
  23. data/lib/tcell_agent/servers/puma.rb +39 -37
  24. data/lib/tcell_agent/servers/thin.rb +0 -1
  25. data/lib/tcell_agent/servers/unicorn.rb +18 -5
  26. data/lib/tcell_agent/start_background_thread.rb +12 -28
  27. data/lib/tcell_agent/version.rb +1 -1
  28. data/spec/apps/rails-3.2/Gemfile +25 -0
  29. data/spec/apps/rails-3.2/Gemfile.lock +126 -0
  30. data/spec/apps/rails-3.2/Rakefile +7 -0
  31. data/spec/apps/rails-3.2/app/assets/images/rails.png +0 -0
  32. data/spec/apps/rails-3.2/app/assets/javascripts/application.js +15 -0
  33. data/spec/apps/rails-3.2/app/assets/stylesheets/application.css +13 -0
  34. data/spec/apps/rails-3.2/app/controllers/application_controller.rb +3 -0
  35. data/spec/apps/rails-3.2/app/controllers/t_cell_app_controller.rb +5 -0
  36. data/spec/apps/rails-3.2/app/helpers/application_helper.rb +2 -0
  37. data/spec/apps/rails-3.2/app/views/layouts/application.html.erb +14 -0
  38. data/spec/apps/rails-3.2/app/views/t_cell_app/index.html.erb +1 -0
  39. data/spec/apps/rails-3.2/config.ru +4 -0
  40. data/spec/apps/rails-3.2/config/application.rb +63 -0
  41. data/spec/apps/rails-3.2/config/boot.rb +6 -0
  42. data/spec/apps/rails-3.2/config/environment.rb +5 -0
  43. data/spec/apps/rails-3.2/config/environments/test.rb +37 -0
  44. data/spec/apps/rails-3.2/config/routes.rb +11 -0
  45. data/spec/apps/rails-4.1/Gemfile +7 -0
  46. data/spec/apps/rails-4.1/Gemfile.lock +114 -0
  47. data/spec/apps/rails-4.1/Rakefile +6 -0
  48. data/spec/apps/rails-4.1/app/assets/javascripts/application.js +16 -0
  49. data/spec/apps/rails-4.1/app/assets/stylesheets/application.css +15 -0
  50. data/spec/apps/rails-4.1/app/controllers/application_controller.rb +5 -0
  51. data/spec/apps/rails-4.1/app/controllers/t_cell_app_controller.rb +5 -0
  52. data/spec/apps/rails-4.1/app/helpers/application_helper.rb +2 -0
  53. data/spec/apps/rails-4.1/app/views/layouts/application.html.erb +14 -0
  54. data/spec/apps/rails-4.1/app/views/t_cell_app/index.html.erb +1 -0
  55. data/spec/apps/rails-4.1/config.ru +4 -0
  56. data/spec/apps/rails-4.1/config/application.rb +24 -0
  57. data/spec/apps/rails-4.1/config/boot.rb +4 -0
  58. data/spec/apps/rails-4.1/config/environment.rb +5 -0
  59. data/spec/apps/rails-4.1/config/environments/test.rb +41 -0
  60. data/spec/apps/rails-4.1/config/initializers/assets.rb +8 -0
  61. data/spec/apps/rails-4.1/config/initializers/backtrace_silencers.rb +7 -0
  62. data/spec/apps/rails-4.1/config/initializers/cookies_serializer.rb +3 -0
  63. data/spec/apps/rails-4.1/config/initializers/filter_parameter_logging.rb +4 -0
  64. data/spec/apps/rails-4.1/config/initializers/inflections.rb +16 -0
  65. data/spec/apps/rails-4.1/config/initializers/mime_types.rb +4 -0
  66. data/spec/apps/rails-4.1/config/initializers/session_store.rb +3 -0
  67. data/spec/apps/rails-4.1/config/initializers/wrap_parameters.rb +14 -0
  68. data/spec/apps/rails-4.1/config/locales/en.yml +23 -0
  69. data/spec/apps/rails-4.1/config/routes.rb +12 -0
  70. data/spec/apps/rails-4.1/config/secrets.yml +22 -0
  71. data/spec/integration/puma.rb +195 -0
  72. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +136 -0
  73. data/spec/lib/tcell_agent/appsensor_spec.rb +0 -1
  74. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -1
  75. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +94 -10
  76. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +39 -34
  77. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +146 -0
  78. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +13 -5
  79. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +258 -0
  80. data/spec/spec_helper.rb +6 -15
  81. data/spec/support/middleware_helper.rb +17 -0
  82. data/spec/{resources → support/resources}/normal_config.json +0 -0
  83. data/spec/support/static_agent_overrides.rb +36 -0
  84. metadata +103 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3e9ec10853e07ac321bca036627e9e98a9e8545f
4
- data.tar.gz: b1dce50c2950629b10397802e5a6f16fa1beabc1
3
+ metadata.gz: 8a2e9af45884f3f879ebdac3c3df5c1443704b46
4
+ data.tar.gz: 4ebb0cf3c1dc1082581b098d60d86a1ab629dd2e
5
5
  SHA512:
6
- metadata.gz: 1506c43edb7ae723f675b4cb1e8e5d0703505941c00cde7c399d3b7c64810ce3f8f0b53744b9eb61719d79272d8676519b0183c4af124f89702d576793b2f342
7
- data.tar.gz: fca2c0f960400a55a7f67c7e0d93465174d785b299f703271cc1ce0befc2430093f0556e570469c0a9251ac6da7aff06dba8180499d284b4a6989d0b11ab7980
6
+ metadata.gz: 34f96472deced27c678bb902dbd70bf3340debe5eed76506ff949ce08b647b5893b005806b82920f75582e371ae5ee7278ea4f3f77bc2bb6751fcb00750e7fee
7
+ data.tar.gz: d99da7567bae448c909d51c3fd720ddb29429993a60cd499c195460e1d1d052e6c3f9d8481af93dc07209f0460a42ad10a2e8a8ae011923dd17cd23f124faf26
@@ -99,6 +99,7 @@ module TCellAgent
99
99
  @mutex = Monitor.new
100
100
 
101
101
  @response_time_table = {}
102
+ @sessions_metrics = TCellAgent::SensorEvents::SessionsMetric.new
102
103
  @dispatchEvents = []
103
104
  @eventQueue = BoundedQueue.new(200)
104
105
 
@@ -118,7 +119,7 @@ module TCellAgent
118
119
  TCellAgent.configuration.app_id == nil)
119
120
  puts " ********* ********* ********* *********"
120
121
  puts "* tCell.io *"
121
- puts "* Confiuration info is missing, you may *"
122
+ puts "* Configuration info is missing, you may *"
122
123
  puts "* need to download config file and place *"
123
124
  puts "* it in the config/ directory *"
124
125
  puts " ********* ********* ********* *********"
@@ -84,6 +84,16 @@ module TCellAgent
84
84
  @response_time_table = {}
85
85
  end
86
86
  end
87
+ if @sessions_metrics.has_sessions?
88
+ sessions_to_send = nil
89
+ @mutex.synchronize do
90
+ sessions_to_send = @sessions_metrics
91
+ @sessions_metrics = TCellAgent::SensorEvents::SessionsMetric.new
92
+ end
93
+ @event_dispatch_monitor.synchronize {
94
+ @dispatchEvents.push( sessions_to_send )
95
+ }
96
+ end
87
97
  @event_dispatch_monitor.synchronize {
88
98
  events_to_send = @dispatchEvents
89
99
  result = tapi.sendEventSet(events_to_send)
@@ -98,8 +108,8 @@ module TCellAgent
98
108
  end
99
109
  }
100
110
  end
101
- # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
102
- else
111
+ # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
112
+ else
103
113
  event.post_process
104
114
  if event.send == true
105
115
  @event_dispatch_monitor.synchronize {
@@ -108,7 +118,7 @@ module TCellAgent
108
118
  end
109
119
  if (event.flush or @dispatchEvents.length >= @dispatchEventsLimit or wait_for < 0)
110
120
  last_run_time = Time.now
111
- # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
121
+ # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
112
122
  if (@events_send_empties || @dispatchEvents.length > 0)
113
123
  if (@response_time_table.size > 0)
114
124
  metrics_event = TCellAgent::SensorEvents::MetricsEvent.new
@@ -120,6 +130,16 @@ module TCellAgent
120
130
  @response_time_table = {}
121
131
  end
122
132
  end
133
+ if @sessions_metrics.has_sessions?
134
+ sessions_to_send = nil
135
+ @mutex.synchronize do
136
+ sessions_to_send = @sessions_metrics
137
+ @sessions_metrics = TCellAgent::SensorEvents::SessionsMetric.new
138
+ end
139
+ @event_dispatch_monitor.synchronize {
140
+ @dispatchEvents.push( sessions_to_send )
141
+ }
142
+ end
123
143
  @event_dispatch_monitor.synchronize {
124
144
  events_to_send = @dispatchEvents
125
145
  result = tapi.sendEventSet(events_to_send)
@@ -130,10 +150,10 @@ module TCellAgent
130
150
  end
131
151
  }
132
152
  end
133
- # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
153
+ # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
134
154
  end
135
155
  end
136
- rescue ThreadError => te
156
+ rescue ThreadError
137
157
  last_run_time = Time.now
138
158
  @event_dispatch_monitor.synchronize {
139
159
  @dispatchEvents = []
@@ -278,12 +298,42 @@ module TCellAgent
278
298
  end
279
299
  end
280
300
 
301
+ def increment_session_info(hmac_session_id, user_id, ip_address, user_agent)
302
+ TCellAgent::Instrumentation.safe_block("Incrementing session info") do
303
+
304
+ if TCellAgent::Agent.is_parent_process? == false
305
+ TCellAgent.queue_metric({
306
+ "_type"=>"increment_session_info",
307
+ "hmac_session_id" => hmac_session_id,
308
+ "user_id" => user_id,
309
+ "ip_address" => ip_address,
310
+ "user_agent" => user_agent
311
+ })
312
+ return
313
+ end
314
+
315
+ @mutex.synchronize do
316
+ @sessions_metrics.add_session_info(hmac_session_id, user_id, ip_address, user_agent)
317
+ end
318
+
319
+ if @sessions_metrics.flush
320
+ TCellAgent.send_event(TCellAgent::SensorEvents::FlushDummyEvent.new)
321
+ end
322
+ end
323
+ end
324
+
281
325
  def increment_route(route_id, response_time)
282
- begin
326
+ TCellAgent::Instrumentation.safe_block("Incrementing route") do
327
+
283
328
  if TCellAgent::Agent.is_parent_process? == false
284
- TCellAgent.queue_metric({"_type"=>"increment_route", "route_id"=>route_id, "response_time"=>response_time})
329
+ TCellAgent.queue_metric({
330
+ "_type"=>"increment_route",
331
+ "route_id"=>route_id,
332
+ "response_time"=>response_time
333
+ })
285
334
  return
286
335
  end
336
+
287
337
  @mutex.synchronize do
288
338
  if (route_id == nil || route_id == "")
289
339
  route_id = "?"
@@ -294,8 +344,7 @@ module TCellAgent
294
344
  @response_time_table[route_id]["mn"] = [@response_time_table[route_id].fetch("mn",response_time), response_time].min
295
345
  @response_time_table[route_id]["t"] = ((@response_time_table[route_id].fetch("t",0)*(@response_time_table[route_id]["c"]-1)) + response_time) / @response_time_table[route_id]["c"]
296
346
  end
297
- rescue Exception => inc_exception
298
- TCellAgent.logger.debug("Could not add incrememnt exception #{inc_exception.message}")
347
+
299
348
  end
300
349
  end
301
350
 
@@ -20,7 +20,7 @@ module TCellAgent
20
20
  self.start_listener(&block)
21
21
  end
22
22
  rescue Exception=>init_exception
23
- TCellAgent.logger.error("Could not start listener for pipe to forks")
23
+ TCellAgent.logger.error("Could not start listener for pipe to forks")
24
24
  TCellAgent.logger.error(init_exception.message)
25
25
  TCellAgent.logger.debug(init_exception.backtrace)
26
26
  end
@@ -44,14 +44,14 @@ module TCellAgent
44
44
  TCellAgent.logger.error(block_exception.message)
45
45
  TCellAgent.logger.debug(block_exception.backtrace)
46
46
  sleep 0.5
47
- end
47
+ end
48
48
  end
49
49
  }
50
50
  end
51
51
  def send_to_parent(event)
52
52
  if is_parent?
53
53
  #puts "Sending in pipe the wrong way"
54
- return
54
+ return
55
55
  else
56
56
  begin
57
57
  packed_event = Marshal.dump(event)
@@ -61,7 +61,7 @@ module TCellAgent
61
61
  TCellAgent.logger.error("Could not write to pipe")
62
62
  TCellAgent.logger.error(block_exception.message)
63
63
  TCellAgent.logger.debug(block_exception.backtrace)
64
- end
64
+ end
65
65
  end
66
66
  end
67
67
  end
@@ -76,7 +76,7 @@ module TCellAgent
76
76
  end
77
77
  }
78
78
  @@metrics_pipe_manager = ForkPipeManager.new { |val|
79
- begin
79
+ TCellAgent::Instrumentation.safe_block("Handling metrics_pipe_block") do
80
80
  switch_on = val.fetch("_type","")
81
81
  case switch_on
82
82
  when "increment_route"
@@ -86,20 +86,23 @@ module TCellAgent
86
86
  )
87
87
  when "discover_database_fields"
88
88
  TCellAgent.discover_database_fields(
89
- val.fetch("route_id",nil),
90
- val.fetch("database",nil),
91
- val.fetch("schema",nil),
92
- val.fetch("table",nil),
89
+ val.fetch("route_id",nil),
90
+ val.fetch("database",nil),
91
+ val.fetch("schema",nil),
92
+ val.fetch("table",nil),
93
93
  val.fetch("fields",nil)
94
94
  )
95
+ when "increment_session_info"
96
+ TCellAgent.increment_session_info(
97
+ val.fetch("hmac_session_id", nil),
98
+ val.fetch("user_id", nil),
99
+ val.fetch("ip_address", nil),
100
+ val.fetch("user_agent", nil)
101
+ )
95
102
  else
96
- # Log this?
103
+ raise Exception.new("Metrics Pipe Manager received unknown metric: #{val.fetch("_type","")}")
97
104
  end
98
- rescue Exception=>block_exception
99
- TCellAgent.logger.error("Could handle metrics_pipe_block")
100
- TCellAgent.logger.error(block_exception.message)
101
- TCellAgent.logger.debug(block_exception.backtrace)
102
- end
105
+ end
103
106
  }
104
107
  def self.is_parent_process?
105
108
  @@event_pipe_manager.is_parent?
@@ -42,6 +42,9 @@ module TCellAgent
42
42
  def self.policy(policy_type)
43
43
  self.thread_agent.policies.fetch(policy_type, nil)
44
44
  end
45
+ def self.increment_session_info(hmac_session_id, user_id, ip_address, user_agent)
46
+ self.thread_agent.increment_session_info(hmac_session_id, user_id, ip_address, user_agent)
47
+ end
45
48
  def self.increment_route(route_id, response_time)
46
49
  self.thread_agent.increment_route(route_id, response_time)
47
50
  end
@@ -57,4 +60,4 @@ module TCellAgent
57
60
  def self.ensure_event_processor_running
58
61
  self.thread_agent.ensure_event_processor_running
59
62
  end
60
- end
63
+ end
@@ -30,24 +30,26 @@ module TCellAgent
30
30
  :cache_filename,
31
31
  :js_agent_api_base_url,
32
32
  :js_agent_url,
33
- :raise_exceptions
33
+ :raise_exceptions,
34
+ :allow_unencrypted_appsensor_payloads
34
35
 
35
36
  attr_accessor :exp_config_settings
36
37
 
37
-
38
38
  def initialize(filename="config/tcell_agent.config", useapp=nil)
39
39
  @version = 0
40
40
  @exp_config_settings = true
41
41
  @demomode = false
42
42
 
43
+ @allow_unencrypted_appsensor_payloads = [true, "true", "yes", "1"].include?(ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"])
44
+
43
45
  @fetch_policies_from_tcell = true
44
46
  @instrument_for_events = true
45
47
  @enabled = true
46
48
  @cache_filename = "tcell/cache/tcell_agent.cache"
47
49
  @default_log_filename = "tcell/logs/tcell_agent.log"
48
50
 
49
- @event_batch_size_limit = 25
50
- @event_time_limit_seconds = 55
51
+ @event_batch_size_limit = 50
52
+ @event_time_limit_seconds = 15
51
53
 
52
54
  @raise_exceptions = false
53
55
 
@@ -39,45 +39,45 @@ module TCellAgent
39
39
  end
40
40
  end
41
41
  end
42
- Devise::Strategies::DatabaseAuthenticatable.class_eval do
43
- alias_method :original_authenticate!, :authenticate!
44
- def authenticate!
45
- begin
46
- tcell_background_worker = TCellAgent.thread_agent
47
- # if (tcell_background_worker && tcell_background_worker.honeytokens_policy)
48
- # credstring = ""
49
- # authentication_keys.each do |authentication_key|
50
- # credstring = credstring + authentication_hash[authentication_key] + "::"
51
- # end
52
- # credstring = credstring + password[1..-3] # Chop off first and last 2 characters
53
- # token_id = tcell_background_worker.honeytokens_policy.id_for_credentialstring(credstring)
54
- # if token_id
55
- # begin
56
- # event = TCellAgent::SensorEvents::HoneytokensSensorEvent.new(request, token_id)
57
- # TCellAgent.send_event(event)
58
- # rescue
59
- # #pass
60
- # end
61
- # return
62
- # end
63
- # end
64
- rescue Exception => e
65
- TCellAgent.logger.error("uncaught exception while processing honeytokens: #{e.message}")
66
- end
67
- original_authenticate!
68
- end
69
- end
70
- end
71
- end
72
- module Devise
73
- module Models
74
- module Recoverable
75
- extend ActiveSupport::Concern
76
- alias_method :original_send_reset_password_instructions, :send_reset_password_instructions
77
- def send_reset_password_instructions
78
- x = original_send_reset_password_instructions
79
- x
80
- end
81
- end
42
+ # Devise::Strategies::DatabaseAuthenticatable.class_eval do
43
+ # alias_method :original_authenticate!, :authenticate!
44
+ # def authenticate!
45
+ # begin
46
+ # tcell_background_worker = TCellAgent.thread_agent
47
+ # # if (tcell_background_worker && tcell_background_worker.honeytokens_policy)
48
+ # # credstring = ""
49
+ # # authentication_keys.each do |authentication_key|
50
+ # # credstring = credstring + authentication_hash[authentication_key] + "::"
51
+ # # end
52
+ # # credstring = credstring + password[1..-3] # Chop off first and last 2 characters
53
+ # # token_id = tcell_background_worker.honeytokens_policy.id_for_credentialstring(credstring)
54
+ # # if token_id
55
+ # # begin
56
+ # # event = TCellAgent::SensorEvents::HoneytokensSensorEvent.new(request, token_id)
57
+ # # TCellAgent.send_event(event)
58
+ # # rescue
59
+ # # #pass
60
+ # # end
61
+ # # return
62
+ # # end
63
+ # # end
64
+ # rescue Exception => e
65
+ # TCellAgent.logger.error("uncaught exception while processing honeytokens: #{e.message}")
66
+ # end
67
+ # original_authenticate!
68
+ # end
69
+ # end
82
70
  end
83
71
  end
72
+ # module Devise
73
+ # module Models
74
+ # module Recoverable
75
+ # extend ActiveSupport::Concern
76
+ # alias_method :original_send_reset_password_instructions, :send_reset_password_instructions
77
+ # def send_reset_password_instructions
78
+ # x = original_send_reset_password_instructions
79
+ # x
80
+ # end
81
+ # end
82
+ # end
83
+ # end
@@ -8,6 +8,53 @@ require 'date'
8
8
 
9
9
  module TCellAgent
10
10
  module Instrumentation
11
+ class ContextFilter
12
+ attr_accessor :type
13
+ attr_accessor :rule
14
+ attr_accessor :context
15
+ attr_accessor :parameter
16
+ attr_accessor :database
17
+ attr_accessor :schema
18
+ attr_accessor :table
19
+ attr_accessor :field
20
+
21
+ DATABASE = "db"
22
+ REQUEST = "request"
23
+
24
+ def for_request(context, parameter, rule)
25
+ self.type = ContextFilter::REQUEST
26
+ self.context = context
27
+ self.parameter = parameter
28
+ self.rule = rule
29
+ return self
30
+ end
31
+ def create_hash_value
32
+ "#{self.type}#{self.context}#{self.parameter}#{self.database}#{self.schema}#{self.table}#{self.field}#{self.rule}".hash
33
+ end
34
+ def eql?(other_key)
35
+ self.hash == other_key.hash
36
+ end
37
+ def hash
38
+ self.create_hash_value
39
+ end
40
+ def for_database(database, schema, table, field, rule)
41
+ self.type = ContextFilter::DATABASE
42
+ self.database = database
43
+ self.schema = schema
44
+ self.table = table
45
+ self.field = field
46
+ self.rule = rule
47
+ return self
48
+ end
49
+ def for_request(context, parameter, rule)
50
+ self.type = ContextFilter::REQUEST
51
+ self.context = context
52
+ self.parameter = parameter
53
+ self.rule = rule
54
+ return self
55
+ end
56
+ end
57
+
11
58
 
12
59
  class TCellData
13
60
  attr_accessor :transaction_id
@@ -16,7 +63,10 @@ module TCellAgent
16
63
  attr_accessor :user_id
17
64
  attr_accessor :route_id
18
65
  attr_accessor :uri
66
+ attr_accessor :context_filters_by_term
19
67
  attr_accessor :database_filters
68
+ attr_accessor :ip_address
69
+ attr_accessor :user_agent
20
70
  def self.filterx(sanitize_string, event_flag, replace_flag, term)
21
71
  send_event = false
22
72
  sanitize_string.gsub!(term) {|m|
@@ -32,13 +82,35 @@ module TCellAgent
32
82
  return send_event
33
83
  end
34
84
  def initialize
35
- @database_filters = Hash.new{|h,k| h[k] = Set.new}
85
+ @context_filters_by_term = Hash.new{|h,k| h[k] = Set.new}
86
+ end
87
+ def is_valid_term?(term)
88
+ if term != nil && term != '' and term.to_s.length >= 5
89
+ return true
90
+ end
91
+ return false
36
92
  end
37
93
  def add_response_db_filter(term, action_obj, database, schema, table, field)
38
- if (term != nil && term != '' && term.to_s.length >= 5)
39
- self.database_filters[term.to_s].add([database, schema, table, field, action_obj])
94
+ if is_valid_term?(term)
95
+ self.context_filters_by_term[term.to_s].add((ContextFilter.new).for_database(database, schema, table, field, action_obj))
40
96
  end
41
97
  end
98
+ def add_filter_for_request_parameter(term, rule, parameter_name)
99
+ if is_valid_term?(term)
100
+ self.context_filters_by_term[term.to_s].add((ContextFilter.new).for_request("form", parameter_name, rule))
101
+ end
102
+ end
103
+ def add_filter_for_header_value(term, rule, header_name)
104
+ if is_valid_term?(term)
105
+ self.context_filters_by_term[term.to_s].add((ContextFilter.new).for_request("header", header_name, rule))
106
+ end
107
+ end
108
+ def add_filter_for_cookie_value(term, rule, cookie_name)
109
+ if is_valid_term?(term)
110
+ self.context_filters_by_term[term.to_s].add((ContextFilter.new).for_request("cookie", cookie_name, rule))
111
+ end
112
+ end
113
+
42
114
  def filter_body(body)
43
115
  dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
44
116
  if dlp_policy and self.session_id
@@ -56,34 +128,28 @@ module TCellAgent
56
128
  end
57
129
  end
58
130
  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)
131
+ self.context_filters_by_term.sort_by {|term,context_filters| -term.length }.each do |term, context_filters|
132
+ replace_filters = (context_filters.select {|context_filter| context_filter.rule.body_redact == true })
133
+ event_filters = (context_filters.select {|context_filter| (context_filter.rule.body_redact != true && context_filter.rule.body_event == true) })
134
+ send_flag = TCellData.filterx(body, event_filters.length > 0, replace_filters.length > 0, term)
64
135
  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)
136
+ (replace_filters + event_filters).each { |filter|
137
+ base_event = TCellAgent::SensorEvents::DlpEvent.new(
138
+ self.route_id,
139
+ self.uri,
140
+ TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY,
141
+ filter.rule.action_id
85
142
  )
86
- end
143
+ if filter.type == ContextFilter::DATABASE
144
+ TCellAgent.send_event(
145
+ base_event.for_database(filter.database, filter.schema, filter.table, filter.field)
146
+ )
147
+ elsif filter.type == ContextFilter::REQUEST
148
+ TCellAgent.send_event(
149
+ base_event.for_request(filter.context, filter.parameter)
150
+ )
151
+ end
152
+ }
87
153
  end
88
154
  end
89
155
  return body
@@ -106,35 +172,29 @@ module TCellAgent
106
172
  end
107
173
  end
108
174
  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)
175
+ self.context_filters_by_term.sort_by {|term,context_filters| -term.length }.each do |term, context_filters|
176
+ replace_filters = (context_filters.select {|context_filter| context_filter.rule.log_redact == true })
177
+ event_filters = (context_filters.select {|context_filter| (context_filter.rule.log_redact != true && context_filter.rule.log_event == true) })
178
+ send_flag = TCellData.filterx(log_msg, event_filters.length > 0, replace_filters.length > 0, term)
114
179
  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)
180
+ (replace_filters + event_filters).each { |filter|
181
+ base_event = TCellAgent::SensorEvents::DlpEvent.new(
182
+ self.route_id,
183
+ self.uri,
184
+ TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG,
185
+ filter.rule.action_id
135
186
  )
136
- end
137
- end
187
+ if filter.type == ContextFilter::DATABASE
188
+ TCellAgent.send_event(
189
+ base_event.for_database(filter.database, filter.schema, filter.table, filter.field)
190
+ )
191
+ elsif filter.type == ContextFilter::REQUEST
192
+ TCellAgent.send_event(
193
+ base_event.for_request(filter.context, filter.parameter)
194
+ )
195
+ end
196
+ }
197
+ end
138
198
  end
139
199
  return log_msg
140
200
  end
@@ -151,16 +211,22 @@ module TCellAgent
151
211
  def self.safe_block(message, &block)
152
212
  begin
153
213
  block.call()
214
+
154
215
  rescue Exception => ex
155
- TCellAgent.logger.debug "Exception in safe_block #{message}: #{ex.class} happened, message is #{ex.message}"
156
- TCellAgent.logger.debug(ex.backtrace)
216
+ if TCellAgent.configuration.raise_exceptions
217
+ raise ex
218
+
219
+ else
220
+ TCellAgent.logger.debug "Exception in safe_block #{message}: #{ex.class} happened, message is #{ex.message}"
221
+ TCellAgent.logger.debug(ex.backtrace)
222
+ end
157
223
  end
158
224
  end
159
225
 
160
226
  def self.safe_block_no_log(message, &block)
161
227
  begin
162
228
  block.call()
163
- rescue Exception => ex
229
+ rescue Exception
164
230
  end
165
231
  end
166
232
  end