contrast-agent 6.15.3 → 7.1.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +1 -1
  3. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +1 -1
  4. data/ext/cs__assess_module/cs__assess_module.c +0 -19
  5. data/ext/cs__assess_test/cs__assess_tests.c +1 -1
  6. data/ext/cs__common/cs__common.c +17 -18
  7. data/ext/cs__common/cs__common.h +7 -11
  8. data/ext/cs__contrast_patch/cs__contrast_patch.c +16 -24
  9. data/ext/extconf_common.rb +79 -0
  10. data/lib/contrast/agent/assess/policy/policy.rb +1 -1
  11. data/lib/contrast/agent/assess/policy/source_method.rb +1 -0
  12. data/lib/contrast/agent/deadzone/policy/policy.rb +1 -1
  13. data/lib/contrast/agent/patching/policy/policy.rb +2 -2
  14. data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +3 -0
  15. data/lib/contrast/agent/protect/rule/no_sqli/no_sqli.rb +1 -1
  16. data/lib/contrast/agent/reporting/reporter.rb +19 -4
  17. data/lib/contrast/agent/reporting/reporting_events/agent_effective_config.rb +32 -0
  18. data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +7 -0
  19. data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +3 -1
  20. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +11 -7
  21. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +15 -7
  22. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +4 -2
  23. data/lib/contrast/agent/reporting/reporting_workers/application_server_worker.rb +3 -0
  24. data/lib/contrast/agent/reporting/reporting_workers/reporter_heartbeat.rb +3 -0
  25. data/lib/contrast/agent/reporting/reporting_workers/server_settings_worker.rb +3 -0
  26. data/lib/contrast/agent/telemetry/base.rb +37 -12
  27. data/lib/contrast/agent/telemetry/client.rb +1 -3
  28. data/lib/contrast/agent/telemetry/telemetry.rb +0 -7
  29. data/lib/contrast/agent/thread/thread_watcher.rb +2 -2
  30. data/lib/contrast/agent/version.rb +1 -1
  31. data/lib/contrast/components/agent.rb +1 -1
  32. data/lib/contrast/components/api.rb +3 -3
  33. data/lib/contrast/components/app_context.rb +1 -1
  34. data/lib/contrast/components/assess.rb +1 -1
  35. data/lib/contrast/components/assess_rules.rb +2 -2
  36. data/lib/contrast/components/base.rb +3 -3
  37. data/lib/contrast/components/config/sources.rb +12 -9
  38. data/lib/contrast/components/config.rb +2 -2
  39. data/lib/contrast/components/protect.rb +2 -2
  40. data/lib/contrast/components/sampling.rb +7 -5
  41. data/lib/contrast/components/settings.rb +1 -1
  42. data/lib/contrast/config/certification_configuration.rb +1 -1
  43. data/lib/contrast/config/configuration_files.rb +47 -0
  44. data/lib/contrast/config/diagnostics/command_line.rb +24 -0
  45. data/lib/contrast/config/{config.rb → diagnostics/config.rb} +21 -6
  46. data/lib/contrast/config/diagnostics/contrast_ui.rb +24 -0
  47. data/lib/contrast/config/diagnostics/effective_config.rb +28 -0
  48. data/lib/contrast/config/diagnostics/effective_config_value.rb +14 -0
  49. data/lib/contrast/config/diagnostics/environment_variables.rb +51 -0
  50. data/lib/contrast/config/{diagnostics.rb → diagnostics/monitor.rb} +10 -10
  51. data/lib/contrast/config/diagnostics/source_config_value.rb +51 -0
  52. data/lib/contrast/config/diagnostics/tools.rb +188 -0
  53. data/lib/contrast/config/diagnostics/user_configuration_file.rb +44 -0
  54. data/lib/contrast/config/request_audit_configuration.rb +1 -1
  55. data/lib/contrast/config/server_configuration.rb +1 -1
  56. data/lib/contrast/configuration.rb +90 -57
  57. data/lib/contrast/utils/hash_utils.rb +43 -0
  58. data/lib/contrast/utils/json.rb +46 -0
  59. data/lib/contrast/utils/middleware_utils.rb +4 -4
  60. data/lib/contrast/utils/net_http_base.rb +75 -26
  61. data/lib/contrast/utils/object_share.rb +3 -3
  62. data/lib/contrast.rb +0 -16
  63. data/ruby-agent.gemspec +4 -8
  64. metadata +40 -25
  65. data/lib/contrast/config/diagnostics_tools.rb +0 -99
  66. data/lib/contrast/config/effective_config.rb +0 -131
  67. data/lib/contrast/config/effective_config_value.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb55239bd37c7b0d2c3adc47d2e47ff25e331694b9be68522a29f8e4ce8c1220
