11#include " waf_log_util_internal.h"
22#include " waf_log_util_external.h"
33
4+ using namespace std ;
5+ unordered_map<int ,bool > appgw_ruleid_hash;
6+
47// This function fills in a waf format message based on modsec input.
5- void set_waf_format (waf_format::Waf_Format* waf_format,char * resourceId,char * operationName,char * category,char * instanceId,char * clientIP,char * clientPort,char * requestUri,char * ruleSetType,char * ruleSetVersion,char * ruleId,char * messages,int action,int site,char * details_messages,char * details_data,char * details_file,char * details_line,char * hostname) {
8+ void set_waf_format (waf_format::Waf_Format* waf_format,char * resourceId,char * operationName,char * category,char * instanceId,char * clientIP,char * clientPort,const char * requestUri,char * ruleSetType,char * ruleSetVersion,char * ruleId,char * messages,int action,int site,char * details_messages,char * details_data,char * details_file,char * details_line,const char * hostname, char * waf_unique_id ) {
69 waf_format::Properties *properties;
710 waf_format::Details *details;
811
@@ -46,25 +49,57 @@ void set_waf_format(waf_format::Waf_Format* waf_format, char* resourceId, char*
4649 }
4750
4851if (ruleId !=NULL ) {
49- properties->set_ruleid (ruleId);
50- }
51-
52- if (messages !=NULL ) {
53- properties->set_message (messages);
52+ ruleId[strlen (ruleId) -1 ] =' \0 ' ;
53+ properties->set_ruleid (ruleId+1 );
5454 }
5555
56- switch (action) {
57- case 1 :
58- properties->set_action (waf_format::Properties::Detected);
59- break ;
60- case 2 :
61- properties->set_action (waf_format::Properties::Blocked);
62- break ;
63- default :
64- break ;
65- }
56+ bool is_mandatory =false ;
57+ try {
58+ int tmpid =atoi (ruleId+1 );
59+ is_mandatory =rule_is_mandatory (tmpid);
60+
61+ if (ruleSetVersion[0 ] !=' 2' && !is_mandatory)
62+ properties->set_action (WAF_ACTION_MATCHED);
63+ else {
64+ switch (action) {
65+ case MODSEC_MODE_DETECT:
66+ properties->set_action (WAF_ACTION_DETECTED);
67+ break ;
68+ case MODSEC_MODE_PREVENT:
69+ properties->set_action (WAF_ACTION_BLOCKED);
70+ break ;
71+ default :
72+ break ;
73+ }
74+ }
75+ }
76+ catch (...) {
77+ properties->set_action (" " );
78+ }
6679
67- if (site ==0 ) {
80+ if (messages !=NULL ) {
81+ if (is_mandatory) {
82+ char mandatory_message[1024 ] =" Mandatory rule. Cannot be disabled." ;
83+ int ind =strlen (mandatory_message) -1 ;
84+ int i;
85+ for (i =1 ; i <strlen (messages) -1 ; i++) {
86+ if (i + ind <1023 ) {
87+ mandatory_message[ind + i] = messages[i];
88+ }
89+ else {
90+ break ;
91+ }
92+ }
93+ mandatory_message[ind + i] =' \0 ' ;
94+ properties->set_message (mandatory_message);
95+ }
96+ else {
97+ messages[strlen (messages) -1 ] =' \0 ' ;
98+ properties->set_message (messages+1 );
99+ }
100+ }
101+
102+ if (site ==0 ) {
68103 properties->set_site (waf_format::Properties::Global);
69104 }
70105
@@ -73,26 +108,33 @@ void set_waf_format(waf_format::Waf_Format* waf_format, char* resourceId, char*
73108 }
74109
75110if (details_data !=NULL ) {
76- details->set_data (details_data);
111+ details_data[strlen (details_data) -1 ] =' \0 ' ;
112+ details->set_data (details_data+1 );
77113 }
78114
79115if (details_file !=NULL ) {
80116 details->set_file (details_file);
81117 }
82118
83119if (details_line !=NULL ) {
84- details->set_line (details_line);
120+ details_line[strlen (details_line) -1 ] =' \0 ' ;
121+ details->set_line (details_line+1 );
85122 }
86123
87- if (hostname !=NULL ) {
88- properties->set_hostname (hostname);
89- }
124+ if (hostname !=NULL ) {
125+ properties->set_hostname (hostname);
126+ }
127+
128+ if (waf_unique_id !=NULL ) {
129+ waf_unique_id[strlen (waf_unique_id) -1 ] =' \0 ' ;
130+ properties->set_transactionid (waf_unique_id+1 );
131+ }
90132}
91133
92134// Main function: get fields from modsec, set the protobuf object and write to file in json.
93- int generate_json (char ** result_json,char * resourceId,char * operationName,char * category,char * instanceId,char * clientIP,char * clientPort,char * requestUri,char * ruleSetType,char * ruleSetVersion,char * ruleId,char * messages,int action,int site,char * details_messages,char * details_data,char * details_file,char * details_line,char * hostname) {
135+ int generate_json (char ** result_json,char * resourceId,char * operationName,char * category,char * instanceId,char * clientIP,char * clientPort,const char * requestUri,char * ruleSetType,char * ruleSetVersion,char * ruleId,char * messages,int action,int site,char * details_messages,char * details_data,char * details_file,char * details_line,const char * hostname, char * waf_unique_id ) {
94136 waf_format::Waf_Format waf_format;
95- std:: string json_string;
137+ string json_string;
96138 google::protobuf::util::JsonPrintOptions options;
97139 google::protobuf::util::Status convert_result;
98140char * json_str;
@@ -103,7 +145,7 @@ int generate_json(char** result_json, char* resourceId, char* operationName, cha
103145 GOOGLE_PROTOBUF_VERIFY_VERSION;
104146
105147// Set Waf format.
106- set_waf_format (&waf_format, resourceId, operationName, category, instanceId, clientIP, clientPort, requestUri, ruleSetType, ruleSetVersion, ruleId, messages, action, site, details_messages, details_data, details_file, details_line, hostname);
148+ set_waf_format (&waf_format, resourceId, operationName, category, instanceId, clientIP, clientPort, requestUri, ruleSetType, ruleSetVersion, ruleId, messages, action, site, details_messages, details_data, details_file, details_line, hostname, waf_unique_id );
107149
108150 options.add_whitespace =false ;
109151 options.always_print_primitive_fields =true ;
@@ -127,3 +169,20 @@ int generate_json(char** result_json, char* resourceId, char* operationName, cha
127169void free_json (char * str) {
128170free (str);
129171}
172+
173+ void init_appgw_rules_id_hash () {
174+ ifstreaminfile (RULES_ID_FILE);
175+ string line;
176+
177+ while (getline (infile, line)) {
178+ int rule_id =stoi (line);
179+ appgw_ruleid_hash[rule_id] =true ;
180+ }
181+ infile.close ();
182+
183+ return ;
184+ }
185+
186+ bool rule_is_mandatory (int rule_id) {
187+ return (appgw_ruleid_hash.find (rule_id) == appgw_ruleid_hash.end ());
188+ }