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

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.
@@ -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