4
- data.tar.gz: 41a5a677403dd10c0dcd67673b32e32aa8f8ad04a82d963891f95ceaa25b46a1
3
+ metadata.gz: 81222798666699f86b31b925d531d2ee2229eb7934582d2a502cc61de3ca4e0b
4
+ data.tar.gz: 7dd4d41a58600b7d57b5f57cf95c42bd2f6d198f5f1906e93751e33c09efa3e0
5
5
  SHA512:
6
- metadata.gz: 94aaa0a8ed0b9fb08fb5c206bee3695cd1cc1f3a8b7752fa8c52abfb563a4e58fac60162ab13c4f06ceb785532ae1a76b93dcc8f348e99d29b112b265a88051b
7
- data.tar.gz: 658421a2a8558bac001eb707340f0bc763012d06b9fdcfe1137fb3ceff6f53966d7cc9af9bced07f08411b5e44af1ad5c4f5805b54abaae0ad71dcc81011fbb9
6
+ metadata.gz: 02e5d3aa6b342e8c4277ad6cefde65819aed6f6b4a1079cfe7528fcce236ec702aa8a63fc756c403c0df6e3ef38d5d25dc9f1c6e5c450d272122d699b6fd9872
7
+ data.tar.gz: 9cc83b5f69edeea949784ae766be7e02c1d589e58b2af5b5c1bd7975dcee1450d294bc7de647f60a9a3f18a1ea05a43bfe452a52d4760ed1b1cfcb0a7339a6ab
@@ -62,7 +62,7 @@ VALUE rb_fiber_yield_hook(int argc, const VALUE *argv) {
62
62
  return rb_fiber_yield_original(argc, argv);
63
63
  }
64
64
 
