libsqreen 0.3.0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }