29
29
#include <sys/utsname.h>
30
30
#include <sys/types.h>
31
31
#include <sys/socket.h>
32
- #if ! defined( IFT_ETHER )
33
- #define IFT_ETHER 0x6/* Ethernet CSMACD */
32
+ #ifndef IFT_ETHER
33
+ #define IFT_ETHER 0x6 /* Ethernet CSMACD */
34
34
#endif
35
35
#endif
36
36
42
42
43
43
// Bese32 encode, based on:
44
44
// https://code.google.com/p/google-authenticator/source/browse/libpam/base32.c
45
- void DSOLOCAL msc_status_engine_base32_encode (char * encoded ,
45
+ int DSOLOCAL msc_status_engine_base32_encode (char * encoded ,
46
46
const char * data , int len ) {
47
47
int buffer ;
48
48
int count = 0 ;
@@ -51,6 +51,11 @@ void DSOLOCAL msc_status_engine_base32_encode(char *encoded,
51
51
52
52
buffer = data [0 ];
53
53
54
+ if (encoded == NULL && len == 0 ) {
55
+ len = length * 3 ;
56
+ count ++ ;
57
+ }
58
+
54
59
if (length > 0 ) {
55
60
int next = 1 ;
56
61
int bitsLeft = 8 ;
@@ -69,27 +74,48 @@ void DSOLOCAL msc_status_engine_base32_encode(char *encoded,
69
74
}
70
75
index = 0x1f & (buffer >> (bitsLeft - 5 ));
71
76
bitsLeft -= 5 ;
72
- result [count ++ ] = msc_status_engine_basis_32 [index ];
77
+ if (encoded != NULL ) {
78
+ result [count ] = msc_status_engine_basis_32 [index ];
79
+ }
80
+ count ++ ;
73
81
}
74
82
}
75
- if (count < len ) {
83
+ if (count < len && encoded != NULL ) {
76
84
result [count ] = '\000' ;
77
85
}
86
+
87
+ return count ;
78
88
}
79
89
80
- void DSOLOCAL msc_status_engine_fill_with_dots (char * encoded_with_dots ,
90
+ int DSOLOCAL msc_status_engine_fill_with_dots (char * encoded_with_dots ,
81
91
const char * data , int len , int space )
82
92
{
83
93
int i ;
84
94
int count = 0 ;
85
95
96
+ if (encoded_with_dots == NULL ) {
97
+ if (len == 0 && data != NULL ) {
98
+ len = strlen (data );
99
+ }
100
+ else if (len == 0 && data == NULL ) {
101
+ count = -1 ;
102
+ goto return_length ;
103
+ }
104
+
105
+ count = len /space + len + 1 ;
106
+ goto return_length ;
107
+ }
108
+
86
109
for (i = 0 ; i < strlen (data ) && i < len ; i ++ ) {
87
110
if (i % space == 0 && i != 0 ) {
88
111
encoded_with_dots [count ++ ] = '.' ;
89
112
}
90
113
encoded_with_dots [count ++ ] = data [i ];
91
114
}
92
115
encoded_with_dots [count ] = '\0' ;
116
+
117
+ return_length :
118
+ return count ;
93
119
}
94
120
95
121
@@ -103,7 +129,9 @@ int DSOLOCAL msc_status_engine_machine_name(char *machine_name, size_t len) {
103
129
memset (machine_name , '\0' , sizeof (char ) * len );
104
130
105
131
#ifdef WIN32
106
- GetComputerName (machine_name , & lenComputerName );
132
+ if (GetComputerName (machine_name , & lenComputerName ) == 0 ) {
133
+ goto failed ;
134
+ }
107
135
#else
108
136
static struct utsname u ;
109
137
@@ -227,7 +255,6 @@ int DSOLOCAL msc_status_engine_mac_address (unsigned char *mac)
227
255
free (pAdapterInfo );
228
256
#endif
229
257
230
- done :
231
258
return 0 ;
232
259
233
260
failed :
@@ -296,137 +323,167 @@ int DSOLOCAL msc_status_engine_unique_id (unsigned char *digest)
296
323
return ret ;
297
324
}
298
325
299
- int msc_status_engine_call ( void ) {
326
+ int DSOLOCAL msc_beacon_string ( char * beacon_string , int beacon_string_max_len ) {
300
327
char * apr = NULL ;
301
328
const char * apr_loaded = NULL ;
302
329
char pcre [7 ];
303
330
const char * pcre_loaded = NULL ;
304
331
char * lua = NULL ;
305
- char * lua_loaded = NULL ;
306
332
char * libxml = NULL ;
307
- char * libxml_loaded = NULL ;
308
333
char * modsec = NULL ;
309
334
const char * apache = NULL ;
310
- char * id = NULL ;
311
- char * beacon_string = NULL ;
312
- int beacon_string_len = 0 ;
313
- char * beacon_string_encoded = NULL ;
314
- char * beacon_string_ready = NULL ;
315
- char * beacon_string_encoded_splitted = NULL ;
316
- int ret = 0 ;
335
+ char id [(APR_SHA1_DIGESTSIZE * 2 ) + 1 ];
336
+ int beacon_string_len = -1 ;
317
337
318
338
apr = APR_VERSION_STRING ;
319
339
apr_loaded = apr_version_string ();
320
-
340
+ apr_snprintf ( pcre , 7 , "%d.%d" , PCRE_MAJOR , PCRE_MINOR );
321
341
pcre_loaded = pcre_version ();
322
- apr_snprintf (pcre , 7 , "%2d.%2d " , PCRE_MAJOR , PCRE_MINOR );
323
342
#ifdef WITH_LUA
324
343
lua = LUA_VERSION ;
325
344
#endif
326
- lua_loaded = 0 ;
327
-
328
345
libxml = LIBXML_DOTTED_VERSION ;
329
- libxml_loaded = 0 ;
330
-
331
346
modsec = MODSEC_VERSION ;
347
+ #ifdef WIN32
348
+ apache = "IIS" ;
349
+ #else
332
350
apache = apache_get_server_version ();
351
+ #endif
333
352
334
- id = malloc (sizeof (char )* ((2 * APR_SHA1_DIGESTSIZE )+ 1 ));
335
- if (!id ) {
336
- ret = -1 ;
337
- goto failed_id ;
353
+ /* 6 represents: strlen("(null)") */
354
+ beacon_string_len = (modsec ? strlen (modsec ) : 6 ) +
355
+ (apache ? strlen (apache ) : 6 ) + (apr ? strlen (apr ) : 6 ) +
356
+ (apr_loaded ? strlen (apr_loaded ) : 6 ) + (pcre ? strlen (pcre ) : 6 ) +
357
+ (pcre_loaded ? strlen (pcre_loaded ) : 6 ) + (lua ? strlen (lua ) : 6 ) +
358
+ (libxml ? strlen (libxml ) : 6 ) + (APR_SHA1_DIGESTSIZE * 2 );
359
+
360
+ beacon_string_len = beacon_string_len + /* null terminator: */ 1 +
361
+ /* comma: */ 6 +
362
+ /* slash: */ 2 ;
363
+
364
+ if (beacon_string == NULL || beacon_string_max_len == 0 ) {
365
+ goto return_length ;
338
366
}
339
367
340
- memset (id , '\0' , sizeof (char )* ((2 * APR_SHA1_DIGESTSIZE )+ 1 ));
368
+ memset (id , '\0' , sizeof (char )* ((2 * APR_SHA1_DIGESTSIZE ) + /* \0: */ 1 ));
341
369
if (msc_status_engine_unique_id (id )) {
342
370
sprintf (id , "unique id failed" );
343
371
}
344
372
345
- beacon_string_len = (modsec ? strlen (modsec ) : 6 ) + (apache ? strlen (apache ) : 6 ) +
346
- (apr ? strlen (apr ) : 6 ) + (apr_loaded ? strlen (apr_loaded ) : 6 ) +
347
- (pcre ? strlen (pcre ) : 6 ) + (pcre_loaded ? strlen (pcre_loaded ) : 6 ) +
348
- (lua ? strlen (lua ) : 6 ) + (lua_loaded ? strlen (lua_loaded ) : 6 ) +
349
- (libxml ? strlen (libxml ) : 6 ) + (libxml_loaded ? strlen (libxml_loaded ) : 6 ) +
350
- (id ? strlen (id ) : 6 );
373
+ apr_snprintf (beacon_string , beacon_string_max_len ,
374
+ "%.25s,%s,%s/%s,%s/%s,%s,%s,%s" ,
375
+ modsec , apache , apr , apr_loaded , pcre , pcre_loaded , lua , libxml , id );
351
376
352
- #ifdef WIN32
353
- beacon_string = malloc (sizeof (char )* (beacon_string_len + 1 + 10 + 4 ));
354
- if (!beacon_string ) {
355
- goto failed_beacon_string ;
377
+ return_length :
378
+ return beacon_string_len ;
379
+ }
380
+
381
+ int DSOLOCAL msc_status_engine_prepare_hostname (char * hostname , const char * plain_data ,
382
+ int max_length )
383
+ {
384
+ int str_enc_len = 0 ;
385
+ int str_enc_spl_len = 0 ;
386
+ char * tmp = NULL ;
387
+ int length = -1 ;
388
+
389
+ str_enc_len = msc_status_engine_base32_encode (NULL , plain_data , 0 );
390
+
391
+ str_enc_spl_len = msc_status_engine_fill_with_dots (NULL , NULL , str_enc_len ,
392
+ STATUS_ENGINE_DNS_IN_BETWEEN_DOTS );
393
+ if (str_enc_spl_len < 0 ) {
394
+ goto failed_enc_spl_len ;
356
395
}
357
396
358
- apr_snprintf (beacon_string , beacon_string_len + 1 + 10 + 4 ,
359
- "%s,IIS,%s/%s,%s/%s,%s/%s,%s/%s,%s" ,
360
- modsec , apr , apr_loaded , pcre , pcre_loaded , lua , lua_loaded ,
361
- libxml , libxml_loaded , id );
362
- #else
363
- beacon_string = malloc (sizeof (char )* (beacon_string_len + 1 + 10 ));
364
- if (!beacon_string ) {
365
- goto failed_beacon_string ;
397
+ length = str_enc_spl_len + strlen (STATUS_ENGINE_DNS_SUFFIX ) +
398
+ /* epoch: */ 10 + /* dots: */ 2 + /* terminator: */ 1 -
399
+ /* removed unsed terminators from str_enc and str_enc_spl: */ 2 ;
400
+
401
+ if (hostname == NULL || max_length == 0 ) {
402
+ goto return_length ;
366
403
}
367
404
368
- apr_snprintf (beacon_string , beacon_string_len + 1 + 10 ,
369
- "%s,%s,%s/%s,%s/%s,%s/%s,%s/%s,%s" ,
370
- modsec , apache , apr , apr_loaded , pcre , pcre_loaded , lua , lua_loaded ,
371
- libxml , libxml_loaded , id );
372
- #endif
405
+ memset (hostname , '\0' , sizeof (char ) * max_length );
373
406
374
- ap_log_error (APLOG_MARK , APLOG_NOTICE , 0 , NULL ,
375
- "ModSecurity: StatusEngine call: \"%s\"" , beacon_string );
407
+ msc_status_engine_base32_encode (hostname , plain_data , str_enc_len );
376
408
377
- beacon_string_encoded = malloc (sizeof (char )* (strlen (beacon_string )* 3 ));
378
- if (!beacon_string_encoded ) {
379
- goto failed_beacon_string_encoded ;
409
+ tmp = strdup (hostname );
410
+ if (tmp == NULL ) {
411
+ length = -1 ;
412
+ goto failed_strdup ;
380
413
}
381
- msc_status_engine_base32_encode (beacon_string_encoded , beacon_string ,
382
- strlen (beacon_string )* 3 );
383
414
384
- beacon_string_encoded_splitted = malloc ( sizeof ( char ) *
385
- (( strlen ( beacon_string_encoded )/ STATUS_ENGINE_DNS_IN_BETWEEN_DOTS ) +
386
- strlen ( beacon_string_encoded ) + 1 + 1 ));
387
- if (! beacon_string_encoded_splitted ) {
388
- goto failed_beacon_string_encoded_splitted ;
415
+ str_enc_spl_len = msc_status_engine_fill_with_dots ( hostname , tmp , max_length ,
416
+ STATUS_ENGINE_DNS_IN_BETWEEN_DOTS );
417
+ if ( str_enc_spl_len < 0 ) {
418
+ length = -1 ;
419
+ goto failed_enc_spl ;
389
420
}
390
421
391
- msc_status_engine_fill_with_dots (beacon_string_encoded_splitted ,
392
- beacon_string_encoded ,
393
- (strlen (beacon_string_encoded )/STATUS_ENGINE_DNS_IN_BETWEEN_DOTS ) +
394
- strlen (beacon_string_encoded ) + 1 + 1 ,
395
- STATUS_ENGINE_DNS_IN_BETWEEN_DOTS );
422
+ apr_snprintf (hostname , max_length , "%s.%lu.%s" , hostname , time (NULL ),
423
+ STATUS_ENGINE_DNS_SUFFIX );
396
424
397
- beacon_string_ready = malloc (sizeof (char ) *
398
- strlen (beacon_string_encoded_splitted ) +
399
- strlen (STATUS_ENGINE_DNS_SUFFIX ) + 10 + 1 );
425
+ failed_enc_spl :
426
+ free (tmp );
427
+ failed_strdup :
428
+ return_length :
429
+ failed_enc_spl_len :
430
+ return length ;
431
+ }
400
432
401
- if (!beacon_string_ready ) {
402
- goto failed_beacon_string_ready ;
433
+ int msc_status_engine_call (void ) {
434
+ char * beacon_str = NULL ;
435
+ int beacon_str_len = 0 ;
436
+ char * hostname = NULL ;
437
+ int hostname_len = 0 ;
438
+ int ret = -1 ;
439
+
440
+ /* Retrieve the beacon string */
441
+ beacon_str_len = msc_beacon_string (NULL , 0 );
442
+
443
+ beacon_str = malloc (sizeof (char ) * beacon_str_len );
444
+ if (beacon_str == NULL ) {
445
+ goto failed_beacon_string_malloc ;
403
446
}
447
+ msc_beacon_string (beacon_str , beacon_str_len );
404
448
405
- apr_snprintf (beacon_string_ready , strlen (beacon_string_encoded_splitted ) +
406
- strlen (STATUS_ENGINE_DNS_SUFFIX ) + 12 + 1 , "%s.%lu.%s" ,
407
- beacon_string_encoded_splitted , time (NULL ),
408
- STATUS_ENGINE_DNS_SUFFIX );
449
+ ap_log_error (APLOG_MARK , APLOG_NOTICE , 0 , NULL ,
450
+ "ModSecurity: StatusEngine call: \"%s\"" , beacon_str );
409
451
410
- if (gethostbyname (beacon_string_ready )) {
452
+ /* Get beacon string in the format of a hostname */
453
+ hostname_len = msc_status_engine_prepare_hostname (NULL , beacon_str , 0 );
454
+ if (hostname_len < 0 ) {
455
+ goto failed_hostname_len ;
456
+ }
457
+
458
+ hostname = malloc (sizeof (char ) * hostname_len );
459
+ if (hostname == NULL ) {
460
+ goto failed_hostname_malloc ;
461
+ }
462
+ hostname_len = msc_status_engine_prepare_hostname (hostname , beacon_str ,
463
+ hostname_len );
464
+ if (hostname_len < 0 ) {
465
+ goto failed_hostname ;
466
+ }
467
+
468
+ /* Perform the DNS query. */
469
+ if (gethostbyname (hostname )) {
411
470
ap_log_error (APLOG_MARK , APLOG_NOTICE , 0 , NULL ,
412
471
"ModSecurity: StatusEngine call successfully sent. For more " \
413
472
"information visit: http://%s/" , STATUS_ENGINE_DNS_SUFFIX );
414
473
} else {
415
474
ap_log_error (APLOG_MARK , APLOG_NOTICE , 0 , NULL ,
416
475
"ModSecurity: StatusEngine call failed. Query: %s" ,
417
- beacon_string_ready );
418
- }
419
-
420
- free (beacon_string_ready );
421
- failed_beacon_string_ready :
422
- free (beacon_string_encoded_splitted );
423
- failed_beacon_string_encoded_splitted :
424
- free (beacon_string_encoded );
425
- failed_beacon_string_encoded :
426
- free (beacon_string );
427
- failed_beacon_string :
428
- free (id );
429
- failed_id :
476
+ hostname );
477
+ }
478
+
479
+ ret = 0 ;
480
+
481
+ failed_hostname :
482
+ free (hostname );
483
+ failed_hostname_malloc :
484
+ failed_hostname_len :
485
+ free (beacon_str );
486
+ failed_beacon_string_malloc :
430
487
431
488
return ret ;
432
489
}
0 commit comments