65
- int install_fiber_hooks() {
65
+ int install_fiber_hooks(void) {
66
66
  rb_fiber_new_original = rb_fiber_new;
67
67
  patch_via_funchook(&rb_fiber_new_original, &rb_fiber_new_hook);
68
68
 
@@ -28,6 +28,6 @@ VALUE rb_fiber_new_hook(VALUE (*func)(ANYARGS), VALUE obj);
28
28
 
29
29
  VALUE rb_fiber_yield_hook(int argc, const VALUE *argv);
30
30
 
31
- static int install_fiber_hooks();
31
+ static int install_fiber_hooks(void);
32
32
 
33
33
  void Init_cs__assess_fiber_track(void);
@@ -115,23 +115,4 @@ void Init_cs__assess_module(void) {
115
115
 
116
116
  contrast_register_patch("Module", "module_eval",
117
117
  contrast_assess_module_module_eval);
118
- /*
119
- * We patch these for better ancestors handling, and only for older ruby
120
- * versions.
121
- */
122
- // if (rb_ver_below_three()) {
123
- /*
124
- * `included` is a private method. We should make it public, patch it,
125
- * and make our new method public
126
- */
127
- // contrast_register_patch("Module", "included",
128
- // contrast_assess_module_included);
129
- /*
130
- * The `prepend` patch may actually be the issue, if we're not properly
131
- * passing along the call/context. It could be that my attempt to fix
132
- * `included` left this section unreachable.
133
- */
134
- // contrast_register_patch("Module", "prepend",
135
- // contrast_assess_module_prepend);
136
- // }
137
118
  }
@@ -1,4 +1,4 @@
1
- #include "../cs__common/cs__common.h";
1
+ #include "../cs__common/cs__common.h"
2
2
  #include "ruby.h"
3
3
  #include <ruby/re.h>
4
4
 
@@ -28,8 +28,12 @@ void patch_via_funchook(void *original_function, void *hook_function) {
28
28
 
29
29
  void *funchook_lib_handle;
30
30
  void *funchook_reference, *(*funchook_create)(void);
31
+ /* This variables are used to load the funchook dylib */
32
+ #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
33
+ #pragma GCC diagnostic push
31
34
  int prepareResult, (*funchook_prepare)(void *, void **, void *);
32
35
  int installResult, (*funchook_install)(void *, int);
36
+ #pragma GCC diagnostic pop
33
37
 
34
38
  funchook_lib_handle =
35
39
  dlopen(StringValueCStr(funchook_path), RTLD_NOW | RTLD_GLOBAL);
@@ -55,7 +59,7 @@ void contrast_alias_method(const VALUE target, const char *to,
55
59
  ID2SYM(rb_intern(to)), ID2SYM(rb_intern(from)));
56
60
  }
57
61
 
58
- VALUE contrast_patcher() {
62
+ VALUE contrast_patcher(void) {
59
63
  return patcher;
60
64
  }
61
65
 
@@ -102,7 +106,7 @@ VALUE contrast_check_and_register_instance_patch(const char *module_name,
102
106
  VALUE(c_fn)(const int, VALUE *,
103
107
  const VALUE)) {
104
108
 
105
- VALUE object, method, is_prepended, patch_type;
109
+ VALUE object, method, is_prepended;
106
110
  /* check if method is prepended */
107
111
  object = rb_const_get(rb_cObject, rb_intern(module_name));
108
112
  method = ID2SYM(rb_intern(method_name));
@@ -119,7 +123,7 @@ VALUE contrast_check_and_register_instance_patch(const char *module_name,
119
123
  }
120
124
  }
121
125
 
122
- static VALUE
126
+ VALUE
123
127
  _contrast_register_patch(const char *module_name, const char *method_name,
124
128
  VALUE(c_fn)(const int, VALUE *, const VALUE),
125
129
  patch_impl patch) {
@@ -175,13 +179,6 @@ _contrast_register_patch(const char *module_name, const char *method_name,
175
179
  return SYM2ID(underlying_method_name);
176
180
  }
177
181
 
178
- int rb_ver_below_three() {
179
- int ruby_version =
180
- FIX2INT(rb_funcall(rb_const_get(rb_cObject, rb_intern("RUBY_VERSION")),
181
- rb_intern("to_i"), 0));
182
- return ruby_version < 3;
183
- }
184
-
185
182
  /* used for direct check on object: String.cs__prepended? *args */
186
183
  extern VALUE contrast_check_prepended(VALUE self, VALUE method_name,
187
184
  VALUE is_instance) {
@@ -200,17 +197,18 @@ extern VALUE contrast_lookout_prepended(VALUE self, VALUE object_name,
200
197
  return result;
201
198
  }
202
199
 
203
- static VALUE _contrast_check_prepended(VALUE object, VALUE method_name,
200
+ VALUE _contrast_check_prepended(VALUE object, VALUE method_name,
204
201
  VALUE is_instance) {
205
- VALUE entry, ancestors, object_idx, entry_methods;
202
+ VALUE entry, ancestors, entry_methods;
206
203
  VALUE result = Qfalse;
207
- int i;
208
- int y;
204
+ VALUE object_idx = Qnil;
205
+ long y;
206
+ unsigned long i;
209
207
 
210
208
  /* get self ancestors */
211
209
  ancestors = rb_mod_ancestors(object);
212
210
  /* get the size of the array */
213
- int length = RARRAY_LEN(ancestors);
211
+ unsigned long length = RARRAY_LEN(ancestors);
214
212
  /* Locate self in ancestors: */
215
213
  for (i = 0; i < length; ++i) {
216
214
  entry = rb_ary_entry(ancestors, i);
@@ -226,14 +224,14 @@ static VALUE _contrast_check_prepended(VALUE object, VALUE method_name,
226
224
  for (i = 0; i < object_idx; ++i) {
227
225
  entry = rb_ary_entry(ancestors, i);
228
226
  if (is_instance == Qtrue) {
229
- entry_methods = rb_class_instance_methods(1, entry, entry);
227
+ entry_methods = rb_class_instance_methods(1UL, &entry, entry);
230
228
  } else {
231
- entry_methods = rb_obj_singleton_methods(1, entry, entry);
229
+ entry_methods = rb_obj_singleton_methods(1UL, &entry, entry);
232
230
  }
233
231
 
234
232
  /* Loop through the instance/singleton methods of the prepended modules
235
233
  */
236
- int entry_methods_length = RARRAY_LEN(entry_methods);
234
+ long entry_methods_length = RARRAY_LEN(entry_methods);
237
235
  for (y = 0; y <= entry_methods_length; ++y) {
238
236
  if (rb_ary_entry(entry_methods, y) == method_name) {
239
237
  result = Qtrue;
@@ -244,6 +242,7 @@ static VALUE _contrast_check_prepended(VALUE object, VALUE method_name,
244
242
  break;
245
243
  }
246
244
  }
245
+
247
246
  return result;
248
247
  }
249
248
 
@@ -10,6 +10,9 @@ typedef enum {
10
10
  IMPL_PREPEND_SINGLETON,
11
11
  } patch_impl;
12
12
 
13
+ /* the unused variable warning is triggered for gcc only */
14
+ #pragma GCC diagnostic ignored "-Wunused-variable"
15
+ #pragma GCC diagnostic push
13
16
  static VALUE cs__send_method;
14
17
  static VALUE cs__alias_method_sym;
15
18
 
@@ -34,14 +37,7 @@ static VALUE rb_sym_alias_instance;
34
37
  static VALUE rb_sym_alias_singleton;
35
38
  static VALUE rb_sym_prepend_instance;
36
39
  static VALUE rb_sym_prepend_singleton;
37
-
38
- /*
39
- * Check if ruby version is < 3.0.0.
40
- * We are using this for handling ancestors of included modules.
41
- * Since this is fixed after Ruby 3.0.0 we should remove this after
42
- * dropping support for older versions, as no longer needed.
43
- */
44
- int rb_ver_below_three();
40
+ #pragma GCC diagnostic pop
45
41
 
46
42
  void patch_via_funchook(void *original_function, void *hook_function);
47
43
 
@@ -73,11 +69,11 @@ VALUE contrast_register_prepend_patch(const char *module_name,
73
69
  VALUE(c_fn)(const int, VALUE *,
74
70
  const VALUE));
75
71
 
76
- static VALUE _contrast_register_patch(const char *module_name, const char *method_name,
72
+ VALUE _contrast_register_patch(const char *module_name, const char *method_name,
77
73
  VALUE(c_fn)(const int, VALUE *, const VALUE),
78
74
  patch_impl patch_impl);
79
75
 
80
- static VALUE _contrast_check_prepended(VALUE self, VALUE method_name, VALUE is_instance);
76
+ VALUE _contrast_check_prepended(VALUE self, VALUE method_name, VALUE is_instance);
81
77
 
82
78
  extern VALUE contrast_check_prepended(VALUE self, VALUE method_name, VALUE is_instance);
83
79
 
@@ -90,7 +86,7 @@ VALUE contrast_check_and_register_instance_patch(const char *module_name,
90
86
  VALUE(c_fn)(const int, VALUE *,
91
87
  const VALUE));
92
88
 
93
- VALUE contrast_patcher();
89
+ VALUE contrast_patcher(void);
94
90
 
95
91
  void Init_cs__common(void);
96
92
 
@@ -97,8 +97,6 @@ VALUE rescue_func(VALUE arg1) {
97
97
  */
98
98
  exception = rb_errinfo();
99
99
  rb_exc_raise(exception);
100
-
101
- return Qnil;
102
100
  }
103
101
 
104
102
  /**
@@ -109,17 +107,18 @@ VALUE rescue_func(VALUE arg1) {
109
107
  *
110
108
  **/
111
109
  VALUE contrast_patch_call_ensure(const VALUE *args) {
112
- // we do not need to ensure that post patch is called if no error was thrown
110
+ /* we do not need to ensure that post patch is called if no error was thrown */
113
111
  if (!RTEST(rb_errinfo())) {
114
112
  return Qnil;
115
113
  }
116
114
 
117
115
  int argc;
118
- VALUE object, preshift, method_policy, method;
116
+ VALUE object, preshift, method_policy;
119
117
  VALUE *argv;
118
+ /* VALUE method; */
120
119
 
121
120
  object = args[0];
122
- method = args[1];
121
+ /* method = args[1]; */
123
122
  argc = NUM2INT(args[2]);
124
123
  argv = (VALUE *)args[3];
125
124
  method_policy = args[4];
@@ -137,8 +136,8 @@ VALUE ensure_wrapper(const VALUE *args) {
137
136
  original_args = (VALUE)args[1];
138
137
  ensure_args = (VALUE)args[2];
139
138
 
140
- // this ensure if being treated as a rescue due to issues surrounding
141
- // Kernel#throw
139
+ /* this ensure if being treated as a rescue due to issues surrounding
140
+ Kernel#throw */
142
141
  return rb_ensure(original_method, original_args, contrast_patch_call_ensure,
143
142
  (VALUE)ensure_args);
144
143
  }
@@ -154,7 +153,7 @@ VALUE contrast_call_super(const VALUE *args) {
154
153
 
155
154
  VALUE contrast_run_patches(const VALUE *wrapped_args) {
156
155
  VALUE impl, method, method_policy, object, original_args, original_ret,
157
- preshift, transformed_ret;
156
+ preshift;
158
157
  int argc;
159
158
  VALUE *argv;
160
159
  VALUE ensure_args[6];
@@ -257,9 +256,15 @@ VALUE contrast_ensure_function(const VALUE method_policy) {
257
256
 
258
257
  VALUE contrast_patch_dispatch(const int argc, const VALUE *argv,
259
258
  const patch_impl impl, const VALUE object) {
259
+ /*
260
+ * Silence the known variable unused warning detected by compiler.
261
+ * Since this Variable is set by cases and we check if it is set or not.
262
+ * To disalbe this remove the -Wno-maybe-uninitialized flag.
263
+ */
264
+
260
265
  VALUE cs__method, known, method, method_policy;
261
266
  VALUE original_args[4];
262
- int do_contrast, nested_scope;
267
+ long do_contrast, nested_scope;
263
268
 
264
269
  /* Do Contrast analysis, unless our subsequent checks tell us no. */
265
270
  do_contrast = 1;
@@ -369,6 +374,8 @@ call_original:
369
374
  case IMPL_PREPEND_SINGLETON:
370
375
  return contrast_call_super(original_args);
371
376
  };
377
+
378
+ return Qfalse;
372
379
  }
373
380
 
374
381
  VALUE contrast_alias_instance_patch(const int argc, const VALUE *argv,
@@ -490,21 +497,6 @@ VALUE contrast_patch_prepend(const VALUE self, const VALUE originalModule,
490
497
  }
491
498
  rb_prepend_module(originalModule, module);
492
499
 
493
- if (rb_ver_below_three()) {
494
- VALUE module_at;
495
- VALUE rb_incl_in_mod_ary =
496
- rb_funcall(originalModule, rb_intern("included_in"), 0);
497
- if (RB_TYPE_P(rb_incl_in_mod_ary, T_ARRAY)) {
498
- int i = 0;
499
- int size = RARRAY_LEN(rb_incl_in_mod_ary);
500
- for (i = 0; i < size; ++i) {
501
- module_at = rb_ary_entry(rb_incl_in_mod_ary, i);
502
- if (RB_TYPE_P(module_at, T_MODULE)) {
503
- rb_include_module(module_at, module);
504
- }
505
- }
506
- }
507
- }
508
500
  return Qtrue;
509
501
  }
510
502
 
@@ -2,18 +2,97 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'mkmf'
5
+ require 'rbconfig'
5
6
  require_relative '../lib/contrast/agent/version'
6
7
 
8
+ # The mkmf.rb file uses all passed flags from Ruby configuration (RbConfig::CONFIG) on
9
+ # Ruby build time. Problem with Clang and GCC is that it do not keep up with c89 and finds
10
+ # error on including <ryby.h> as not allowing inline variables.
11
+ #
12
+ # Ruby inlining is a C99 feature that is allowed to be used, because the Ruby configure script
13
+ # can work around the absence of the inline feature with a simple #define:
14
+ #
15
+ # ifndef __cplusplus
16
+ # define inline
17
+ # endif
18
+ #
19
+ # There is difference between using c89 and gnu89, as the latter is extended version of the
20
+ # 1989 standard allowing features like // comments for example. This makes the use of the
21
+ # gnu not favorable since it will skip some checks and would make wholes in the c89 standard
22
+ # support.
23
+ #
24
+ # We can directly append the CFLAGS we need with ENV variable used to create the makefile.
25
+ # MAKEFILE_CONFIG is extension of the RbConfig::CONFIG used to build the Ruby itself.
26
+ # So if we try to run c89 on clang it will brake because of detecting errors from external
27
+ # library used - Ruby itself build with different standard as it seems. This means the
28
+ # Ruby must be compiled beforehand with the compiler forced to C89.
29
+ #
30
+ # This makes the C dialect of choice to be gnu89 with strict pedantic warnings reported as errors,
31
+ # and making the compiler configurable by flags:
32
+ STANDARD_FLAGS = '-std=gnu89'
33
+ CLANG = 'clang'
34
+
35
+ # TODO: RUBY-999999 Add -pedantic flag, remove all warning flags and see to it that as many as possible become obsolete.
36
+ # Note: Adding -pedantic could raise <ruby.h> warnings, and we are not in control of that code.
37
+ # e.g. error: '_Bool' is a C99 extension [-Werror,-Wc99-extensions] ; empty macros and etc.
38
+ #
39
+ # -Wno-int-conversion => Passing VALUEs as function args but required as unsigned long parameters.
40
+ # -Werror => report all warnings as errors
41
+ # -Wshorten-64-to-32 => is recognized by clang but not in gcc.
42
+ # Use alternative if viable. [Wno-narrowing]
43
+ # -Wno-maybe-uninitialized is used by clang but not gcc
44
+ #
45
+ # Note: Clang supports old style function definition e.g. void func () {}
46
+ # but the gcc is not.
47
+ # make sure to add parameters type => void func (void) {}.
48
+ # All Changes must be tested against both clang and gcc.
49
+ WARNING_FLAGS = %w[
50
+ -Wno-language-extension-token -Wno-incompatible-function-pointer-types
51
+ -Wno-declaration-after-statement -Wno-variadic-macros -Wno-int-conversion
52
+ -Wno-incompatible-pointer-types -Wno-narrowing
53
+ ].freeze # rubocop:disable Security/Object/Freeze
54
+
55
+ # Flags that are only recognized by gcc:
56
+ GCC_FLAGS = %w[-Wno-maybe-uninitialized].freeze # rubocop:disable Security/Object/Freeze
57
+
58
+ # Extend $CFLAGS passed directly to compiler in ruby mkmf
59
+ def extend_cflags
60
+ $CFLAGS += " #{ [STANDARD_FLAGS, WARNING_FLAGS].flatten.join(' ') }"
61
+ # Extend with GCC specific flags:
62
+ unless RbConfig::MAKEFILE_CONFIG['CC'].downcase.include?(CLANG) ||
63
+ RbConfig::MAKEFILE_CONFIG['CPP'].downcase.include?(CLANG) ||
64
+ RbConfig::CONFIG['CC'].downcase.include?(CLANG)
65
+
66
+ $CFLAGS += " #{ GCC_FLAGS.flatten.join(' ') }"
67
+ end
68
+ end
69
+
7
70
  def make!
8
71
  create_makefile("#{ $TO_MAKE }/#{ $TO_MAKE }")
9
72
  end
10
73
 
74
+ # -----------------------------------------------------------------------
75
+ # | MOVING CODE BELLOW THIS SECTION MAY BRAKE MAKEFILE. ORDER MATTERS! |
76
+ # ----------------------------------------------------------------------
77
+
11
78
  def ext_path
12
79
  # __dir__ is relative to the file you're reading.
13
80
  # this file you're reading is presently within $APP_ROOT/ext/.
14
81
  __dir__
15
82
  end
16
83
 
84
+ # We need to first build funchook which relies on ext_path method. This enables the require of
85
+ # funchook.h file. Then we can pass CFLAGS and extend makefile flags and invoke make!
17
86
  require_relative './build_funchook'
18
87
 
88
+ # Extended flags are mainly tested with clang and gcc. Experience with other compilers may vary.
89
+ # To that end if something brakes on client side we must have a mechanism to go back to previous
90
+ # non strict gnu89 standard and be able to maintain the build.
91
+ # We can disable newly added changes with this setting CONTRAST_USE_C89=false.
92
+ extend_cflags unless ENV['CONTRAST__USE_GNU89'] == 'false'
93
+
94
+ # use same C compiler if set.
95
+ RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
96
+
97
+ # Generate Makefile.
19
98
  make!
@@ -58,7 +58,7 @@ module Contrast
58
58
  # can skip policy loading.
59
59
  return if disabled_globally?
60
60
 
61
- policy_data = JSON.parse(string)
61
+ policy_data = Contrast::Utils::Json.parse(string)
62
62
 
63
63
  policy_data[SOURCES_KEY].each do |source_hash|
64
64
  source = Contrast::Agent::Assess::Policy::SourceNode.new(source_hash)
@@ -91,6 +91,7 @@ module Contrast
91
91
  process_source(source_node, value, source_data, source_type, source_name, *args)
92
92
  end
93
93
  end
94
+ nil
94
95
  rescue StandardError => e
95
96
  logger.warn('Unable to apply source', e, node_id: source_node.id)
96
97
  end
@@ -28,7 +28,7 @@ module Contrast
28
28
  end
29
29
 
30
30
  def from_hash_string string
31
- policy_data = JSON.parse(string)
31
+ policy_data = Contrast::Utils::Json.parse(string)
32
32
 
33
33
  policy_data[DEADZONES_KEY].each do |deadzone_hash|
34
34
  add_node(node_type.new(deadzone_hash))
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'json'
4
+ require 'contrast/utils/json'
5
5
  require 'singleton'
6
6
 
7
7
  require 'contrast'
@@ -71,7 +71,7 @@ module Contrast
71
71
  # it, so in that case, we can skip policy loading.
72
72
  return if disabled_globally?
73
73
 
74
- policy_data = JSON.parse(string)
74
+ policy_data = Contrast::Utils::Json.parse(string)
75
75
 
76
76
  policy_data[RULES_KEY].each do |rule_hash|
77
77
  rule_hash[TRIGGERS_KEY].each do |trigger_hash|
@@ -26,11 +26,14 @@ module Contrast
26
26
  # Thread that will process all the InputAnalysisResults that have a score level of WORTHWATCHING and
27
27
  # sends results to TeamServer
28
28
  def start_thread!
29
+ return unless attempt_to_start?
29
30
  return if running?
30
31
 
31
32
  @_thread = Contrast::Agent::Thread.new do
32
33
  logger.info('[WorthWatchingAnalyzer] Starting thread.')
33
34
  loop do
35
+ break unless attempt_to_start?
36
+
34
37
  sleep(REPORT_INTERVAL_SECOND)
35
38
  next if queue.empty?
36
39
 
@@ -94,7 +94,7 @@ module Contrast
94
94
  #
95
95
  # @return [Boolean]
96
96
  def json? string
97
- return true if JSON.parse(string)
97
+ return true if Contrast::Utils::Json.parse(string)
98
98
  rescue StandardError
99
99
  false
100
100
  end
@@ -10,10 +10,12 @@ require 'contrast/agent/telemetry/exception'
10
10
  module Contrast
11
11
  module Agent
12
12
  # This module will hold everything essential to reporting to TeamServer
13
- class Reporter < WorkerThread
13
+ class Reporter < WorkerThread # rubocop:disable Metrics/ClassLength
14
14
  include Contrast::Components::Logger::InstanceMethods
15
15
  include Contrast::Utils::ObjectShare
16
16
 
17
+ # How many tries to reconnect the Reporter should make.
18
+ RETRY_ATTEMPTS = 10
17
19
  MAX_QUEUE_SIZE = 1000
18
20
 
19
21
  class << self
@@ -35,13 +37,17 @@ module Contrast
35
37
  end
36
38
 
37
39
  def start_thread!
40
+ return unless attempt_to_start?
38
41
  return if running?
39
42
 
43
+ @connection_attempts = 0
44
+
40
45
  client.startup!(connection)
41
46
  @_thread = Contrast::Agent::Thread.new do
42
47
  logger.debug('[Reporter] Starting background Reporter thread.')
43
48
  loop do
44
49
  next unless connected?
50
+ break unless attempt_to_start?
45
51
 
46
52
  process_event(queue.pop)
47
53
  rescue StandardError => e
@@ -124,10 +130,19 @@ module Contrast
124
130
  #
125
131
  # @return [Boolean]
126
132
  def connected?
127
- return true if client && connection
133
+ if client && connection
134
+ # Try to resend startup messages now with connection:
135
+ client.startup!(connection) unless client.status.startup_messages_sent?
136
+ return true
137
+ end
128
138
 
129
- logger.debug('[Reporter] No client/connection; sleeping...', client: client, connection: connection)
130
- sleep(5)
139
+ logger.debug('[Reporter] No client/connection; sleeping...')
140
+ @connection_attempts += 1
141
+ if @connection_attempts >= RETRY_ATTEMPTS
142
+ logger.debug('[Reporter] shutting down..')
143
+ Contrast::AGENT.disable!
144
+ end
145
+ sleep(5) unless Contrast::AGENT.disabled?
131
146
  false
132
147
  end
133
148
 
@@ -0,0 +1,32 @@
1
+ # Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'contrast/agent/reporting/reporting_events/reporting_event'
5
+ require 'contrast/config'
6
+
7
+ module Contrast
8
+ module Agent
9
+ module Reporting
10
+ # AgentStartup Event which sends the agent data to TeamServer on the startup of a server or process,
11
+ # used to create a new Server entity there.
12
+ class AgentEffectiveConfig < Contrast::Agent::Reporting::ReportingEvent
13
+ # @param diagnostics [Contrast::Agent::DiagnosticsConfig::Diagnostics] current diagnostics
14
+ def initialize diagnostics
15
+ @event_method = :PUT
16
+ @event_endpoint = Contrast::Agent::Reporting::Endpoints.effective_config
17
+ @event_type = :effective_config
18
+ @diagnostics = diagnostics
19
+ super()
20
+ end
21
+
22
+ def file_name
23
+ 'agent-effective-config'
24
+ end
25
+
26
+ def to_controlled_hash
27
+ @diagnostics.to_controlled_hash
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -83,6 +83,13 @@ module Contrast
83
83
  end
84
84
  end
85
85
 
86
+ # @return [String, nil]
87
+ def effective_config
88
+ with_rescue do
89
+ "#{ application_endpoint }/effective-config".cs__freeze
90
+ end
91
+ end
92
+
86
93
  private
87
94
 
88
95
  # Returns the URL needed to connect to endpoints in TeamServer required for application related information.
@@ -11,7 +11,7 @@ module Contrast
11
11
  # This class will build the required headers for agent reporting to TS
12
12
  class Headers
13
13
  attr_reader :app_name, :api_key, :agent_version, :app_language, :app_path, :app_version, :authorization,
14
- :server_name, :server_path, :server_type, :content_type, :encoding, :compression
14
+ :server_name, :server_path, :server_type, :content_type, :encoding, :compression, :session_id
15
15
 
16
16
  include Contrast::Utils::ObjectShare
17
17
  ENCODING = 'base64'
@@ -29,6 +29,7 @@ module Contrast
29
29
  @server_name = Base64.strict_encode64(Contrast::APP_CONTEXT.server_name)
30
30
  @server_path = Base64.strict_encode64(Contrast::APP_CONTEXT.server_path)
31
31
  @server_type = Base64.strict_encode64(Contrast::APP_CONTEXT.server_type)
32
+ @session_id = Contrast::CONFIG.session_id
32
33
  @content_type = CONTENT_TYPE
33
34
  @encoding = ENCODING
34
35
  @compression = COMPRESSION
@@ -46,6 +47,7 @@ module Contrast
46
47
  server_name: @server_name,
47
48
  server_path: @server_path,
48
49
  server_type: @server_type,
50
+ 'Session-ID': @session_id,
49
51
  content_type: @content_type,
50
52
  encoding: @encoding,
51
53
  compression: @compression