libddwaf 1.15.0.0.0-x86_64-linux → 1.18.0.0.1-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,313 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require 'datadog/appsec/waf/version'
5
+
6
+ module Datadog
7
+ module AppSec
8
+ module WAF
9
+ # FFI-binding for C-libddwaf
10
+ # See https://github.com/DataDog/libddwaf
11
+ module LibDDWAF
12
+ # An exception binding raises in most of the cases
13
+ class Error < StandardError
14
+ attr_reader :diagnostics
15
+
16
+ def initialize(msg, diagnostics: nil)
17
+ @diagnostics = diagnostics
18
+
19
+ super(msg)
20
+ end
21
+ end
22
+
23
+ extend ::FFI::Library
24
+
25
+ def self.local_os
26
+ if RUBY_ENGINE == 'jruby'
27
+ os_name = java.lang.System.get_property('os.name')
28
+
29
+ os = case os_name
30
+ when /linux/i then 'linux'
31
+ when /mac/i then 'darwin'
32
+ else raise Error, "unsupported JRuby os.name: #{os_name.inspect}"
33
+ end
34
+
35
+ return os
36
+ end
37
+
38
+ Gem::Platform.local.os
39
+ end
40
+
41
+ def self.local_version
42
+ return nil unless local_os == 'linux'
43
+
44
+ # Old rubygems don't handle non-gnu linux correctly
45
+ return ::Regexp.last_match(1) if RUBY_PLATFORM =~ /linux-(.+)$/
46
+
47
+ 'gnu'
48
+ end
49
+
50
+ def self.local_cpu
51
+ if RUBY_ENGINE == 'jruby'
52
+ os_arch = java.lang.System.get_property('os.arch')
53
+
54
+ cpu = case os_arch
55
+ when 'amd64' then 'x86_64'
56
+ when 'aarch64' then local_os == 'darwin' ? 'arm64' : 'aarch64'
57
+ else raise Error, "unsupported JRuby os.arch: #{os_arch.inspect}"
58
+ end
59
+
60
+ return cpu
61
+ end
62
+
63
+ Gem::Platform.local.cpu
64
+ end
65
+
66
+ def self.source_dir
67
+ __dir__ || raise('__dir__ is nil: eval?')
68
+ end
69
+
70
+ def self.vendor_dir
71
+ File.join(source_dir, '../../../../vendor')
72
+ end
73
+
74
+ def self.libddwaf_vendor_dir
75
+ File.join(vendor_dir, 'libddwaf')
76
+ end
77
+
78
+ def self.shared_lib_triplet(version: local_version)
79
+ version ? "#{local_os}-#{version}-#{local_cpu}" : "#{local_os}-#{local_cpu}"
80
+ end
81
+
82
+ def self.libddwaf_dir
83
+ default = File.join(libddwaf_vendor_dir,
84
+ "libddwaf-#{Datadog::AppSec::WAF::VERSION::BASE_STRING}-#{shared_lib_triplet}")
85
+ candidates = [
86
+ default
87
+ ]
88
+
89
+ if local_os == 'linux'
90
+ candidates << File.join(libddwaf_vendor_dir,
91
+ "libddwaf-#{Datadog::AppSec::WAF::VERSION::BASE_STRING}-#{shared_lib_triplet(version: nil)}")
92
+ end
93
+
94
+ candidates.find { |d| Dir.exist?(d) } || default
95
+ end
96
+
97
+ def self.shared_lib_extname
98
+ if Gem::Platform.local.os == 'darwin'
99
+ '.dylib'
100
+ elsif Gem::Platform.local.os == 'java' && java.lang.System.get_property('os.name').match(/mac/i)
101
+ '.dylib'
102
+ else
103
+ '.so'
104
+ end
105
+ end
106
+
107
+ def self.shared_lib_path
108
+ File.join(libddwaf_dir, 'lib', "libddwaf#{shared_lib_extname}")
109
+ end
110
+
111
+ ffi_lib [shared_lib_path]
112
+
113
+ # version
114
+
115
+ attach_function :ddwaf_get_version, [], :string
116
+
117
+ # ddwaf::object data structure
118
+
119
+ DDWAF_OBJ_TYPE = enum :ddwaf_obj_invalid, 0,
120
+ :ddwaf_obj_signed, 1 << 0,
121
+ :ddwaf_obj_unsigned, 1 << 1,
122
+ :ddwaf_obj_string, 1 << 2,
123
+ :ddwaf_obj_array, 1 << 3,
124
+ :ddwaf_obj_map, 1 << 4,
125
+ :ddwaf_obj_bool, 1 << 5,
126
+ :ddwaf_obj_float, 1 << 6,
127
+ :ddwaf_obj_null, 1 << 7
128
+
129
+ typedef DDWAF_OBJ_TYPE, :ddwaf_obj_type
130
+
131
+ typedef :pointer, :charptr
132
+ typedef :pointer, :charptrptr
133
+
134
+ # Ruby representation of C uint32_t
135
+ class UInt32Ptr < ::FFI::Struct
136
+ layout :value, :uint32
137
+ end
138
+
139
+ typedef UInt32Ptr.by_ref, :uint32ptr
140
+
141
+ # Ruby representation of C uint64_t
142
+ class UInt64Ptr < ::FFI::Struct
143
+ layout :value, :uint64
144
+ end
145
+
146
+ typedef UInt64Ptr.by_ref, :uint64ptr
147
+
148
+ # Ruby representation of C size_t
149
+ class SizeTPtr < ::FFI::Struct
150
+ layout :value, :size_t
151
+ end
152
+
153
+ typedef SizeTPtr.by_ref, :sizeptr
154
+
155
+ # Ruby representation of C union
156
+ class ObjectValueUnion < ::FFI::Union
157
+ layout :stringValue, :charptr,
158
+ :uintValue, :uint64,
159
+ :intValue, :int64,
160
+ :array, :pointer,
161
+ :boolean, :bool,
162
+ :f64, :double
163
+ end
164
+
165
+ # Ruby representation of ddwaf_object
166
+ # See https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L94C1-L115C3
167
+ class Object < ::FFI::Struct
168
+ layout :parameterName, :charptr,
169
+ :parameterNameLength, :uint64,
170
+ :valueUnion, ObjectValueUnion,
171
+ :nbEntries, :uint64,
172
+ :type, :ddwaf_obj_type
173
+ end
174
+
175
+ typedef Object.by_ref, :ddwaf_object
176
+
177
+ ## setters
178
+
179
+ attach_function :ddwaf_object_invalid, [:ddwaf_object], :ddwaf_object
180
+ attach_function :ddwaf_object_string, [:ddwaf_object, :string], :ddwaf_object
181
+ attach_function :ddwaf_object_stringl, [:ddwaf_object, :charptr, :size_t], :ddwaf_object
182
+ attach_function :ddwaf_object_stringl_nc, [:ddwaf_object, :charptr, :size_t], :ddwaf_object
183
+ attach_function :ddwaf_object_string_from_unsigned, [:ddwaf_object, :uint64], :ddwaf_object
184
+ attach_function :ddwaf_object_string_from_signed, [:ddwaf_object, :int64], :ddwaf_object
185
+ attach_function :ddwaf_object_unsigned, [:ddwaf_object, :uint64], :ddwaf_object
186
+ attach_function :ddwaf_object_signed, [:ddwaf_object, :int64], :ddwaf_object
187
+ attach_function :ddwaf_object_bool, [:ddwaf_object, :bool], :ddwaf_object
188
+ attach_function :ddwaf_object_null, [:ddwaf_object], :ddwaf_object
189
+ attach_function :ddwaf_object_float, [:ddwaf_object, :double], :ddwaf_object
190
+
191
+ attach_function :ddwaf_object_array, [:ddwaf_object], :ddwaf_object
192
+ attach_function :ddwaf_object_array_add, [:ddwaf_object, :ddwaf_object], :bool
193
+
194
+ attach_function :ddwaf_object_map, [:ddwaf_object], :ddwaf_object
195
+ attach_function :ddwaf_object_map_add, [:ddwaf_object, :string, :pointer], :bool
196
+ attach_function :ddwaf_object_map_addl, [:ddwaf_object, :charptr, :size_t, :pointer], :bool
197
+ attach_function :ddwaf_object_map_addl_nc, [:ddwaf_object, :charptr, :size_t, :pointer], :bool
198
+
199
+ ## getters
200
+
201
+ attach_function :ddwaf_object_type, [:ddwaf_object], DDWAF_OBJ_TYPE
202
+ attach_function :ddwaf_object_size, [:ddwaf_object], :uint64
203
+ attach_function :ddwaf_object_length, [:ddwaf_object], :size_t
204
+ attach_function :ddwaf_object_get_key, [:ddwaf_object, :sizeptr], :charptr
205
+ attach_function :ddwaf_object_get_string, [:ddwaf_object, :sizeptr], :charptr
206
+ attach_function :ddwaf_object_get_unsigned, [:ddwaf_object], :uint64
207
+ attach_function :ddwaf_object_get_signed, [:ddwaf_object], :int64
208
+ attach_function :ddwaf_object_get_index, [:ddwaf_object, :size_t], :ddwaf_object
209
+ attach_function :ddwaf_object_get_bool, [:ddwaf_object], :bool
210
+ attach_function :ddwaf_object_get_float, [:ddwaf_object], :double
211
+
212
+ ## freeers
213
+
214
+ ObjectFree = attach_function :ddwaf_object_free, [:ddwaf_object], :void
215
+ ObjectNoFree = ::FFI::Pointer::NULL
216
+
217
+ # main handle
218
+
219
+ typedef :pointer, :ddwaf_handle
220
+ typedef Object.by_ref, :ddwaf_rule
221
+
222
+ callback :ddwaf_object_free_fn, [:ddwaf_object], :void
223
+
224
+ # Ruby representation of ddwaf_config
225
+ # https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L129-L152
226
+ class Config < ::FFI::Struct
227
+ # Ruby representation of ddwaf_config_limits
228
+ # https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L131-L138
229
+ class Limits < ::FFI::Struct
230
+ layout :max_container_size, :uint32,
231
+ :max_container_depth, :uint32,
232
+ :max_string_length, :uint32
233
+ end
234
+
235
+ # Ruby representation of ddwaf_config_obfuscator
236
+ # https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L141-L146
237
+ class Obfuscator < ::FFI::Struct
238
+ layout :key_regex, :pointer, # should be :charptr
239
+ :value_regex, :pointer # should be :charptr
240
+ end
241
+
242
+ layout :limits, Limits,
243
+ :obfuscator, Obfuscator,
244
+ :free_fn, :pointer # :ddwaf_object_free_fn
245
+ end
246
+
247
+ typedef Config.by_ref, :ddwaf_config
248
+
249
+ attach_function :ddwaf_init, [:ddwaf_rule, :ddwaf_config, :ddwaf_object], :ddwaf_handle
250
+ attach_function :ddwaf_update, [:ddwaf_handle, :ddwaf_object, :ddwaf_object], :ddwaf_handle
251
+ attach_function :ddwaf_destroy, [:ddwaf_handle], :void
252
+
253
+ attach_function :ddwaf_known_addresses, [:ddwaf_handle, UInt32Ptr], :charptrptr
254
+
255
+ # updating
256
+
257
+ DDWAF_RET_CODE = enum :ddwaf_err_internal, -3,
258
+ :ddwaf_err_invalid_object, -2,
259
+ :ddwaf_err_invalid_argument, -1,
260
+ :ddwaf_ok, 0,
261
+ :ddwaf_match, 1
262
+ typedef DDWAF_RET_CODE, :ddwaf_ret_code
263
+
264
+ # running
265
+
266
+ typedef :pointer, :ddwaf_context
267
+
268
+ attach_function :ddwaf_context_init, [:ddwaf_handle], :ddwaf_context
269
+ attach_function :ddwaf_context_destroy, [:ddwaf_context], :void
270
+
271
+ # Ruby representation of ddwaf_result
272
+ # See https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L154-L173
273
+ class Result < ::FFI::Struct
274
+ layout :timeout, :bool,
275
+ :events, Object,
276
+ :actions, Object,
277
+ :derivatives, Object,
278
+ :total_runtime, :uint64
279
+ end
280
+
281
+ typedef Result.by_ref, :ddwaf_result
282
+ typedef :uint64, :timeout_us
283
+
284
+ attach_function :ddwaf_run, [:ddwaf_context, :ddwaf_object, :ddwaf_object, :ddwaf_result, :timeout_us], :ddwaf_ret_code, blocking: true
285
+ attach_function :ddwaf_result_free, [:ddwaf_result], :void
286
+
287
+ # logging
288
+
289
+ DDWAF_LOG_LEVEL = enum :ddwaf_log_trace,
290
+ :ddwaf_log_debug,
291
+ :ddwaf_log_info,
292
+ :ddwaf_log_warn,
293
+ :ddwaf_log_error,
294
+ :ddwaf_log_off
295
+ typedef DDWAF_LOG_LEVEL, :ddwaf_log_level
296
+
297
+ callback :ddwaf_log_cb, [:ddwaf_log_level, :string, :string, :uint, :charptr, :uint64], :void
298
+
299
+ attach_function :ddwaf_set_log_cb, [:ddwaf_log_cb, :ddwaf_log_level], :bool
300
+
301
+ DEFAULT_MAX_CONTAINER_SIZE = 256
302
+ DEFAULT_MAX_CONTAINER_DEPTH = 20
303
+ DEFAULT_MAX_STRING_LENGTH = 16_384 # in bytes, UTF-8 worst case being 4x size in terms of code point)
304
+
305
+ DDWAF_MAX_CONTAINER_SIZE = 256
306
+ DDWAF_MAX_CONTAINER_DEPTH = 20
307
+ DDWAF_MAX_STRING_LENGTH = 4096
308
+
309
+ DDWAF_RUN_TIMEOUT = 5000
310
+ end
311
+ end
312
+ end
313
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ module WAF
6
+ # Ruby representation of the ddwaf_result of a libddwaf run.
7
+ # See https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L159-L173
8
+ class Result
9
+ attr_reader :status, :events, :total_runtime, :timeout, :actions, :derivatives
10
+
11
+ def initialize(status, events, total_runtime, timeout, actions, derivatives)
12
+ @status = status
13
+ @events = events
14
+ @total_runtime = total_runtime
15
+ @timeout = timeout
16
+ @actions = actions
17
+ @derivatives = derivatives
18
+ end
19
+
20
+ def to_h
21
+ {
22
+ status: @status,
23
+ events: @events,
24
+ total_runtime: @total_runtime,
25
+ timeout: @timeout,
26
+ actions: @actions,
27
+ derivatives: @derivatives
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -2,8 +2,8 @@ module Datadog
2
2
  module AppSec
3
3
  module WAF
4
4
  module VERSION
5
- BASE_STRING = '1.15.0'
6
- STRING = "#{BASE_STRING}.0.0"
5
+ BASE_STRING = '1.18.0'
6
+ STRING = "#{BASE_STRING}.0.1"
7
7
  MINIMUM_RUBY_VERSION = '2.5'
8
8
  end
9
9
  end