libsqreen 0.3.0.0.3

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,53 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ require 'rbconfig'
5
+ require 'shellwords'
6
+
7
+ module LibSqreen
8
+ module Paths
9
+ module_function
10
+
11
+ def include_paths
12
+ [Shellwords.escape(File.join(vendored_source_path, 'libsqreen', 'include'))]
13
+ end
14
+
15
+ def object_paths
16
+ objects = [
17
+ File.join(vendored_source_path, 'libsqreen', cpu, platform, libname),
18
+ ]
19
+
20
+ return objects if platform == 'darwin'
21
+
22
+ objects << File.join(vendored_source_path, 'libc++', cpu, platform, 'libc++.a')
23
+ objects << File.join(vendored_source_path, 'libc++', cpu, platform, 'libc++abi.a')
24
+ objects << File.join(vendored_source_path, 'libc++', cpu, platform, 'libunwind.a')
25
+
26
+ objects
27
+ end
28
+
29
+ def header_files
30
+ ['waf.h']
31
+ end
32
+
33
+ def config
34
+ RbConfig::MAKEFILE_CONFIG
35
+ end
36
+
37
+ def platform
38
+ RUBY_PLATFORM =~ /(solaris|darwin|linux(?=-.*$)|linux$)/ && $1
39
+ end
40
+
41
+ def cpu
42
+ RUBY_PLATFORM =~ /^(universal\.|)(.*?)-/ && $2
43
+ end
44
+
45
+ def libname
46
+ "libsqreen.#{config['LIBEXT']}"
47
+ end
48
+
49
+ def vendored_source_path
50
+ File.expand_path('../../../vendor', __FILE__)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ require 'mkmf'
5
+
6
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../../ext'))
7
+ require 'libsqreen/location'
8
+ location = LibSqreen::Location.load!
9
+ begin
10
+ location.verify!
11
+ rescue LibSqreen::Location::Vendor::HeaderNotFound
12
+ puts 'could not find header. fallback to stubbing.'
13
+ $defs.push('-DLIBSQREEN_STUB')
14
+ rescue LibSqreen::Location::Vendor::ArchiveNotFound
15
+ puts "could not find binary archive: native features for platform #{RUBY_PLATFORM} not supported. fallback to stubbing."
16
+ $defs.push('-DLIBSQREEN_STUB')
17
+ else
18
+ location.configure
19
+
20
+ $CFLAGS += ' -std=c99'
21
+ if RUBY_PLATFORM =~ /linux/
22
+ version_script_path = File.expand_path(File.join(File.dirname(__FILE__), '../../ext/libsqreen_extension/libsqreen_extension.version'))
23
+ $LDFLAGS += " -lpthread -Wl,--version-script='#{version_script_path}'"
24
+ end
25
+ end
26
+
27
+ create_makefile('libsqreen_extension')
@@ -0,0 +1,559 @@
1
+ // Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ // Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ #include <ruby.h>
5
+ #include <stdbool.h>
6
+
7
+ #ifndef LIBSQREEN_STUB
8
+
9
+ #include <waf.h>
10
+
11
+ /* boxes */
12
+
13
+ // PWArgs box
14
+ struct libsqreen_waf_args {
15
+ void *boxed;
16
+ };
17
+
18
+ static void
19
+ libsqreen_waf_args_free(void *b) {
20
+ struct libsqreen_waf_args *box = b;
21
+
22
+ if (box == NULL) {
23
+ return;
24
+ }
25
+
26
+ if (box->boxed == NULL) {
27
+ return;
28
+ }
29
+
30
+ box->boxed = NULL;
31
+ }
32
+
33
+ static VALUE
34
+ libsqreen_waf_args_alloc(VALUE klass) {
35
+ VALUE obj;
36
+ struct libsqreen_waf_args *box;
37
+
38
+ obj = Data_Make_Struct(klass, struct libsqreen_waf_args, NULL, libsqreen_waf_args_free, box);
39
+
40
+ box->boxed = NULL;
41
+
42
+ return obj;
43
+ }
44
+
45
+ static VALUE
46
+ libsqreen_waf_args_klass() {
47
+ VALUE mLibSqreen;
48
+ VALUE mWAF;
49
+ VALUE cArgs;
50
+
51
+ mLibSqreen = rb_const_get(rb_cObject, rb_intern("LibSqreen"));
52
+ mWAF = rb_const_get(mLibSqreen, rb_intern("WAF"));
53
+ cArgs = rb_const_get(mWAF, rb_intern("Args"));
54
+
55
+ return cArgs;
56
+ }
57
+
58
+ static VALUE
59
+ libsqreen_waf_args_new() {
60
+ VALUE cArgs;
61
+ ID new;
62
+ VALUE waf_args;
63
+
64
+ cArgs = libsqreen_waf_args_klass();
65
+ new = rb_intern("new");
66
+ waf_args = rb_funcall(cArgs, new, 0);
67
+
68
+ return waf_args;
69
+ }
70
+
71
+ static VALUE
72
+ libsqreen_waf_args_new_from_hash(VALUE hash) {
73
+ VALUE cArgs;
74
+ ID new;
75
+ VALUE waf_args;
76
+
77
+ cArgs = libsqreen_waf_args_klass();
78
+ new = rb_intern("new");
79
+ waf_args = rb_funcall(cArgs, new, 1, hash);
80
+
81
+ return waf_args;
82
+ }
83
+
84
+ static void
85
+ libsqreen_waf_args_set_boxed(VALUE self, PWArgs *args) {
86
+ struct libsqreen_waf_args *box;
87
+ Data_Get_Struct(self, struct libsqreen_waf_args, box);
88
+ box->boxed = (void *)args;
89
+ }
90
+
91
+ static PWArgs *
92
+ libsqreen_waf_args_get_boxed(VALUE self) {
93
+ PWArgs *args;
94
+
95
+ struct libsqreen_waf_args *box;
96
+ Data_Get_Struct(self, struct libsqreen_waf_args, box);
97
+ args = (PWArgs *)box->boxed;
98
+ return args;
99
+ }
100
+
101
+ /* wrappers */
102
+
103
+ static VALUE
104
+ libsqreen_waf_module() {
105
+ VALUE mLibSqreen;
106
+ VALUE mWAF;
107
+
108
+ mLibSqreen = rb_const_get(rb_cObject, rb_intern("LibSqreen"));
109
+ mWAF = rb_const_get(mLibSqreen, rb_intern("WAF"));
110
+
111
+ return mWAF;
112
+ }
113
+
114
+ static VALUE
115
+ libsqreen_version(VALUE self) {
116
+ PWVersion version;
117
+ VALUE result;
118
+
119
+ version = powerwaf_getVersion();
120
+ result = rb_ary_new();
121
+ rb_ary_push(result, INT2NUM(version.major));
122
+ rb_ary_push(result, INT2NUM(version.minor));
123
+ rb_ary_push(result, INT2NUM(version.patch));
124
+
125
+ return result;
126
+ }
127
+
128
+ static VALUE
129
+ libsqreen_waf_set(VALUE self, VALUE name, VALUE rules) {
130
+ char * pw_name;
131
+ char * pw_rules;
132
+ bool pw_result;
133
+ VALUE result;
134
+
135
+ Check_Type(name, T_STRING);
136
+ Check_Type(rules, T_STRING);
137
+
138
+ pw_name = StringValueCStr(name);
139
+ pw_rules = StringValueCStr(rules);
140
+ pw_result = powerwaf_initializePowerWAF(pw_name, pw_rules);
141
+
142
+ result = pw_result ? Qtrue : Qfalse;
143
+
144
+ return result;
145
+ }
146
+
147
+ static VALUE
148
+ libsqreen_waf_delete(VALUE self, VALUE name) {
149
+ char * pw_name;
150
+
151
+ Check_Type(name, T_STRING);
152
+
153
+ pw_name = StringValueCStr(name);
154
+ powerwaf_clearRule(pw_name);
155
+
156
+ return Qnil;
157
+ }
158
+
159
+ static VALUE
160
+ libsqreen_waf_clear(VALUE self) {
161
+ powerwaf_clearAll();
162
+
163
+ return Qnil;
164
+ }
165
+
166
+ static const PWArgs PWArgsNil;
167
+
168
+ int on_hash_iteration(VALUE key, VALUE val, VALUE args);
169
+
170
+ PWArgs value_to_pw_args(VALUE val) {
171
+ PWArgs pw_val;
172
+
173
+ switch (TYPE(val)) {
174
+ case T_STRING:
175
+ {
176
+ char *pw_string;
177
+ size_t pw_len;
178
+
179
+ pw_string = StringValuePtr(val);
180
+ pw_len = RSTRING_LEN(val);
181
+ pw_val = powerwaf_createStringWithLength(pw_string, pw_len);
182
+ }
183
+ break;
184
+ case T_FIXNUM:
185
+ {
186
+ int64_t pw_int;
187
+
188
+ pw_int = FIX2LONG(val);
189
+ pw_val = powerwaf_createInt(pw_int);
190
+ }
191
+ break;
192
+ case T_HASH:
193
+ {
194
+ VALUE waf_args;
195
+
196
+ pw_val = powerwaf_createMap();
197
+ waf_args = libsqreen_waf_args_new();
198
+ libsqreen_waf_args_set_boxed(waf_args, &pw_val);
199
+ rb_hash_foreach(val, on_hash_iteration, waf_args);
200
+ }
201
+ break;
202
+ case T_ARRAY:
203
+ {
204
+ pw_val = powerwaf_createArray();
205
+ for (int i = 0; i < RARRAY_LEN(val); i++) {
206
+ VALUE e;
207
+ PWArgs pw_e;
208
+ bool ok;
209
+
210
+ e = rb_ary_entry(val, i);
211
+
212
+ if (e == Qnil) {
213
+ continue;
214
+ }
215
+
216
+ pw_e = value_to_pw_args(e);
217
+ ok = powerwaf_addToPWArgsArray(&pw_val, pw_e);
218
+ if (!ok) {
219
+ powerwaf_freeInput(&pw_e, false);
220
+ }
221
+ }
222
+ }
223
+ break;
224
+ case T_NIL:
225
+ pw_val = PWArgsNil;
226
+ break;
227
+ default:
228
+ pw_val = PWArgsNil;
229
+ break;
230
+ }
231
+
232
+ return pw_val;
233
+ }
234
+
235
+ int on_hash_iteration(VALUE key, VALUE val, VALUE args) {
236
+ PWArgs *pw_args;
237
+ char *pw_key;
238
+ PWArgs pw_val;
239
+ bool ok;
240
+
241
+ Check_Type(key, T_STRING);
242
+ // Check_Type(in, libsqreen_waf_args)
243
+
244
+ if (val == Qnil) {
245
+ return ST_CONTINUE;
246
+ }
247
+
248
+ pw_args = (PWArgs *)libsqreen_waf_args_get_boxed(args);
249
+ pw_key = StringValueCStr(key);
250
+ pw_val = value_to_pw_args(val);
251
+ ok = powerwaf_addToPWArgsMap(pw_args, pw_key, strlen(pw_key), pw_val);
252
+ if (!ok) {
253
+ powerwaf_freeInput(&pw_val, false);
254
+ }
255
+
256
+ return ST_CONTINUE;
257
+ }
258
+
259
+ static VALUE
260
+ libsqreen_waf_args_initialize(VALUE self, VALUE args) {
261
+ VALUE hash;
262
+ long len;
263
+ PWArgs pw_args;
264
+
265
+ len = RARRAY_LEN(args);
266
+ if (len > 2) {
267
+ rb_raise(rb_eArgError, "wrong number of arguments");
268
+ }
269
+ if (len == 0) {
270
+ return self;
271
+ }
272
+
273
+ hash = rb_ary_entry(args, 0);
274
+ Check_Type(hash, T_HASH);
275
+
276
+ pw_args = value_to_pw_args(hash);
277
+ libsqreen_waf_args_set_boxed(self, &pw_args);
278
+
279
+ return self;
280
+ }
281
+
282
+
283
+ VALUE ret_code_to_sym(PW_RET_CODE level) {
284
+ VALUE sym;
285
+
286
+ switch (level) {
287
+ case PW_ERR_INTERNAL:
288
+ sym = ID2SYM(rb_intern("internal_error"));
289
+ break;
290
+ case PW_ERR_TIMEOUT:
291
+ sym = ID2SYM(rb_intern("timeout"));
292
+ break;
293
+ case PW_ERR_INVALID_CALL:
294
+ sym = ID2SYM(rb_intern("invalid_call"));
295
+ break;
296
+ case PW_ERR_INVALID_RULE:
297
+ sym = ID2SYM(rb_intern("invalid_rule"));
298
+ break;
299
+ case PW_ERR_INVALID_FLOW:
300
+ sym = ID2SYM(rb_intern("invalid_flow"));
301
+ break;
302
+ case PW_ERR_NORULE:
303
+ sym = ID2SYM(rb_intern("no_rule"));
304
+ break;
305
+ case PW_GOOD:
306
+ sym = ID2SYM(rb_intern("good"));
307
+ break;
308
+ case PW_MONITOR:
309
+ sym = ID2SYM(rb_intern("monitor"));
310
+ break;
311
+ case PW_BLOCK:
312
+ sym = ID2SYM(rb_intern("block"));
313
+ break;
314
+ default:
315
+ sym = Qnil;
316
+ rb_raise(rb_eArgError, "not valid value");
317
+ break;
318
+ }
319
+
320
+ return sym;
321
+ }
322
+
323
+ static VALUE
324
+ libsqreen_waf_run(VALUE self, VALUE name, VALUE args, VALUE budget) {
325
+ VALUE waf_args;
326
+ char *pw_name;
327
+ PWArgs pw_args;
328
+ size_t pw_budget;
329
+ PWRet *pw_ret;
330
+ VALUE result;
331
+
332
+ Check_Type(name, T_STRING);
333
+ Check_Type(args, T_HASH);
334
+ Check_Type(budget, T_FIXNUM);
335
+
336
+ waf_args = libsqreen_waf_args_new_from_hash(args);
337
+ pw_args = *(PWArgs *)libsqreen_waf_args_get_boxed(waf_args);
338
+ pw_budget = FIX2LONG(budget);
339
+ pw_name = StringValueCStr(name);
340
+ pw_ret = powerwaf_runPowerWAF(pw_name, &pw_args, pw_budget);
341
+
342
+ result = rb_ary_new();
343
+ rb_ary_push(result, ret_code_to_sym(pw_ret->action));
344
+ rb_ary_push(result, pw_ret->data == NULL ? Qnil : rb_str_new2(pw_ret->data));
345
+
346
+ powerwaf_freeInput(&pw_args, false);
347
+ powerwaf_freeReturn(pw_ret);
348
+
349
+ return result;
350
+ }
351
+
352
+ VALUE log_level_to_sym(PW_LOG_LEVEL level) {
353
+ VALUE sym;
354
+
355
+ switch (level) {
356
+ case PWL_TRACE:
357
+ sym = ID2SYM(rb_intern("trace"));
358
+ break;
359
+ case PWL_DEBUG:
360
+ sym = ID2SYM(rb_intern("debug"));
361
+ break;
362
+ case PWL_INFO:
363
+ sym = ID2SYM(rb_intern("info"));
364
+ break;
365
+ case PWL_WARN:
366
+ sym = ID2SYM(rb_intern("warn"));
367
+ break;
368
+ case PWL_ERROR:
369
+ sym = ID2SYM(rb_intern("error"));
370
+ break;
371
+ default:
372
+ sym = Qnil;
373
+ rb_raise(rb_eArgError, "not valid value");
374
+ break;
375
+ }
376
+
377
+ return sym;
378
+ }
379
+
380
+ VALUE log_level_to_fixnum(PW_LOG_LEVEL level) {
381
+ VALUE sym;
382
+
383
+ switch (level) {
384
+ case PWL_TRACE:
385
+ sym = INT2FIX(0); // Logger::DEBUG
386
+ break;
387
+ case PWL_DEBUG:
388
+ sym = INT2FIX(0); // Logger::DEBUG
389
+ break;
390
+ case PWL_INFO:
391
+ sym = INT2FIX(1); // Logger::INFO
392
+ break;
393
+ case PWL_WARN:
394
+ sym = INT2FIX(2); // Logger::WARN
395
+ break;
396
+ case PWL_ERROR:
397
+ sym = INT2FIX(3); // Logger::ERROR
398
+ break;
399
+ default:
400
+ sym = Qnil;
401
+ rb_raise(rb_eArgError, "not valid value");
402
+ break;
403
+ }
404
+
405
+ return sym;
406
+ }
407
+
408
+ PW_LOG_LEVEL sym_to_log_level(VALUE sym) {
409
+ PW_LOG_LEVEL level;
410
+
411
+ Check_Type(sym, T_SYMBOL);
412
+
413
+ if (SYM2ID(sym) == rb_intern("trace")) {
414
+ level = PWL_TRACE;
415
+ } else if (SYM2ID(sym) == rb_intern("debug")) {
416
+ level = PWL_DEBUG;
417
+ } else if (SYM2ID(sym) == rb_intern("info")) {
418
+ level = PWL_INFO;
419
+ } else if (SYM2ID(sym) == rb_intern("warn")) {
420
+ level = PWL_WARN;
421
+ } else if (SYM2ID(sym) == rb_intern("error")) {
422
+ level = PWL_ERROR;
423
+ } else {
424
+ rb_raise(rb_eArgError, "not valid value");
425
+ level = _PWL_AFTER_LAST;
426
+ }
427
+
428
+ return level;
429
+ }
430
+
431
+ void on_log(PW_LOG_LEVEL level, const char *function, const char *file, int line, const char *message, size_t message_len);
432
+
433
+ static VALUE
434
+ libsqreen_waf_log_enable(VALUE self, VALUE severity) {
435
+ PW_LOG_LEVEL level;
436
+
437
+ Check_Type(severity, T_SYMBOL);
438
+
439
+ level = sym_to_log_level(severity);
440
+ powerwaf_setupLogging((powerwaf_logging_cb_t)on_log, level);
441
+
442
+ return Qnil;
443
+ }
444
+
445
+ static VALUE
446
+ libsqreen_waf_log_disable(VALUE self) {
447
+ PW_LOG_LEVEL level = PWL_ERROR;
448
+
449
+ powerwaf_setupLogging(NULL, level);
450
+
451
+ return Qnil;
452
+ }
453
+
454
+ static VALUE
455
+ libsqreen_waf_set_logger(VALUE self, VALUE logger) {
456
+ ID i_logger;
457
+
458
+ if (logger == Qnil) {
459
+ libsqreen_waf_log_disable(self);
460
+ }
461
+
462
+ i_logger = rb_intern("@logger");
463
+ rb_ivar_set(self, i_logger, logger);
464
+
465
+ if (logger != Qnil) {
466
+ libsqreen_waf_log_enable(self, ID2SYM(rb_intern("error")));
467
+ }
468
+
469
+ return logger;
470
+ }
471
+
472
+ static VALUE
473
+ libsqreen_waf_get_logger(VALUE self) {
474
+ VALUE logger;
475
+ ID i_logger;
476
+
477
+ i_logger = rb_intern("@logger");
478
+ logger = rb_ivar_get(self, i_logger);
479
+
480
+ return logger;
481
+ }
482
+
483
+ void
484
+ on_log(PW_LOG_LEVEL level, const char *function, const char *file, int line, const char *message, size_t message_len) {
485
+ VALUE severity;
486
+ VALUE logger;
487
+ VALUE log_msg;
488
+ VALUE mWAF;
489
+
490
+ mWAF = libsqreen_waf_module();
491
+ logger = libsqreen_waf_get_logger(mWAF);
492
+ if (logger == Qnil) {
493
+ return;
494
+ }
495
+
496
+ severity = log_level_to_fixnum(level);
497
+ if (severity == Qnil) {
498
+ return;
499
+ }
500
+
501
+ log_msg = rb_sprintf("from %s:%d:in `%s': %s", file, line, function, message);
502
+ //rb_funcall(logger, SYM2ID(sym_level), 1, log_msg);
503
+ rb_funcall(logger, rb_intern("add"), 2, severity, log_msg);
504
+ }
505
+
506
+ #endif
507
+
508
+ // extension initializer
509
+ void
510
+ Init_libsqreen_extension(void) {
511
+ VALUE mLibSqreen;
512
+
513
+ mLibSqreen = rb_define_module("LibSqreen");
514
+
515
+ // record load order
516
+ {
517
+ ID i_load_order;
518
+ VALUE load_order;
519
+
520
+ i_load_order = rb_intern("@load_order");
521
+ load_order = rb_ivar_get(mLibSqreen, i_load_order);
522
+ if (load_order == Qnil) {
523
+ load_order = rb_ary_new();
524
+ rb_ivar_set(mLibSqreen, i_load_order, load_order);
525
+ }
526
+
527
+ rb_ary_push(load_order, ID2SYM(rb_intern("libsqreen_extension.c")));
528
+ }
529
+
530
+ #ifndef LIBSQREEN_STUB
531
+
532
+ // define C API bindings
533
+ {
534
+ rb_define_module_function(mLibSqreen, "version", libsqreen_version, 0);
535
+
536
+ {
537
+ VALUE mWAF;
538
+ mWAF = rb_define_module_under(mLibSqreen, "WAF");
539
+ rb_define_module_function(mWAF, "[]=", libsqreen_waf_set, 2);
540
+ rb_define_module_function(mWAF, "delete", libsqreen_waf_delete, 1);
541
+ rb_define_module_function(mWAF, "clear", libsqreen_waf_clear, 0);
542
+ rb_define_module_function(mWAF, "run", libsqreen_waf_run, 3);
543
+ rb_define_module_function(mWAF, "logger", libsqreen_waf_get_logger, 0);
544
+ rb_define_module_function(mWAF, "logger=", libsqreen_waf_set_logger, 1);
545
+ rb_define_module_function(mWAF, "log_level=", libsqreen_waf_log_enable, 1);
546
+ rb_define_module_function(mWAF, "log_disable", libsqreen_waf_log_disable, 0);
547
+ rb_define_const(mWAF, "BUDGET_MAX", ULL2NUM((size_t)-1));
548
+
549
+ {
550
+ VALUE cArgs;
551
+ cArgs = rb_define_class_under(mWAF, "Args", rb_cData);
552
+ rb_define_alloc_func(cArgs, libsqreen_waf_args_alloc);
553
+ rb_define_method(cArgs, "initialize", libsqreen_waf_args_initialize, -2);
554
+ }
555
+ }
556
+ }
557
+
558
+ #endif
559
+ }