Skip to content

Commit 5696fd2

Browse files
committed
add support for reloading ruleset
1 parent fe82923 commit 5696fd2

File tree

2 files changed

+119
-62
lines changed

2 files changed

+119
-62
lines changed

src/test.c

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <wafielib.h>
33
#include <stdlib.h>
44
#include <string.h>
5+
#include <unistd.h>
56
#include <pthread.h>
67

78

@@ -34,10 +35,29 @@ char *read_file(const char *filename) {
3435

3536
void *evalu_request(void *ptr) {
3637
WafieEvaluationRequest *request = ptr;
37-
wafie_init_transaction(request);
38-
wafie_process_request_headers(request);
39-
wafie_process_request_body(request);
40-
wafie_cleanup(request);
38+
for (int i = 0; i < 3; i++) {
39+
wafie_init_transaction(request);
40+
if (request->transaction != NULL) {
41+
wafie_process_request_headers(request);
42+
wafie_process_request_body(request);
43+
wafie_cleanup(request);
44+
break;
45+
}
46+
sleep(1);
47+
}
48+
49+
return NULL;
50+
}
51+
52+
void *reload_ruleset(void *ptr) {
53+
WafieRuleSetConfig cfg[3];
54+
cfg[0].protection_id = 1;
55+
cfg[0].config_path = "/config1";
56+
cfg[1].protection_id = 2;
57+
cfg[1].config_path = "/config2";
58+
cfg[2].protection_id = 3;
59+
cfg[2].config_path = "/config3";
60+
wafie_load_rule_sets(cfg, 3);
4161
return NULL;
4262
}
4363

@@ -85,7 +105,7 @@ int main() {
85105
.headers_count = 2,
86106
.headers = headers1,
87107
.body = "",
88-
.protection_id = 2,
108+
.protection_id = 3,
89109
};
90110
WafieEvaluationRequest request4 = {
91111
.client_ip = "192.168.1.3",
@@ -95,7 +115,7 @@ int main() {
95115
.headers_count = 2,
96116
.headers = headers1,
97117
.body = "",
98-
.protection_id = 2,
118+
.protection_id = 3,
99119
};
100120
WafieEvaluationRequest request5 = {
101121
.client_ip = "192.168.1.3",
@@ -105,7 +125,7 @@ int main() {
105125
.headers_count = 2,
106126
.headers = headers1,
107127
.body = "",
108-
.protection_id = 2,
128+
.protection_id = 3,
109129
};
110130
WafieEvaluationRequest request6 = {
111131
.client_ip = "192.168.1.3",
@@ -128,22 +148,28 @@ int main() {
128148
pthread_t thread4;
129149
pthread_t thread5;
130150
pthread_t thread6;
151+
pthread_t thread_reload_ruleset;
152+
131153
const int t1 = pthread_create(&thread1, NULL, evalu_request, &request1);
132-
// const int t2 = pthread_create(&thread2, NULL, evalu_request, &request2);
133-
// const int t3 = pthread_create(&thread3, NULL, evalu_request, &request3);
134-
// const int t4 = pthread_create(&thread4, NULL, evalu_request, &request4);
135-
// const int t5 = pthread_create(&thread5, NULL, evalu_request, &request5);
136-
// const int t6 = pthread_create(&thread6, NULL, evalu_request, &request6);
137-
// if (t1 || t2 || t3 || t4 || t5 || t6) {
138-
// fprintf(stderr, "Error - pthread_create() return code: %d\n", t1 || t2);
139-
// exit(EXIT_FAILURE);
140-
// }
154+
const int t2 = pthread_create(&thread2, NULL, evalu_request, &request2);
155+
const int th7 = pthread_create(&thread_reload_ruleset, NULL, reload_ruleset, NULL);
156+
const int t3 = pthread_create(&thread3, NULL, evalu_request, &request3);
157+
const int t4 = pthread_create(&thread4, NULL, evalu_request, &request4);
158+
const int t5 = pthread_create(&thread5, NULL, evalu_request, &request5);
159+
const int t6 = pthread_create(&thread6, NULL, evalu_request, &request6);
160+
if (t1 || t2 || t3 || t4 || t5 || t6 || th7) {
161+
fprintf(stderr, "Error - pthread_create() return code: %d\n", t1 || t2);
162+
exit(EXIT_FAILURE);
163+
}
164+
141165
pthread_join(thread1, NULL);
142-
// pthread_join(thread2, NULL);
143-
// pthread_join(thread3, NULL);
144-
// pthread_join(thread4, NULL);
145-
// pthread_join(thread5, NULL);
146-
// pthread_join(thread6, NULL);
166+
pthread_join(thread2, NULL);
167+
pthread_join(thread3, NULL);
168+
pthread_join(thread4, NULL);
169+
pthread_join(thread5, NULL);
170+
pthread_join(thread6, NULL);
171+
pthread_join(thread_reload_ruleset, NULL);
172+
147173
free(headers1);
148174

149175
char *audit_content = read_file("/tmp/modsec_audit.log");

src/wafielib.c

Lines changed: 72 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@
33
#include <stdio.h>
44
#include <dirent.h>
55
#include <pthread.h>
6+
#include <sys/time.h>
67
#include "modsecurity/rules_set.h"
78
#include "modsecurity/modsecurity.h"
89
#include "modsecurity/transaction.h"
910
#include "modsecurity/intervention.h"
1011

12+
#ifndef WAFIE_RULESET_BUFFER_SIZE
13+
#define WAFIE_RULESET_BUFFER_SIZE 1000
14+
#endif
15+
1116

1217
ModSecurity *modsec;
13-
WafieRuleSet *wrs[1000];
18+
WafieRuleSet *wrs[WAFIE_RULESET_BUFFER_SIZE];
19+
WafieRuleSet *wrs_swap[WAFIE_RULESET_BUFFER_SIZE];
1420
pthread_rwlock_t ruleset_lock = PTHREAD_RWLOCK_INITIALIZER;
1521

1622
ModSecurityIntervention wafie_new_intervention() {
@@ -23,13 +29,15 @@ ModSecurityIntervention wafie_new_intervention() {
2329
return intervention;
2430
}
2531

32+
2633
// register logs call back
2734
void wafie_log_cb(void *data, const void *msg) {
2835
fprintf(stderr, "%s\n", (const char *) msg);
2936
}
3037

3138
static void wafie_load_main_configs(RulesSet *rule_set, char *config_path, int protection_id) {
32-
fprintf(stdout, "[libwafie.protection.id: %d] loading main configuration \n", protection_id);
39+
fprintf(stdout, "[libwafie.wafie_load_main_configs.protection.id: %d] loading main configuration \n",
40+
protection_id);
3341
char **main_config_files = (char *[]){
3442
"modsecurity.conf",
3543
"crs-setup.conf",
@@ -47,12 +55,12 @@ static void wafie_load_main_configs(RulesSet *rule_set, char *config_path, int p
4755
msc_rules_error_cleanup(error);
4856
}
4957
}
50-
// request->total_loaded_rules += ret;
5158
}
5259
}
5360

5461
static void wafie_load_modescurity_rules_configs(RulesSet *rule_set, char *config_path, int protection_id) {
55-
fprintf(stdout, "[libwafie.protection.id: %d] loading rules \n", protection_id);
62+
fprintf(stdout, "[libwafie.wafie_load_modescurity_rules_configs.protection.id: %d] loading rules \n",
63+
protection_id);
5664
const char *error = NULL;
5765
// const char *config_file_suffix = ".conf";
5866
// 7 = strlen("/rules") + 1
@@ -95,53 +103,73 @@ void wafie_init() {
95103
}
96104

97105
void wafie_load_rule_sets(WafieRuleSetConfig cfg[], const int cfg_size) {
98-
// lock rules for RW
99-
pthread_rwlock_wrlock(&ruleset_lock);
100-
WafieRuleSet *wrs_swap[1000];
106+
struct timespec start, end;
107+
clock_gettime(CLOCK_MONOTONIC, &start);
108+
fprintf(stdout, "[libwafie.wafie_load_rule_sets] reloading ruleset \n");
101109
for (int i = 0; i < cfg_size; i++) {
102-
wrs[i] = malloc(sizeof(WafieRuleSet));
103-
wrs[i]->protection_id = cfg[i].protection_id;
104-
wrs[i]->rules = msc_create_rules_set();
110+
wrs_swap[i] = malloc(sizeof(WafieRuleSet));
111+
wrs_swap[i]->protection_id = cfg[i].protection_id;
112+
wrs_swap[i]->rules = msc_create_rules_set();
105113
// load main configurations files
106-
wafie_load_main_configs(wrs[i]->rules, cfg[i].config_path, wrs[i]->protection_id);
114+
wafie_load_main_configs(wrs_swap[i]->rules, cfg[i].config_path, wrs_swap[i]->protection_id);
107115
// load the rules files
108-
wafie_load_modescurity_rules_configs(wrs[i]->rules, cfg[i].config_path, wrs[i]->protection_id);
116+
wafie_load_modescurity_rules_configs(wrs_swap[i]->rules, cfg[i].config_path, wrs_swap[i]->protection_id);
117+
}
118+
// lock rules for RW
119+
pthread_rwlock_wrlock(&ruleset_lock);
120+
WafieRuleSet *old_rules[WAFIE_RULESET_BUFFER_SIZE];
121+
for (int i = 0; i < WAFIE_RULESET_BUFFER_SIZE; i++) {
122+
old_rules[i] = wrs[i]; // Save old pointers
123+
wrs[i] = (i < cfg_size) ? wrs_swap[i] : NULL; // Atomic pointer swap
124+
wrs_swap[i] = NULL;
109125
}
110126
// unlock rules for RW
111127
pthread_rwlock_unlock(&ruleset_lock);
128+
// Clean up old rules after lock is released
129+
for (int i = 0; i < WAFIE_RULESET_BUFFER_SIZE; i++) {
130+
if (old_rules[i] != NULL) {
131+
msc_rules_cleanup(old_rules[i]->rules);
132+
free(old_rules[i]);
133+
}
134+
}
135+
clock_gettime(CLOCK_MONOTONIC, &end);
136+
long long elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
137+
double elapsed_ms = elapsed_ns / 1000000.0;
138+
fprintf(stdout, "[libwafie.wafie_load_rule_sets] reload ruleset took %.3f ms\n", elapsed_ms);
112139
}
113140

114141
// init transaction
115142
void wafie_init_transaction(WafieEvaluationRequest *request) {
116143
struct timespec start, end;
117-
118144
clock_gettime(CLOCK_MONOTONIC, &start);
145+
// read lock
119146
pthread_rwlock_rdlock(&ruleset_lock);
120-
fprintf(stdout, "[libwafie: protection id - %d] initializing evaluation request\n", request->protection_id);
121-
// init modesc
122-
// request->modsec = msc_init();
123-
// msc_set_log_cb(request->modsec, wafie_log_cb);
124-
// msc_set_connector_info(request->modsec, "wafie v0.0.2-alpha");
125-
// load rules
126-
// request->total_loaded_rules = 0;
127-
// request->rules = msc_create_rules_set();
128-
// wafie_load_modsecuirty_configuration(request);
147+
fprintf(stdout, "[libwafie.wafie_init_transaction.protection id - %d] initializing evaluation request\n",
148+
request->protection_id);
129149
// init transaction
130-
int rule_set_idx = 0;
131-
for (int i = 0; i < 1; i++) {
132-
if (wrs[i]->protection_id == request->protection_id) {
150+
int rule_set_idx = -1;
151+
for (int i = 0; i < WAFIE_RULESET_BUFFER_SIZE; i++) {
152+
if (wrs[i] != NULL && wrs[i]->protection_id == request->protection_id) {
133153
rule_set_idx = i;
134154
break;
135155
}
136156
}
137-
request->transaction = msc_new_transaction(modsec, wrs[rule_set_idx]->rules, NULL);
157+
if (rule_set_idx == -1) {
158+
fprintf(
159+
stderr, "[libwafie.wafie_init_transaction.protection id - %d] error: no ruleset found for protection_id\n",
160+
request->protection_id);
161+
} else {
162+
request->transaction = msc_new_transaction(modsec, wrs[rule_set_idx]->rules, NULL);
163+
}
164+
// read unlock
138165
pthread_rwlock_unlock(&ruleset_lock);
139166
clock_gettime(CLOCK_MONOTONIC, &end);
140-
141167
long long elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
142168
double elapsed_ms = elapsed_ns / 1000000.0;
143-
fprintf(stdout, "[libwafie: protection id - %d] evaluation request initialization took %.3f ms\n",
144-
request->protection_id, elapsed_ms);
169+
fprintf(
170+
stdout,
171+
"[libwafie.wafie_init_transaction.protection id - %d] evaluation request initialization took %.3f ms\n",
172+
request->protection_id, elapsed_ms);
145173
}
146174

147175
// cleanup transaction
@@ -181,9 +209,9 @@ int wafie_process_intervention(Transaction *transaction) {
181209
// process headers
182210
int wafie_process_request_headers(WafieEvaluationRequest const *request) {
183211
struct timespec start, end;
184-
185212
clock_gettime(CLOCK_MONOTONIC, &start);
186-
fprintf(stdout, "[libwafie.protection.id: %d] processing request headers \n", request->protection_id);
213+
fprintf(stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] processing request \n",
214+
request->protection_id);
187215
int intervention_status = 0;
188216
// process connection
189217
msc_process_connection(request->transaction, request->client_ip, 0, "0.0.0.0", 0);
@@ -192,10 +220,13 @@ int wafie_process_request_headers(WafieEvaluationRequest const *request) {
192220
return intervention_status;
193221
}
194222
// process URI and request headers
195-
fprintf(stdout, "[libwafie.protection.id: %d] request uri -> %s\n", request->protection_id, request->uri);
196-
fprintf(stdout, "[libwafie.protection.id: %d] request method -> %s\n", request->protection_id,
223+
fprintf(stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] uri -> %s\n",
224+
request->protection_id, request->uri);
225+
fprintf(stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] method -> %s\n",
226+
request->protection_id,
197227
request->http_method);
198-
fprintf(stdout, "[libwafie.protection.id: %d] request version -> %s\n", request->protection_id,
228+
fprintf(stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] version -> %s\n",
229+
request->protection_id,
199230
request->http_version);
200231
msc_process_uri(request->transaction, request->uri, request->http_method, request->http_version);
201232
intervention_status = wafie_process_intervention(request->transaction);
@@ -204,7 +235,7 @@ int wafie_process_request_headers(WafieEvaluationRequest const *request) {
204235
}
205236
for (size_t i = 0; i < request->headers_count; i++) {
206237
msc_add_request_header(request->transaction, request->headers[i].key, request->headers[i].value);
207-
fprintf(stdout, "[libwafie.protection.id: %d] request header -> %s: %s\n",
238+
fprintf(stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] header -> %s: %s\n",
208239
request->protection_id,
209240
(const char *) request->headers[i].key,
210241
(const char *) request->headers[i].value);
@@ -215,8 +246,9 @@ int wafie_process_request_headers(WafieEvaluationRequest const *request) {
215246

216247
long long elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
217248
double elapsed_ms = elapsed_ns / 1000000.0;
218-
fprintf(stdout, "[libwafie.protection.id: %d] processing request headers took %.3f ms\n",
219-
request->protection_id, elapsed_ms);
249+
fprintf(
250+
stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] processing request took %.3f ms\n",
251+
request->protection_id, elapsed_ms);
220252

221253
if (intervention_status != 0) {
222254
return intervention_status;
@@ -227,9 +259,8 @@ int wafie_process_request_headers(WafieEvaluationRequest const *request) {
227259
// process body
228260
int wafie_process_request_body(WafieEvaluationRequest const *request) {
229261
struct timespec start, end;
230-
231-
232-
fprintf(stdout, "[libwafie.protection.id: %d] processing request body \n", request->protection_id);
262+
fprintf(stdout, "[libwafie.wafie_process_request_body.protection.id: %d] processing request\n",
263+
request->protection_id);
233264
int intervention_status = 0;
234265
// process request body
235266
if (request->body != NULL) {
@@ -246,7 +277,7 @@ int wafie_process_request_body(WafieEvaluationRequest const *request) {
246277

247278
long long elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
248279
double elapsed_ms = elapsed_ns / 1000000.0;
249-
fprintf(stdout, "[libwafie.protection.id: %d] processing request body took %.3f ms\n",
280+
fprintf(stdout, "[libwafie.wafie_process_request_body.protection.id: %d] processing request took %.3f ms\n",
250281
request->protection_id, elapsed_ms);
251282

252283
if (intervention_status != 0) {

0 commit comments

Comments
 (0)