23
23
#include "msc_util.h"
24
24
25
25
#include <apr_lib.h>
26
+ #include <apr_sha1.h>
26
27
#include "modsecurity_config.h"
27
28
29
+ #include "curl/curl.h"
30
+
28
31
/**
29
32
* NOTE: Be careful as these can ONLY be used on static values for X.
30
33
* (i.e. VALID_HEX(c++) will NOT work)
@@ -2593,7 +2596,7 @@ int ip_tree_from_file(TreeRoot **rtree, char *uri,
2593
2596
tnode = TreeAddIP (start , (* rtree )-> ipv6_tree , IPV6_TREE );
2594
2597
}
2595
2598
#endif
2596
-
2599
+
2597
2600
if (tnode == NULL )
2598
2601
{
2599
2602
* error_msg = apr_psprintf (mp , "Could not add entry " \
@@ -2610,6 +2613,140 @@ int ip_tree_from_file(TreeRoot **rtree, char *uri,
2610
2613
return 0 ;
2611
2614
}
2612
2615
2616
+ int ip_tree_from_uri (TreeRoot * * rtree , char * uri ,
2617
+ apr_pool_t * mp , char * * error_msg )
2618
+ {
2619
+ TreeNode * tnode = NULL ;
2620
+ apr_status_t rc ;
2621
+ int line = 0 ;
2622
+ apr_file_t * fd ;
2623
+ char * start ;
2624
+ char * end ;
2625
+ char buf [HUGE_STRING_LEN + 1 ]; // FIXME: 2013-10-29 zimmerle: dynamic?
2626
+ char errstr [1024 ]; //
2627
+
2628
+ CURL * curl ;
2629
+ CURLcode res ;
2630
+
2631
+ char id [(APR_SHA1_DIGESTSIZE * 2 ) + 1 ];
2632
+ char * apr_id = NULL ;
2633
+ char * beacon_str = NULL ;
2634
+ int beacon_str_len = 0 ;
2635
+ char * beacon_apr = NULL ;
2636
+ struct msc_curl_memory_buffer_t chunk ;
2637
+ chunk .memory = malloc (1 ); /* will be grown as needed by the realloc above */
2638
+ chunk .size = 0 ; /* no data at this point */
2639
+ char * word = NULL ;
2640
+ char * brkt = NULL ;
2641
+ char * sep = "\n" ;
2642
+
2643
+
2644
+
2645
+ if (create_radix_tree (mp , rtree , error_msg ))
2646
+ {
2647
+ return -1 ;
2648
+ }
2649
+
2650
+ /* Retrieve the beacon string */
2651
+ beacon_str_len = msc_beacon_string (NULL , 0 );
2652
+
2653
+ beacon_str = malloc (sizeof (char ) * beacon_str_len + 1 );
2654
+ if (beacon_str == NULL ) {
2655
+ beacon_str = "Failed to retrieve beacon string" ;
2656
+ beacon_apr = apr_psprintf (mp , "ModSec-status: %s" , beacon_str );
2657
+ }
2658
+ else
2659
+ {
2660
+ msc_beacon_string (beacon_str , beacon_str_len );
2661
+ beacon_apr = apr_psprintf (mp , "ModSec-status: %s" , beacon_str );
2662
+ free (beacon_str );
2663
+ }
2664
+
2665
+ memset (id , '\0' , sizeof (id ));
2666
+ if (msc_status_engine_unique_id (id )) {
2667
+ sprintf (id , "no unique id" );
2668
+ }
2669
+
2670
+ apr_id = apr_psprintf (mp , "ModSec-unique-id: %s" , id );
2671
+ curl_global_init (CURL_GLOBAL_ALL );
2672
+ curl = curl_easy_init ();
2673
+
2674
+ if (curl ) {
2675
+ struct curl_slist * headers_chunk = NULL ;
2676
+ curl_easy_setopt (curl , CURLOPT_URL , uri );
2677
+
2678
+ headers_chunk = curl_slist_append (headers_chunk , apr_id );
2679
+ headers_chunk = curl_slist_append (headers_chunk , beacon_apr );
2680
+
2681
+ /* send all data to this function */
2682
+ curl_easy_setopt (curl , CURLOPT_WRITEFUNCTION , msc_curl_write_memory_cb );
2683
+
2684
+ /* we pass our 'chunk' struct to the callback function */
2685
+ curl_easy_setopt (curl , CURLOPT_WRITEDATA , (void * )& chunk );
2686
+
2687
+ /* some servers don't like requests that are made without a user-agent
2688
+ field, so we provide one */
2689
+ curl_easy_setopt (curl , CURLOPT_USERAGENT , "ModSecurity" );
2690
+ curl_easy_setopt (curl , CURLOPT_HTTPHEADER , headers_chunk );
2691
+
2692
+ res = curl_easy_perform (curl );
2693
+
2694
+ if (res != CURLE_OK )
2695
+ {
2696
+ * error_msg = apr_psprintf (mp , "Failed to fetch \"%s\" error: %s " , uri , curl_easy_strerror (res ));
2697
+ return -1 ;
2698
+ }
2699
+
2700
+ curl_easy_cleanup (curl );
2701
+ curl_slist_free_all (headers_chunk );
2702
+ }
2703
+ curl_global_cleanup ();
2704
+
2705
+ for (word = strtok_r (chunk .memory , sep , & brkt );
2706
+ word ;
2707
+ word = strtok_r (NULL , sep , & brkt ))
2708
+ {
2709
+ int i = 0 ;
2710
+ line ++ ;
2711
+
2712
+ /* Ignore empty lines and comments */
2713
+ if (* word == '#' ) continue ;
2714
+
2715
+ for (i = 0 ; i < strlen (word ); i ++ )
2716
+ {
2717
+ if (apr_isxdigit (word [i ]) || word [i ] == '.' || word [i ] == '/' || word [i ] == ':' || word [i ] == '\n' )
2718
+ {
2719
+ continue ;
2720
+ }
2721
+
2722
+ * error_msg = apr_psprintf (mp , "Invalid char \"%c\" in line %d " \
2723
+ "of uri %s" , * end , line , uri );
2724
+ return -1 ;
2725
+ }
2726
+
2727
+ if (strchr (word , ':' ) == NULL )
2728
+ {
2729
+ tnode = TreeAddIP (word , (* rtree )-> ipv4_tree , IPV4_TREE );
2730
+ }
2731
+ #if APR_HAVE_IPV6
2732
+ else
2733
+ {
2734
+ tnode = TreeAddIP (word , (* rtree )-> ipv6_tree , IPV6_TREE );
2735
+ }
2736
+ #endif
2737
+
2738
+ if (tnode == NULL )
2739
+ {
2740
+ * error_msg = apr_psprintf (mp , "Could not add entry " \
2741
+ "\"%s\" in line %d of file %s to IP list" , word , line , uri );
2742
+ return -1 ;
2743
+ }
2744
+
2745
+ }
2746
+ return 0 ;
2747
+ }
2748
+
2749
+
2613
2750
int tree_contains_ip (apr_pool_t * mp , TreeRoot * rtree ,
2614
2751
const char * value , modsec_rec * msr , char * * error_msg )
2615
2752
{
@@ -2691,3 +2828,22 @@ int ip_tree_from_param(apr_pool_t *mp,
2691
2828
return 0 ;
2692
2829
}
2693
2830
2831
+ size_t msc_curl_write_memory_cb (void * contents , size_t size ,
2832
+ size_t nmemb , void * userp )
2833
+ {
2834
+ size_t realsize = size * nmemb ;
2835
+ struct msc_curl_memory_buffer_t * mem = (struct msc_curl_memory_buffer_t * )userp ;
2836
+
2837
+ mem -> memory = realloc (mem -> memory , mem -> size + realsize + 1 );
2838
+ if (mem -> memory == NULL ) {
2839
+ /* out of memory! */
2840
+ return 0 ;
2841
+ }
2842
+
2843
+ memcpy (& (mem -> memory [mem -> size ]), contents , realsize );
2844
+ mem -> size += realsize ;
2845
+ mem -> memory [mem -> size ] = 0 ;
2846
+
2847
+ return realsize ;
2848
+ }
2849
+
0 commit comments