~ubuntu-branches/ubuntu/saucy/nginx/saucy-updates

« back to all changes in this revision

Viewing changes to debian/modules/naxsi/naxsi_src/naxsi_runtime.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry, Cyril Lavier, Michael Lustfield, Kartik Mistry
  • Date: 2012-05-14 11:15:00 UTC
  • mfrom: (4.2.49 sid)
  • Revision ID: package-import@ubuntu.com-20120514111500-1y9ij7zulu9xnmry
Tags: 1.2.0-1
[Cyril Lavier]
* New upstream release. (Closes: #670306)
  + 1.2.x is stable release now.
* debian/modules/chunkin-nginx-module:
  + Updated chunkin-nginx-module to v0.23rc2-3-g85eca98.
* debian/modules/headers-more-module:
  + Updated headers-more-module to v0.17rc1-4-g33a82ed.
* debian/modules/nginx-development-kit:
  + Updated nginx-development-kit to v0.2.17-7-g24202b4.
* debian/modules/nginx-echo:
  + Updated nginx-echo to v0.38rc2-7-g080c0a1.
* debian/modules/nginx-lua:
  + Updated nginx-lua to v0.5.0rc25-5-g8d28785.
* debian/modules/nginx-upstream-fair:
  + Updated nginx-upstream-fair to a18b409.
* debian/modules/nginx-upload-progress:
  + Updated nginx-upload-progress to v0.9.0-0-ga788dea.
* debian/modules/naxsi:
  + Updated naxsi to 0.46
* debian/modules/README.Modules-versions:
  + Updated versions and URLs for modules.
* debian/naxsi-ui-extract, debian/naxsi-ui-intercept,
  debian/nginx-naxsi-ui.*, debian/naxsi-ui-extract.1,
  debian/naxsi-ui-intercept.1, debian/rules:
  + Added nginx-naxsi-ui package containing the learning daemon
    and the WebUI.
* debian/nginx-common.nginx.default, debian/nginx-common.nginx.init:
  + Renamed files to be compliant with the nginx-naxsi-ui package.
* debian/po:
  + Added needed files for using po-debconf.
  + Added French translation.
* debian/control:
  + Applied the modifications given after the review by Justin Rye.

[Michael Lustfield]
* debian/conf/uwsgi_params:
  + Added UWSGI_SCHEME to uwsgi_params. (Closes: #664878)
* debian/conf/sites-available/default:
  + Added allow directive for ipv6 localhost. (Closes: #664271)

[Kartik Mistry]
* debian/control:
  + wrap-and-sort.
* debian/copyright:
  + Added missing copyrights, minor formatting fixes.
* debian/nginx-common.nginx.init:
  + Added ulimit for restarts, Thanks to Daniel Roschka
    <danielroschka@phoenitydawn.de> for patch. (Closes: #673580)
* debian/conf/sites-available/default:
  + Added patch to fix deprecated "listen" directive, Thanks to
    Guillaume Plessis <gui@dotdeb.org> for patch. (Closes: #672632)

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 * You should have received a copy of the GNU General Public License
29
29
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
30
30
 */
31
 
 
32
31
#include "naxsi.h"
33
32
 
34
33
/* used to store locations during the configuration time. 
41
40
** We use those to be able to call is_rule_whitelisted_n() on those
42
41
** rules at any time ;)
43
42
*/
 
43
//nx_int__post_without_data
 
44
//nx_int__no_headers
 
45
//nx_int__weird_url
 
46
//nx_int__weird_body
 
47
//nx_int__weird_args
 
48
//nx_int__post_without_content_type
 
49
 
 
50
 
44
51
ngx_http_rule_t nx_int__weird_request = {/*type*/ 0, /*whitelist flag*/ 0, 
45
52
                                         /*wl_id ptr*/ NULL, /*rule_id*/ 1,
46
53
                                         /*log_msg*/ NULL, /*score*/ 0, 
47
 
                                         /*sc_tag*/ NULL, /*sc_score*/ 0,
 
54
                                         /*sscores*/ NULL,
48
55
                                         /*sc_block*/ 0,  /*sc_allow*/ 0, 
49
56
                                         /*block*/ 1,  /*allow*/ 0, 
50
57
                                         /*lnk_to & from*/ 0, 0,
51
 
                                         /*fr & br ptrs*/ NULL, NULL};
 
58
                                         /*br ptrs*/ NULL};
52
59
ngx_http_rule_t nx_int__big_request = {/*type*/ 0, /*whitelist flag*/ 0, 
53
60
                                       /*wl_id ptr*/ NULL, /*rule_id*/ 2,
54
61
                                       /*log_msg*/ NULL, /*score*/ 0, 
55
 
                                       /*sc_tag*/ NULL, /*sc_score*/ 0,
 
62
                                       /*sscores*/ NULL,
56
63
                                       /*sc_block*/ 0,  /*sc_allow*/ 0, 
57
64
                                       /*block*/ 1,  /*allow*/ 0, 
58
65
                                       /*lnk_to & from*/ 0, 0,
59
 
                                       /*fr & br ptrs*/ NULL, NULL};
 
66
                                       /*br ptrs*/ NULL};
60
67
 
61
68
#define dummy_error_fatal(ctx, r, ...) do {                             \
62
69
    if (ctx) ctx->block = 1;                                            \
571
578
        strcat(tmp_zone, "HEADERS");
572
579
      if (mr[i].url)
573
580
        strcat(tmp_zone, "URL");
 
581
      if (mr[i].target_name)
 
582
        strcat(tmp_zone, "|NAME");
 
583
      
574
584
      w += snprintf(fmt+w, rc, fmt_rm, i, tmp_zone, i, 
575
585
                    mr[i].rule->rule_id, i, mr[i].name->len, 
576
586
                    mr[i].name->data);
643
653
/*
644
654
** new rulematch, less arguments ^
645
655
*/
646
 
/* #define whitelist_debug */
 
656
#define whitelist_debug 
647
657
/* #define whitelist_light_debug */
648
658
/* #define whitelist_heavy_debug */
649
659
 
653
663
                             ngx_str_t *value, enum DUMMY_MATCH_ZONE zone, 
654
664
                             ngx_int_t nb_match, ngx_int_t target_name)
655
665
{
656
 
  unsigned int          found = 0, i;
657
 
  ngx_http_special_score_t      *sc;
 
666
  unsigned int          found = 0, i, z;
 
667
  ngx_http_special_score_t      *sc, *rsc;
658
668
  ngx_http_dummy_loc_conf_t     *cf;
659
669
  ngx_http_matched_rule_t       *mr;
660
670
  
661
671
  cf = ngx_http_get_module_loc_conf(req, ngx_http_naxsi_module);
662
672
  if (!cf || !ctx )
663
673
    return ;
664
 
  if (ngx_http_dummy_is_rule_whitelisted_n(req, cf, r, name, zone, target_name) == 1)
 
674
  if (ngx_http_dummy_is_rule_whitelisted_n(req, cf, r, name, 
 
675
                                           zone, target_name) == 1) {
 
676
  #ifdef whitelist_light_debug
 
677
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
 
678
                  "rule is whitelisted.");
 
679
  #endif  
665
680
    return ;
 
681
  }
666
682
  if (nb_match == 0)
667
683
    nb_match = 1;
668
 
  /* it was not whitelisted, apply score and stuff */
669
 
#ifdef whitelist_light_debug
670
 
  if (req->uri.len > 0) {
671
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
672
 
                  "[%V][%V] rule(%d) matched %d times on %s(%V)=(%V) [zones(%s,%s,%s,%s)]", 
673
 
                  r->log_msg, &(req->uri), r->rule_id, nb_match, 
674
 
                  target_name ? "[var name] " : "", name, value,
675
 
                  zone == HEADERS ? "HEADERS" : "",
676
 
                  zone == URL ? "URL" : "",
677
 
                  zone == BODY ? "BODY" : "",
678
 
                  zone == ARGS ? "ARGS" : "");
679
 
  }
680
 
  else {
681
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
682
 
                  "[xx][XXX] rule(%d) matched %d times on %s(%V)=(%V) [zones(%s,%s,%s,%s)]", r->rule_id, nb_match, 
683
 
                  target_name ? "[var name] " : "", name, value,
684
 
                  zone == HEADERS ? "HEADERS" : "",
685
 
                  zone == URL ? "URL" : "",
686
 
                  zone == BODY ? "BODY" : "",
687
 
                  zone == ARGS ? "ARGS" : "");
688
 
 
689
 
  }
690
 
#endif
691
684
  if (!ctx->matched)
692
685
    ctx->matched = ngx_array_create(req->pool, 2, 
693
686
                                    sizeof(ngx_http_matched_rule_t));
698
691
  if (!mr)
699
692
    return ;
700
693
  memset(mr, 0, sizeof(ngx_http_matched_rule_t));
 
694
  if (target_name)
 
695
    mr->target_name = 1;
701
696
  switch(zone) {
702
697
  case HEADERS:
703
698
    mr->headers_var = 1;
727
722
    mr->name->len = 0; 
728
723
  }
729
724
  /* apply special score on rulematch */
730
 
  if (r->sc_tag) {
731
 
      
 
725
  if (r->sscores) {
 
726
#ifdef whitelist_debug
 
727
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
728
                  "Rule applies %d custom scores", r->sscores->nelts);
 
729
#endif
 
730
    if (!ctx->special_scores) //create the list
 
731
      ctx->special_scores = ngx_array_create(req->pool, 1, 
 
732
                                             sizeof(ngx_http_special_score_t));
732
733
    found = 0;
733
 
    if (!ctx->special_scores) //create the list
734
 
      ctx->special_scores = ngx_array_create(req->pool, 1, sizeof(ngx_http_special_score_t));
735
 
    else {
 
734
    rsc = r->sscores->elts;
 
735
    for (z = 0; z < r->sscores->nelts; z++) {
736
736
      //search into the list for matching special score
 
737
      found = 0;
737
738
      sc = ctx->special_scores->elts;
738
739
      for (i = 0; i < ctx->special_scores->nelts; i++) {
739
 
        if (sc[i].sc_tag->len == r->sc_tag->len && 
740
 
            !ngx_strcmp(sc[i].sc_tag->data, r->sc_tag->data)) {
 
740
        if (rsc[z].sc_tag && sc[i].sc_tag && sc[i].sc_tag->len == rsc[z].sc_tag->len && 
 
741
            !ngx_strcmp(sc[i].sc_tag->data, rsc[z].sc_tag->data)) {
741
742
#ifdef whitelist_debug
742
 
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
743
 
                        "Special Score (%V) actual=%d,next=%d", r->sc_tag, 
744
 
                        sc[i].sc_score, sc[i].sc_score+(r->sc_score * nb_match));
 
743
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
 
744
                        "Special Score (%V) actual=%d,next=%d", rsc[z].sc_tag,
 
745
                        sc[i].sc_score, sc[i].sc_score+(rsc[z].sc_score * nb_match));
745
746
#endif
746
 
          sc[i].sc_score += (r->sc_score * nb_match);
 
747
          sc[i].sc_score += (rsc[z].sc_score * nb_match);
747
748
          found = 1;
748
749
          break;
749
750
        }
750
751
      }
751
 
    }
752
 
    //else push it.
753
 
    if (!found) {
 
752
      
 
753
      
 
754
      if (!found) {
754
755
#ifdef whitelist_debug
755
 
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
756
 
                    "Special Score (%s) actual=%d,next=%d", r->sc_tag->data, 
757
 
                    0, r->sc_score);
 
756
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
757
                      "Special Score (%V)  next=%d", 
 
758
                      rsc[z].sc_tag, (rsc[z].sc_score * nb_match));
758
759
#endif
759
 
      sc = ngx_array_push(ctx->special_scores);
760
 
      if (!sc)
761
 
        return ;
762
 
      memset(sc, 0, sizeof(ngx_http_special_score_t));
763
 
      sc->sc_tag = r->sc_tag;
764
 
      sc->sc_score = (r->sc_score * nb_match);
 
760
        sc = ngx_array_push(ctx->special_scores);
 
761
        if (!sc)
 
762
          return ;
 
763
        memset(sc, 0, sizeof(ngx_http_special_score_t));
 
764
        sc->sc_tag = rsc[z].sc_tag;
 
765
        sc->sc_score = (rsc[z].sc_score * nb_match);    
 
766
      }
765
767
    }
766
768
  }
767
 
  else {
768
 
    /* else, apply normal score */
769
 
    ctx->score += (r->sc_score * nb_match);
770
 
    if (r->block)
771
 
      ctx->block = 1;
772
 
    if (r->allow)
773
 
      ctx->allow = 1;
774
 
  }
 
769
  //else {
 
770
  /* else, apply normal score */
 
771
  ctx->score += (r->score * nb_match);
 
772
  if (r->block)
 
773
    ctx->block = 1;
 
774
  if (r->allow)
 
775
    ctx->allow = 1;
 
776
  //}
775
777
  
776
778
  ngx_http_dummy_update_current_ctx_status(ctx, cf, req);
777
779
  return ;
908
910
  return (0);
909
911
}
910
912
 
911
 
/*
912
 
** check variable + name against a set of rules, checking against 'custom' location rules too.
913
 
*/
 
913
    /*
 
914
    ** check variable + name against a set of rules, checking against 'custom' location rules too.
 
915
    */
914
916
#define basestr_ruleset_debug
915
917
 
916
 
int 
917
 
ngx_http_basestr_ruleset_n(ngx_pool_t *pool,
918
 
                           ngx_str_t    *name,
919
 
                           ngx_str_t    *value,
920
 
                           ngx_array_t *rules,
921
 
                           ngx_http_request_t *req,
922
 
                           ngx_http_request_ctx_t *ctx,
923
 
                           enum DUMMY_MATCH_ZONE        zone)
924
 
{
925
 
  ngx_http_rule_t                  *r;
926
 
  unsigned int                     i, ret, z;
927
 
  ngx_int_t                        nb_match;
928
 
  ngx_http_custom_rule_location_t *location;
929
 
  ngx_http_dummy_loc_conf_t     *cf;
 
918
    int 
 
919
      ngx_http_basestr_ruleset_n(ngx_pool_t *pool,
 
920
                                 ngx_str_t      *name,
 
921
                                 ngx_str_t      *value,
 
922
                                 ngx_array_t *rules,
 
923
                                 ngx_http_request_t *req,
 
924
                                 ngx_http_request_ctx_t *ctx,
 
925
                                 enum DUMMY_MATCH_ZONE  zone)
 
926
    {
 
927
      ngx_http_rule_t              *r;
 
928
      unsigned int                         i, ret, z;
 
929
      ngx_int_t                    nb_match;
 
930
      ngx_http_custom_rule_location_t *location;
 
931
      ngx_http_dummy_loc_conf_t *cf;
930
932
  
931
933
#ifdef basestr_ruleset_debug
932
 
  ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
933
 
                "XX-check check [%V]=[%V] in zone %s", name, value,
934
 
                zone == BODY ? "BODY" : zone == HEADERS ? "HEADERS" : zone == URL ? "URL" :
935
 
                zone == ARGS ? "ARGS" : "UNKNOWN"); 
936
 
#endif
937
 
  
938
 
  if (!rules) {
939
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
940
 
                  "XX-no rules, wtf ?!"); 
941
 
    return (0);
942
 
  }
943
 
  r = rules->elts;
944
 
  cf = ngx_http_get_module_loc_conf(req, ngx_http_naxsi_module);
945
 
#ifdef basestr_ruleset_debug 
946
 
  ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
947
 
                "XX-checking rules ..."); 
948
 
#endif
949
 
  
950
 
  for (i = 0; i < rules->nelts && (!ctx->block || cf->learning) ; i++) {
951
 
#ifdef basestr_ruleset_debug 
952
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
953
 
                  "XX-rule %d (%V=%V)", r[i].rule_id, name, value); 
 
934
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
935
                    "XX-check check [%V]=[%V] in zone %s", name, value,
 
936
                    zone == BODY ? "BODY" : zone == HEADERS ? "HEADERS" : zone == URL ? "URL" :
 
937
                    zone == ARGS ? "ARGS" : "UNKNOWN"); 
 
938
#endif
 
939
  
 
940
      if (!rules) {
 
941
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
942
                      "XX-no rules, wtf ?!"); 
 
943
        return (0);
 
944
      }
 
945
      r = rules->elts;
 
946
      cf = ngx_http_get_module_loc_conf(req, ngx_http_naxsi_module);
 
947
#ifdef basestr_ruleset_debug 
 
948
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
949
                    "XX-checking rules ..."); 
 
950
#endif
 
951
  
 
952
      for (i = 0; i < rules->nelts && (!ctx->block || cf->learning) ; i++) {
 
953
#ifdef basestr_ruleset_debug 
 
954
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
955
                      "XX-rule %d (%V=%V)", r[i].rule_id, name, value); 
954
956
#endif
955
957
      
956
 
    /* does the rule have a custom location ? custom location means checking only on a specific argument */
957
 
    if (name && name->len > 0 && r[i].br->custom_location) {
958
 
      location = r[i].br->custom_locations->elts;
959
 
      /* for each custom location */
960
 
      for (z = 0; z < r[i].br->custom_locations->nelts; z++) {
961
 
        /* if the name are the same, check */
962
 
        if (name->len == location[z].target.len &&
963
 
            !strncasecmp((const char *)name->data, 
964
 
                         (const char *) location[z].target.data, 
965
 
                         location[z].target.len)) {
 
958
        /* does the rule have a custom location ? custom location means checking only on a specific argument */
 
959
        if (name && name->len > 0 && r[i].br->custom_location) {
 
960
          location = r[i].br->custom_locations->elts;
 
961
          /* for each custom location */
 
962
          for (z = 0; z < r[i].br->custom_locations->nelts; z++) {
 
963
            /* if the name are the same, check */
 
964
            if (name->len == location[z].target.len &&
 
965
                !strncasecmp((const char *)name->data, 
 
966
                             (const char *) location[z].target.data, 
 
967
                             location[z].target.len)) {
966
968
            
967
969
#ifdef basestr_ruleset_debug
968
 
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
969
 
                        "XX-[SPECIFIC] check one rule [%d] iteration %d * %d", r[i].rule_id, i, z);
970
 
#endif
971
 
          /* match rule against var content, */
 
970
              ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
 
971
                            "XX-[SPECIFIC] check one rule [%d] iteration %d * %d", r[i].rule_id, i, z);
 
972
#endif
 
973
              /* match rule against var content, */
 
974
              ret = ngx_http_process_basic_rule_buffer(value, &(r[i]), &nb_match);
 
975
              //if our rule matched, apply effects (score etc.)
 
976
              if (ret == 1) {
 
977
#ifdef basestr_ruleset_debug
 
978
                ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
979
                              "XX-apply rulematch!! [%V]=[%V] [rule=%d] (match %d times)", name, value, r[i].rule_id, nb_match); 
 
980
#endif
 
981
                ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 0);            
 
982
              }
 
983
          
 
984
              if (!r[i].br->negative) {  
 
985
                /* match rule against var name, */
 
986
                ret = ngx_http_process_basic_rule_buffer(name, &(r[i]), &nb_match);
 
987
                //if our rule matched, apply effects (score etc.)
 
988
                if (ret == 1) {
 
989
#ifdef basestr_ruleset_debug
 
990
                  ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
991
                                "XX-apply rulematch[in name] [%V]=[%V] [rule=%d] (match %d times)", name, value, r[i].rule_id, nb_match); 
 
992
#endif
 
993
                  ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, name, zone, nb_match, 1);
 
994
                }
 
995
              }
 
996
          
 
997
            }
 
998
          }
 
999
      
 
1000
        }
 
1001
    
 
1002
    
 
1003
    
 
1004
        /*
 
1005
        ** check against the rule if the current zone is matching 
 
1006
        ** the zone the rule is meant to be check against
 
1007
        */
 
1008
        if ( (zone == HEADERS && r[i].br->headers) ||
 
1009
             (zone == URL && r[i].br->url) ||
 
1010
             (zone == ARGS && r[i].br->args) ||
 
1011
             (zone == BODY && r[i].br->body && !r[i].br->file_ext) ||
 
1012
             (zone == FILE_EXT && r[i].br->file_ext) ) {
 
1013
 
 
1014
          /* #ifdef basestr_ruleset_debug */
 
1015
          /*    ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,  */
 
1016
          /*                  "XX-check [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);  */
 
1017
          /* #endif */
 
1018
 
 
1019
#ifdef basestr_ruleset_debug
 
1020
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
1021
                        "XX-test rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); 
 
1022
#endif
 
1023
    
 
1024
          /* check the rule against the value*/
972
1025
          ret = ngx_http_process_basic_rule_buffer(value, &(r[i]), &nb_match);
973
 
          //if our rule matched, apply effects (score etc.)
 
1026
          /*if our rule matched, apply effects (score etc.)*/
974
1027
          if (ret == 1) {
975
1028
#ifdef basestr_ruleset_debug
976
1029
            ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
977
 
                          "XX-apply rulematch!! [%V]=[%V] [rule=%d] (match %d times)", name, value, r[i].rule_id, nb_match); 
 
1030
                          "XX-apply rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); 
978
1031
#endif
979
 
            ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 0);        
 
1032
            ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 0);
980
1033
          }
981
 
          
982
 
          if (!r[i].br->negative) {  
983
 
            /* match rule against var name, */
 
1034
    
 
1035
          if (!r[i].br->negative) {
 
1036
#ifdef basestr_ruleset_debug
 
1037
            ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
 
1038
                          "XX-test rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); 
 
1039
#endif
 
1040
            /* check the rule against the name*/
984
1041
            ret = ngx_http_process_basic_rule_buffer(name, &(r[i]), &nb_match);
985
 
            //if our rule matched, apply effects (score etc.)
 
1042
            /*if our rule matched, apply effects (score etc.)*/
986
1043
            if (ret == 1) {
987
1044
#ifdef basestr_ruleset_debug
988
1045
              ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
989
 
                            "XX-apply rulematch[in name] [%V]=[%V] [rule=%d] (match %d times)", name, value, r[i].rule_id, nb_match); 
 
1046
                            "XX-apply rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); 
990
1047
#endif
991
 
              ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, name, zone, nb_match, 1);
 
1048
              ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 1);
992
1049
            }
993
1050
          }
994
 
          
995
1051
        }
996
1052
      }
997
 
      
 
1053
      return (0);
998
1054
    }
999
 
    
1000
 
    
1001
 
    
 
1055
  
 
1056
 
 
1057
 
 
1058
 
1002
1059
    /*
1003
 
    ** check against the rule if the current zone is matching 
1004
 
    ** the zone the rule is meant to be check against
 
1060
    ** does : parse body data, a.k.a POST/PUT datas. identifies content-type,
 
1061
    **    and, if appropriate, boundary. then parse the stuff if multipart/for..
 
1062
    **    or rely on spliturl if application/x-w..
 
1063
    ** [XXX] : this function sucks ! I don't parse bigger-than-body-size posts that 
 
1064
    **     are partially stored in files, TODO ;)
1005
1065
    */
1006
 
    if ( (zone == HEADERS && r[i].br->headers) ||
1007
 
         (zone == URL && r[i].br->url) ||
1008
 
         (zone == ARGS && r[i].br->args) ||
1009
 
         (zone == BODY && r[i].br->body && !r[i].br->file_ext) ||
1010
 
         (zone == FILE_EXT && r[i].br->file_ext) ) {
1011
 
 
1012
 
      /* #ifdef basestr_ruleset_debug */
1013
 
      /*        ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,  */
1014
 
      /*                      "XX-check [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);  */
1015
 
      /* #endif */
1016
 
 
1017
 
#ifdef basestr_ruleset_debug
1018
 
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
1019
 
                    "XX-test rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); 
1020
 
#endif
1021
 
    
1022
 
      /* check the rule against the value*/
1023
 
      ret = ngx_http_process_basic_rule_buffer(value, &(r[i]), &nb_match);
1024
 
      /*if our rule matched, apply effects (score etc.)*/
1025
 
      if (ret == 1) {
1026
 
#ifdef basestr_ruleset_debug
1027
 
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
1028
 
                      "XX-apply rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); 
1029
 
#endif
1030
 
        ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 0);
1031
 
      }
1032
 
    
1033
 
      if (!r[i].br->negative) {
1034
 
#ifdef basestr_ruleset_debug
1035
 
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
1036
 
                      "XX-test rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); 
1037
 
#endif
1038
 
        /* check the rule against the name*/
1039
 
        ret = ngx_http_process_basic_rule_buffer(name, &(r[i]), &nb_match);
1040
 
        /*if our rule matched, apply effects (score etc.)*/
1041
 
        if (ret == 1) {
1042
 
#ifdef basestr_ruleset_debug
1043
 
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, 
1044
 
                        "XX-apply rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); 
1045
 
#endif
1046
 
          ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 1);
1047
 
        }
1048
 
      }
1049
 
    }
1050
 
  }
1051
 
  return (0);
1052
 
}
1053
 
  
1054
 
 
1055
 
 
1056
 
 
1057
 
  /*
1058
 
  ** does : parse body data, a.k.a POST/PUT datas. identifies content-type,
1059
 
  **      and, if appropriate, boundary. then parse the stuff if multipart/for..
1060
 
  **      or rely on spliturl if application/x-w..
1061
 
  ** [XXX] : this function sucks ! I don't parse bigger-than-body-size posts that 
1062
 
  **       are partially stored in files, TODO ;)
1063
 
  */
1064
 
  //#define post_heavy_debug
1065
 
  //#define dummy_body_parse_debug
1066
 
void    ngx_http_dummy_multipart_parse(ngx_http_request_ctx_t *ctx, 
1067
 
                                       ngx_http_request_t        *r,
1068
 
                                       u_char                   *src,
1069
 
                                       u_int                     len)
1070
 
{
1071
 
  ngx_str_t                             final_var, final_data;
1072
 
  char                          *boundary, *varn_start, *varn_end;
1073
 
  char                          *filen_start, *filen_end;
1074
 
  char                          *end, *line_end;
1075
 
  u_int                         boundary_len, varn_len, varc_len, idx;
1076
 
  ngx_http_dummy_loc_conf_t             *cf;
1077
 
  ngx_http_dummy_main_conf_t            *main_cf;
1078
 
  
1079
 
  cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module);
1080
 
  main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module);
 
1066
    //#define post_heavy_debug
 
1067
    //#define dummy_body_parse_debug
 
1068
    void        ngx_http_dummy_multipart_parse(ngx_http_request_ctx_t *ctx, 
 
1069
                                               ngx_http_request_t        *r,
 
1070
                                               u_char                   *src,
 
1071
                                               u_int                     len)
 
1072
    {
 
1073
      ngx_str_t                         final_var, final_data;
 
1074
      char                              *boundary, *varn_start, *varn_end;
 
1075
      char                              *filen_start, *filen_end;
 
1076
      char                              *end, *line_end;
 
1077
      u_int                             boundary_len, varn_len, varc_len, idx;
 
1078
      ngx_http_dummy_loc_conf_t         *cf;
 
1079
      ngx_http_dummy_main_conf_t                *main_cf;
 
1080
  
 
1081
      cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module);
 
1082
      main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module);
1081
1083
  
1082
1084
#ifdef post_heavy_debug
1083
 
  ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1084
 
                "XX-multipart/form-data");
 
1085
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1086
                    "XX-multipart/form-data");
1085
1087
#endif
1086
 
  /* So far, I have noticed to correct ways of putting the boundary in a multipart post :
1087
 
  ** 1: in the content-type header, after multipart/form-data
1088
 
  ** 2: at the very begining of the body. */
1089
 
  /*extract boundary*/
1090
 
  boundary = ngx_strstr(src, "boundary=");
1091
 
  if (!boundary)
1092
 
    boundary = ngx_strstr(r->headers_in.content_type->value.data, "boundary=");
1093
 
  if (!boundary)
1094
 
    {
1095
 
      dummy_error_fatal(ctx, r, "no boundary present in POST data ?");
1096
 
      return ;
1097
 
    }
1098
 
  boundary += 9; //strlen ("boundary=")
1099
 
  boundary_len = strlen(boundary);
 
1088
      /* So far, I have noticed to correct ways of putting the boundary in a multipart post :
 
1089
      ** 1: in the content-type header, after multipart/form-data
 
1090
      ** 2: at the very begining of the body. */
 
1091
      /*extract boundary*/
 
1092
      boundary = ngx_strstr(src, "boundary=");
 
1093
      if (!boundary)
 
1094
        boundary = ngx_strstr(r->headers_in.content_type->value.data, "boundary=");
 
1095
      if (!boundary)
 
1096
        {
 
1097
          dummy_error_fatal(ctx, r, "no boundary present in POST data ?");
 
1098
          return ;
 
1099
        }
 
1100
      boundary += 9; //strlen ("boundary=")
 
1101
      boundary_len = strlen(boundary);
1100
1102
   
1101
 
  /* fetch every line starting with boundary */
1102
 
  idx = 0;
1103
 
  while (idx < len) {
1104
 
#ifdef post_heavy_debug
1105
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1106
 
                  "XX-POST data : (%s)", src+idx);
1107
 
#endif
1108
 
    //dummy_error_fatal(ctx, r, "POST data : (%s)", src+idx);
1109
 
    /* if we've reached the last boundary '--' + boundary + '--' + '\r\n'*/
1110
 
    if (idx+boundary_len+6 >= len)
1111
 
      {
 
1103
      /* fetch every line starting with boundary */
 
1104
      idx = 0;
 
1105
      while (idx < len) {
1112
1106
#ifdef post_heavy_debug
1113
1107
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1114
 
                      "XX-reached end, not enough len");
1115
 
#endif
1116
 
        break;
1117
 
      }
1118
 
    //check if line starts with -- (pre-boundary stuff) 
1119
 
    if (src[idx] != '-' || src[idx+1] != '-' || 
1120
 
        //and if it's really followed by a boundary
1121
 
        ngx_strncmp(src+idx+2, boundary, boundary_len) || 
1122
 
        //and if it's not the last boundary of the buffer
1123
 
        idx+boundary_len + 2 + 2  >= len ||  
1124
 
        //and if it's followed by \r\n
1125
 
        src[idx+boundary_len+2] != '\r' || src[idx+boundary_len+3] != '\n') {
1126
 
      
1127
 
      dummy_error_fatal(ctx, r, "POST data is malformed (%s)", src+idx);
1128
 
      return ;
1129
 
    }
1130
 
    idx += boundary_len + 4;
1131
 
    /* we have two cases :
1132
 
    ** ---- file upload
1133
 
    ** Content-Disposition: form-data; name="somename"; filename="NetworkManager.conf"\r\n
1134
 
    ** Content-Type: application/octet-stream\r\n\r\n
1135
 
    ** <DATA>
1136
 
    ** ---- normal post var
1137
 
    ** Content-Disposition: form-data; name="lastname"\r\n\r\n
1138
 
    ** <DATA>
1139
 
    */
1140
 
    if (ngx_strncasecmp(src+idx, 
1141
 
                        (u_char *) "content-disposition: form-data;", 30)) {
1142
 
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1143
 
                    "Unknown content-type: [%s]", src+idx);
1144
 
      dummy_error_fatal(ctx, r, "POST data : unknown content-disposition");
1145
 
      
1146
 
      return ;
1147
 
    }
1148
 
    idx += 30;
1149
 
    line_end = ngx_strchr(src+idx, '\n');
1150
 
    if (!line_end) {
1151
 
      dummy_error_fatal(ctx, r, "POST data : malformed boundary line");
1152
 
      return ;
1153
 
    }
1154
 
    // seek for name="<var>" and filename="<var>" in the current line
1155
 
    // verify that the name/filename tag founds are present
1156
 
    varn_end = filen_end = NULL;
1157
 
    varn_start = ngx_strstr(src+idx, "name=\"");
1158
 
    if (varn_start && varn_start < line_end) {
1159
 
      varn_start += 6;
1160
 
      varn_end = ngx_strchr(varn_start, '"');
1161
 
    }
1162
 
    else
1163
 
      varn_start = NULL;
1164
 
    filen_start = ngx_strstr(src+idx, "filename=\"");
1165
 
    if (filen_start && filen_start < line_end) {
1166
 
      filen_start += 10;
1167
 
      /* avoid being bypassed by filenames like bla\"aa.php */
1168
 
      filen_end = filen_start;
1169
 
      do {
1170
 
        filen_end = ngx_strchr(filen_end, '"');
1171
 
        if (*(filen_end - 1) != '\\')
1172
 
          break;
1173
 
        filen_end++;
1174
 
      } while (filen_end < line_end);
1175
 
      /* here add support :
1176
 
      ** - when a file is here, the line bellow 'content-disposition' is content-type.
1177
 
      ** - skip this line. we should probably parse it ... to make regex on it :D
1178
 
      */
1179
 
      line_end = ngx_strchr(line_end+1, '\n');
1180
 
      if (!line_end) {
1181
 
        dummy_error_fatal(ctx, r, "POST data : malformed 'filename' field");
1182
 
        return ;
1183
 
      }
1184
 
    }
1185
 
    else
1186
 
      filen_start = NULL;
 
1108
                      "XX-POST data : (%s)", src+idx);
 
1109
#endif
 
1110
        //dummy_error_fatal(ctx, r, "POST data : (%s)", src+idx);
 
1111
        /* if we've reached the last boundary '--' + boundary + '--' + '\r\n'*/
 
1112
        if (idx+boundary_len+6 >= len)
 
1113
          {
 
1114
#ifdef post_heavy_debug
 
1115
            ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1116
                          "XX-reached end, not enough len");
 
1117
#endif
 
1118
            break;
 
1119
          }
 
1120
        //check if line starts with -- (pre-boundary stuff) 
 
1121
        if (src[idx] != '-' || src[idx+1] != '-' || 
 
1122
            //and if it's really followed by a boundary
 
1123
            ngx_strncmp(src+idx+2, boundary, boundary_len) || 
 
1124
            //and if it's not the last boundary of the buffer
 
1125
            idx+boundary_len + 2 + 2  >= len ||  
 
1126
            //and if it's followed by \r\n
 
1127
            src[idx+boundary_len+2] != '\r' || src[idx+boundary_len+3] != '\n') {
 
1128
      
 
1129
          dummy_error_fatal(ctx, r, "POST data is malformed (%s)", src+idx);
 
1130
          return ;
 
1131
        }
 
1132
        idx += boundary_len + 4;
 
1133
        /* we have two cases :
 
1134
        ** ---- file upload
 
1135
        ** Content-Disposition: form-data; name="somename"; filename="NetworkManager.conf"\r\n
 
1136
        ** Content-Type: application/octet-stream\r\n\r\n
 
1137
        ** <DATA>
 
1138
        ** ---- normal post var
 
1139
        ** Content-Disposition: form-data; name="lastname"\r\n\r\n
 
1140
        ** <DATA>
 
1141
        */
 
1142
        if (ngx_strncasecmp(src+idx, 
 
1143
                            (u_char *) "content-disposition: form-data;", 30)) {
 
1144
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1145
                        "Unknown content-type: [%s]", src+idx);
 
1146
          dummy_error_fatal(ctx, r, "POST data : unknown content-disposition");
 
1147
      
 
1148
          return ;
 
1149
        }
 
1150
        idx += 30;
 
1151
        line_end = ngx_strchr(src+idx, '\n');
 
1152
        if (!line_end) {
 
1153
          dummy_error_fatal(ctx, r, "POST data : malformed boundary line");
 
1154
          return ;
 
1155
        }
 
1156
        // seek for name="<var>" and filename="<var>" in the current line
 
1157
        // verify that the name/filename tag founds are present
 
1158
        varn_end = filen_end = NULL;
 
1159
        varn_start = ngx_strstr(src+idx, "name=\"");
 
1160
        if (varn_start && varn_start < line_end) {
 
1161
          varn_start += 6;
 
1162
          varn_end = ngx_strchr(varn_start, '"');
 
1163
        }
 
1164
        else
 
1165
          varn_start = NULL;
 
1166
        filen_start = ngx_strstr(src+idx, "filename=\"");
 
1167
        if (filen_start && filen_start < line_end) {
 
1168
          filen_start += 10;
 
1169
          /* avoid being bypassed by filenames like bla\"aa.php */
 
1170
          filen_end = filen_start;
 
1171
          do {
 
1172
            filen_end = ngx_strchr(filen_end, '"');
 
1173
            if (*(filen_end - 1) != '\\')
 
1174
              break;
 
1175
            filen_end++;
 
1176
          } while (filen_end < line_end);
 
1177
          /* here add support :
 
1178
          ** - when a file is here, the line bellow 'content-disposition' is content-type.
 
1179
          ** - skip this line. we should probably parse it ... to make regex on it :D
 
1180
          */
 
1181
          line_end = ngx_strchr(line_end+1, '\n');
 
1182
          if (!line_end) {
 
1183
            dummy_error_fatal(ctx, r, "POST data : malformed 'filename' field");
 
1184
            return ;
 
1185
          }
 
1186
        }
 
1187
        else
 
1188
          filen_start = NULL;
1187
1189
          
1188
 
    // check that var name is present and not malformed
1189
 
    if (!varn_start || !varn_end || varn_end <= varn_start) {
1190
 
      dummy_error_fatal(ctx, r, "POST data : no 'name' in POST var");
1191
 
      return ;
1192
 
    }
1193
 
    varn_len = varn_end - varn_start;
1194
 
    // now idx point to the end of the
1195
 
    // content-disposition: form-data; filename="" name=""
1196
 
    idx += (u_char *)line_end - (src+idx) + 1;
1197
 
    if (src[idx] != '\r' || src[idx+1] != '\n') {
1198
 
      dummy_error_fatal(ctx, r, "POST data : malformed content-disposition line");
1199
 
      return ;
1200
 
    }
1201
 
    idx += 2;
1202
 
    // seek the end of the data too
1203
 
    end = NULL;
1204
 
    while (idx < len) {
1205
 
      end = ngx_strstr(src+idx, "\r\n--");
1206
 
      if (!end) {
1207
 
        dummy_error_fatal(ctx, r, "POST data : malformed content-disposition line");
1208
 
        return ;
1209
 
      }
1210
 
      if (!ngx_strncmp(end+4, boundary, boundary_len))
1211
 
        break;
1212
 
      else {
1213
 
        idx += ((u_char *) end - (src+idx)) + 1;
 
1190
        // check that var name is present and not malformed
 
1191
        if (!varn_start || !varn_end || varn_end <= varn_start) {
 
1192
          dummy_error_fatal(ctx, r, "POST data : no 'name' in POST var");
 
1193
          return ;
 
1194
        }
 
1195
        varn_len = varn_end - varn_start;
 
1196
        // now idx point to the end of the
 
1197
        // content-disposition: form-data; filename="" name=""
 
1198
        idx += (u_char *)line_end - (src+idx) + 1;
 
1199
        if (src[idx] != '\r' || src[idx+1] != '\n') {
 
1200
          dummy_error_fatal(ctx, r, "POST data : malformed content-disposition line");
 
1201
          return ;
 
1202
        }
 
1203
        idx += 2;
 
1204
        // seek the end of the data too
1214
1205
        end = NULL;
1215
 
      }
1216
 
    }
1217
 
    if (!end) {
1218
 
      dummy_error_fatal(ctx, r, "POST data : malformed line");
1219
 
      return ;
1220
 
    }
1221
 
    if (filen_start) {
1222
 
      final_var.data = (unsigned char *)varn_start;
1223
 
      final_var.len = varn_len;
1224
 
      final_data.data = (unsigned char *)filen_start;
1225
 
      final_data.len = filen_end - filen_start;
 
1206
        while (idx < len) {
 
1207
          end = ngx_strstr(src+idx, "\r\n--");
 
1208
          if (!end) {
 
1209
            dummy_error_fatal(ctx, r, "POST data : malformed content-disposition line");
 
1210
            return ;
 
1211
          }
 
1212
          if (!ngx_strncmp(end+4, boundary, boundary_len))
 
1213
            break;
 
1214
          else {
 
1215
            idx += ((u_char *) end - (src+idx)) + 1;
 
1216
            end = NULL;
 
1217
          }
 
1218
        }
 
1219
        if (!end) {
 
1220
          dummy_error_fatal(ctx, r, "POST data : malformed line");
 
1221
          return ;
 
1222
        }
 
1223
        if (filen_start) {
 
1224
          final_var.data = (unsigned char *)varn_start;
 
1225
          final_var.len = varn_len;
 
1226
          final_data.data = (unsigned char *)filen_start;
 
1227
          final_data.len = filen_end - filen_start;
1226
1228
#ifdef post_heavy_debug
1227
 
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1228
 
                    "[POST] checking filename [%V] = [%V]",
1229
 
                    &final_var, &final_data);
 
1229
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1230
                        "[POST] checking filename [%V] = [%V]",
 
1231
                        &final_var, &final_data);
1230
1232
#endif
1231
 
      /* here we got val name + val content !*/       
1232
 
      if (cf->body_rules)
1233
 
        ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1234
 
                                   cf->body_rules, r, ctx, FILE_EXT);
 
1233
          /* here we got val name + val content !*/           
 
1234
          if (cf->body_rules)
 
1235
            ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
 
1236
                                       cf->body_rules, r, ctx, FILE_EXT);
1235
1237
#ifdef post_heavy_debug
1236
 
      else
1237
 
        /* here we got val name + val content !*/             
1238
 
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1239
 
                      "No local body rules ?!");
 
1238
          else
 
1239
            /* here we got val name + val content !*/         
 
1240
            ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1241
                          "No local body rules ?!");
1240
1242
#endif
1241
1243
                
1242
 
      if (main_cf->body_rules)
1243
 
        ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1244
 
                                   main_cf->body_rules, r, ctx, FILE_EXT);
 
1244
          if (main_cf->body_rules)
 
1245
            ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
 
1246
                                       main_cf->body_rules, r, ctx, FILE_EXT);
1245
1247
#ifdef post_heavy_debug
1246
 
      else
1247
 
        /* here we got val name + val content !*/             
1248
 
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1249
 
                      "No main body rules ?!");
 
1248
          else
 
1249
            /* here we got val name + val content !*/         
 
1250
            ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1251
                          "No main body rules ?!");
1250
1252
#endif
1251
1253
      
1252
 
      idx += (u_char *) end - (src+idx);
1253
 
    }
1254
 
    else
1255
 
      if (varn_start) {
1256
 
        varc_len = (u_char *) end - (src+idx);
1257
 
        final_var.data = (unsigned char *)varn_start;
1258
 
        final_var.len = varn_len;
1259
 
        final_data.data = src+idx;
1260
 
        final_data.len = varc_len;
1261
 
#ifdef post_heavy_debug
1262
 
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1263
 
                      "[POST] [%V]=[%V]",
1264
 
                      &final_var, &final_data);
1265
 
#endif
1266
 
        /* here we got val name + val content !*/             
1267
 
        if (cf->body_rules)
1268
 
          ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1269
 
                                     cf->body_rules, r, ctx, BODY);
1270
 
#ifdef post_heavy_debug
 
1254
          idx += (u_char *) end - (src+idx);
 
1255
        }
1271
1256
        else
1272
 
          /* here we got val name + val content !*/           
1273
 
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1274
 
                        "No local body rules ?!");
 
1257
          if (varn_start) {
 
1258
            varc_len = (u_char *) end - (src+idx);
 
1259
            final_var.data = (unsigned char *)varn_start;
 
1260
            final_var.len = varn_len;
 
1261
            final_data.data = src+idx;
 
1262
            final_data.len = varc_len;
 
1263
#ifdef post_heavy_debug
 
1264
            ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1265
                          "[POST] [%V]=[%V]",
 
1266
                          &final_var, &final_data);
 
1267
#endif
 
1268
            /* here we got val name + val content !*/         
 
1269
            if (cf->body_rules)
 
1270
              ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
 
1271
                                         cf->body_rules, r, ctx, BODY);
 
1272
#ifdef post_heavy_debug
 
1273
            else
 
1274
              /* here we got val name + val content !*/       
 
1275
              ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1276
                            "No local body rules ?!");
1275
1277
#endif
1276
1278
                
1277
 
        if (main_cf->body_rules)
1278
 
          ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1279
 
                                     main_cf->body_rules, r, ctx, BODY);
 
1279
            if (main_cf->body_rules)
 
1280
              ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
 
1281
                                         main_cf->body_rules, r, ctx, BODY);
1280
1282
#ifdef post_heavy_debug
1281
 
        else
1282
 
          /* here we got val name + val content !*/           
1283
 
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1284
 
                        "No main body rules ?!");
 
1283
            else
 
1284
              /* here we got val name + val content !*/       
 
1285
              ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1286
                            "No main body rules ?!");
1285
1287
#endif
1286
1288
              
1287
 
        idx += (u_char *) end - (src+idx);
1288
 
      }
1289
 
      else {
1290
 
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1291
 
                      "(multipart) : ");
1292
 
 
1293
 
      }
1294
 
    if (!ngx_strncmp(end, "\r\n", 2))
1295
 
      idx += 2;
1296
 
  }
1297
 
  ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1298
 
                "(multipart) : OVER");
1299
 
 
1300
 
}
1301
 
 
1302
 
  //#define dummy_body_parse_debug
1303
 
 
1304
 
void    
1305
 
ngx_http_dummy_body_parse(ngx_http_request_ctx_t *ctx, 
1306
 
                          ngx_http_request_t     *r,
1307
 
                          ngx_http_dummy_loc_conf_t *cf,
1308
 
                          ngx_http_dummy_main_conf_t *main_cf)
1309
 
{
1310
 
  u_char                        *src; 
1311
 
  ngx_str_t                     tmp;
1312
 
  ngx_chain_t                   *bb;
1313
 
  u_char                        *full_body;
1314
 
  u_int                         full_body_len;
1315
 
  
1316
 
  
1317
 
#ifdef dummy_body_parse_debug
1318
 
  ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1319
 
                "XX-BODY PARSE");
1320
 
#endif
1321
 
  if (!r->request_body->bufs || !r->headers_in.content_type) {
1322
 
#ifdef dummy_body_parse_debug
1323
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1324
 
                  "XX-No content type ..");
1325
 
#endif
1326
 
    if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1327
 
      ctx->weird_request = 1;
1328
 
    return ;
1329
 
  }
1330
 
 
1331
 
  if (r->request_body->temp_file) {
1332
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1333
 
                  "naxsi: POST REQUEST to temp_file, partially parsed.");
1334
 
    if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__big_request, NULL, BODY, 0) == 0)
1335
 
      ctx->big_request = 1;
1336
 
    return ;
1337
 
  }
1338
 
 
1339
 
#ifdef dummy_body_parse_debug
1340
 
  ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1341
 
                "XX-VALID BODY");
1342
 
#endif
1343
 
  /* request body in single buffer */
1344
 
  if (r->request_body->bufs->next == NULL) {
1345
 
    full_body_len = (u_int) (r->request_body->bufs->buf->last - 
1346
 
                             r->request_body->bufs->buf->pos);
1347
 
    full_body =  ngx_pcalloc(r->pool, (u_int) (full_body_len+1));
1348
 
    memcpy(full_body, r->request_body->bufs->buf->pos, full_body_len);
1349
 
  }
1350
 
  /* request body in chain */
1351
 
  else {
1352
 
#ifdef dummy_body_parse_debug
1353
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1354
 
                  "[POST] REQUEST BODY IN CHAIN !");
1355
 
#endif
1356
 
    for (full_body_len = 0, bb = r->request_body->bufs; bb; bb = bb->next)
1357
 
      full_body_len += (bb->buf->last - bb->buf->pos);
1358
 
    full_body = ngx_pcalloc(r->pool, full_body_len+1);
1359
 
    src = full_body;
1360
 
    if (!full_body) 
1361
 
      return ;
1362
 
    for(bb = r->request_body->bufs ; bb ; bb = bb->next)
1363
 
      full_body = ngx_cpymem(full_body, bb->buf->pos, 
1364
 
                             bb->buf->last - bb->buf->pos);
1365
 
    full_body = src;
1366
 
#ifdef dummy_body_parse_debug
1367
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1368
 
                  "[POST] REQUEST BODY IN CHAIN [%s] (len=%d)", 
1369
 
                  full_body, full_body_len);
1370
 
#endif
1371
 
  }
1372
 
#ifdef dummy_body_parse_debug
1373
 
  ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1374
 
                "content-len header (%d) mismatch actual len (%d) ??", 
1375
 
                r->headers_in.content_length_n, full_body_len);
1376
 
#endif
1377
 
  /* File probably got buffered. */
1378
 
  if (r->headers_in.content_length_n != full_body_len) {
1379
 
    if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1380
 
      ctx->weird_request = 1;
1381
 
    return ;
1382
 
  }
1383
 
  /* x-www-form-urlencoded POSTs */
1384
 
  //33 = echo -n "application/x-www-form-urlencoded" | wc -c
1385
 
  if (!ngx_strncasecmp(r->headers_in.content_type->value.data, 
1386
 
                       (u_char *)"application/x-www-form-urlencoded", 33)) {
1387
 
#ifdef post_heavy_debug
1388
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1389
 
                  "XX-application/x-www..");
1390
 
#endif
1391
 
    tmp.len = full_body_len;
1392
 
    tmp.data = full_body;
1393
 
 
1394
 
#ifdef post_heavy_debug
1395
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1396
 
                  "XX-POST DATA [%V]", &tmp);
1397
 
#endif
1398
 
    if(ngx_http_spliturl_ruleset(r->pool, (char *)tmp.data, 
1399
 
                                 cf->body_rules, main_cf->body_rules, 
1400
 
                                 r, ctx, BODY)) {
1401
 
#ifdef post_heavy_debug
1402
 
      dummy_error_fatal(ctx, r, "spliturl failed, someone is trying to trick us");
1403
 
#endif
1404
 
      if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1405
 
        ctx->weird_request = 1;
1406
 
      return ;
1407
 
    }
1408
 
  }
1409
 
  //19 = echo -n "multipart/form-data" | wc -c
1410
 
  else if (!ngx_strncasecmp(r->headers_in.content_type->value.data, 
1411
 
                            (u_char *) "multipart/form-data", 19)) {
1412
 
    ngx_http_dummy_multipart_parse(ctx, r, full_body, full_body_len);
1413
 
  }
1414
 
  else {
1415
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
1416
 
                  "[POST] Unknown content-type, gtfo");
1417
 
    if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1418
 
      ctx->weird_request = 1;
1419
 
  }
1420
 
}
1421
 
 
1422
 
 
1423
 
 
1424
 
  /*
1425
 
  ** does : bui ! this is a 'main' function, all the stuff goes from here.
1426
 
  **      to make it short, it does the following :
1427
 
  ** - if we got header rules, apply header_rules on each.
1428
 
  ** - apply generic_rules on url decoded URI.
1429
 
  ** - if we got get_rules and get args, apply get_rules varname/value couple.
1430
 
  ** - if we are in a POST/PUT request and we got body_rules, apply rules :)
1431
 
  */
1432
 
void    
1433
 
ngx_http_dummy_uri_parse(ngx_http_dummy_main_conf_t *main_cf, 
1434
 
                         ngx_http_dummy_loc_conf_t *cf, 
1435
 
                         ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1436
 
{
1437
 
  ngx_str_t                     tmp, name;
1438
 
  
1439
 
  if (!r->uri.len)
1440
 
    return ;
1441
 
  if (ctx->block && !cf->learning)
1442
 
    return ;
1443
 
  if (!main_cf->generic_rules && !cf->generic_rules) {
1444
 
    dummy_error_fatal(ctx, r, "no generic rules ?!");
1445
 
    return ;
1446
 
  }
1447
 
  tmp.len = r->uri.len;
1448
 
  tmp.data = ngx_pcalloc(r->pool, r->uri.len+1);
1449
 
  if (!tmp.data) {
1450
 
    dummy_error_fatal(ctx, r, "failed alloc of %d", r->uri.len+1);
1451
 
    return ;
1452
 
  }
1453
 
  memcpy(tmp.data, r->uri.data, r->uri.len);
1454
 
  name.data = NULL;
1455
 
  name.len = 0;
1456
 
  if (cf->generic_rules)
1457
 
    ngx_http_basestr_ruleset_n(r->pool, &name, &tmp, cf->generic_rules, 
1458
 
                               r, ctx, URL);
1459
 
  if (main_cf->generic_rules)
1460
 
    ngx_http_basestr_ruleset_n(r->pool, &name, &tmp, main_cf->generic_rules, 
1461
 
                               r, ctx, URL);
1462
 
  ngx_pfree(r->pool, tmp.data);
1463
 
}
1464
 
 
1465
 
void    
1466
 
ngx_http_dummy_args_parse(ngx_http_dummy_main_conf_t *main_cf, 
1467
 
                          ngx_http_dummy_loc_conf_t *cf, 
1468
 
                          ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1469
 
{
1470
 
  ngx_str_t                     tmp;
1471
 
  
1472
 
  if (ctx->block && !cf->learning)
1473
 
    return ;
1474
 
  if (!r->args.len)
1475
 
    return ;
1476
 
  if (!cf->get_rules && !main_cf->get_rules)
1477
 
    return ;
1478
 
  tmp.len = r->args.len;
1479
 
  tmp.data = ngx_pcalloc(r->pool, r->args.len+1);
1480
 
  if (!tmp.data) {
1481
 
    dummy_error_fatal(ctx, r, "failed alloc");
1482
 
    return ;
1483
 
  }
1484
 
  memcpy(tmp.data, r->args.data, r->args.len);
1485
 
  if(ngx_http_spliturl_ruleset(r->pool, (char *)tmp.data, 
1486
 
                               cf->get_rules, main_cf->get_rules, r, 
1487
 
                               ctx, ARGS)) {
1488
 
    dummy_error_fatal(ctx, r, 
1489
 
                      "spliturl error : malformed url, possible attack");
1490
 
    return ;
1491
 
  }
1492
 
  ngx_pfree(r->pool, tmp.data);
1493
 
}
1494
 
 
1495
 
void    
1496
 
ngx_http_dummy_headers_parse(ngx_http_dummy_main_conf_t *main_cf, 
1497
 
                             ngx_http_dummy_loc_conf_t *cf, 
1498
 
                             ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1499
 
{
1500
 
  ngx_list_part_t           *part;
1501
 
  ngx_table_elt_t           *h;
1502
 
  unsigned int               i;
1503
 
 
1504
 
  if (!cf->header_rules && !main_cf->header_rules)
1505
 
    return ;
1506
 
  // this check may be removed, as it shouldn't be needed anymore !
1507
 
  if (ctx->block && !cf->learning)
1508
 
    return ;
1509
 
  part = &r->headers_in.headers.part;
1510
 
  h = part->elts;
1511
 
  // this check may be removed, as it shouldn't be needed anymore !
1512
 
  for (i = 0; !ctx->block ; i++) {
1513
 
    if (i >= part->nelts) {
1514
 
      if (part->next == NULL) 
1515
 
        break;
1516
 
      part = part->next;
 
1289
            idx += (u_char *) end - (src+idx);
 
1290
          }
 
1291
          else {
 
1292
            ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1293
                          "(multipart) : ");
 
1294
 
 
1295
          }
 
1296
        if (!ngx_strncmp(end, "\r\n", 2))
 
1297
          idx += 2;
 
1298
      }
 
1299
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1300
                    "(multipart) : OVER");
 
1301
 
 
1302
    }
 
1303
 
 
1304
    //#define dummy_body_parse_debug
 
1305
 
 
1306
    void        
 
1307
      ngx_http_dummy_body_parse(ngx_http_request_ctx_t *ctx, 
 
1308
                                ngx_http_request_t       *r,
 
1309
                                ngx_http_dummy_loc_conf_t *cf,
 
1310
                                ngx_http_dummy_main_conf_t *main_cf)
 
1311
    {
 
1312
      u_char                    *src; 
 
1313
      ngx_str_t                 tmp;
 
1314
      ngx_chain_t                       *bb;
 
1315
      u_char                    *full_body;
 
1316
      u_int                             full_body_len;
 
1317
  
 
1318
  
 
1319
#ifdef dummy_body_parse_debug
 
1320
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1321
                    "XX-BODY PARSE");
 
1322
#endif
 
1323
      if (!r->request_body->bufs || !r->headers_in.content_type) {
 
1324
#ifdef dummy_body_parse_debug
 
1325
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1326
                      "XX-No content type ..");
 
1327
#endif
 
1328
        if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
 
1329
          ctx->weird_request = 1;
 
1330
        return ;
 
1331
      }
 
1332
 
 
1333
      if (r->request_body->temp_file) {
 
1334
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1335
                      "naxsi: POST REQUEST to temp_file, partially parsed.");
 
1336
        if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__big_request, NULL, BODY, 0) == 0)
 
1337
          ctx->big_request = 1;
 
1338
        return ;
 
1339
      }
 
1340
 
 
1341
#ifdef dummy_body_parse_debug
 
1342
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1343
                    "XX-VALID BODY");
 
1344
#endif
 
1345
      /* request body in single buffer */
 
1346
      if (r->request_body->bufs->next == NULL) {
 
1347
        full_body_len = (u_int) (r->request_body->bufs->buf->last - 
 
1348
                                 r->request_body->bufs->buf->pos);
 
1349
        full_body =  ngx_pcalloc(r->pool, (u_int) (full_body_len+1));
 
1350
        memcpy(full_body, r->request_body->bufs->buf->pos, full_body_len);
 
1351
      }
 
1352
      /* request body in chain */
 
1353
      else {
 
1354
#ifdef dummy_body_parse_debug
 
1355
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1356
                      "[POST] REQUEST BODY IN CHAIN !");
 
1357
#endif
 
1358
        for (full_body_len = 0, bb = r->request_body->bufs; bb; bb = bb->next)
 
1359
          full_body_len += (bb->buf->last - bb->buf->pos);
 
1360
        full_body = ngx_pcalloc(r->pool, full_body_len+1);
 
1361
        src = full_body;
 
1362
        if (!full_body) 
 
1363
          return ;
 
1364
        for(bb = r->request_body->bufs ; bb ; bb = bb->next)
 
1365
          full_body = ngx_cpymem(full_body, bb->buf->pos, 
 
1366
                                 bb->buf->last - bb->buf->pos);
 
1367
        full_body = src;
 
1368
#ifdef dummy_body_parse_debug
 
1369
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1370
                      "[POST] REQUEST BODY IN CHAIN [%s] (len=%d)", 
 
1371
                      full_body, full_body_len);
 
1372
#endif
 
1373
      }
 
1374
#ifdef dummy_body_parse_debug
 
1375
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1376
                    "content-len header (%d) mismatch actual len (%d) ??", 
 
1377
                    r->headers_in.content_length_n, full_body_len);
 
1378
#endif
 
1379
      /* File probably got buffered. */
 
1380
      if (r->headers_in.content_length_n != full_body_len) {
 
1381
        if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
 
1382
          ctx->weird_request = 1;
 
1383
        return ;
 
1384
      }
 
1385
      /* x-www-form-urlencoded POSTs */
 
1386
      //33 = echo -n "application/x-www-form-urlencoded" | wc -c
 
1387
      if (!ngx_strncasecmp(r->headers_in.content_type->value.data, 
 
1388
                           (u_char *)"application/x-www-form-urlencoded", 33)) {
 
1389
#ifdef post_heavy_debug
 
1390
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1391
                      "XX-application/x-www..");
 
1392
#endif
 
1393
        tmp.len = full_body_len;
 
1394
        tmp.data = full_body;
 
1395
 
 
1396
#ifdef post_heavy_debug
 
1397
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1398
                      "XX-POST DATA [%V]", &tmp);
 
1399
#endif
 
1400
        if(ngx_http_spliturl_ruleset(r->pool, (char *)tmp.data, 
 
1401
                                     cf->body_rules, main_cf->body_rules, 
 
1402
                                     r, ctx, BODY)) {
 
1403
#ifdef post_heavy_debug
 
1404
          dummy_error_fatal(ctx, r, "spliturl failed, someone is trying to trick us");
 
1405
#endif
 
1406
          if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
 
1407
            ctx->weird_request = 1;
 
1408
          return ;
 
1409
        }
 
1410
      }
 
1411
      //19 = echo -n "multipart/form-data" | wc -c
 
1412
      else if (!ngx_strncasecmp(r->headers_in.content_type->value.data, 
 
1413
                                (u_char *) "multipart/form-data", 19)) {
 
1414
        ngx_http_dummy_multipart_parse(ctx, r, full_body, full_body_len);
 
1415
      }
 
1416
      else {
 
1417
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
 
1418
                      "[POST] Unknown content-type, gtfo");
 
1419
        if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
 
1420
          ctx->weird_request = 1;
 
1421
      }
 
1422
    }
 
1423
 
 
1424
 
 
1425
 
 
1426
    /*
 
1427
    ** does : bui ! this is a 'main' function, all the stuff goes from here.
 
1428
    **    to make it short, it does the following :
 
1429
    ** - if we got header rules, apply header_rules on each.
 
1430
    ** - apply generic_rules on url decoded URI.
 
1431
    ** - if we got get_rules and get args, apply get_rules varname/value couple.
 
1432
    ** - if we are in a POST/PUT request and we got body_rules, apply rules :)
 
1433
    */
 
1434
    void        
 
1435
      ngx_http_dummy_uri_parse(ngx_http_dummy_main_conf_t *main_cf, 
 
1436
                               ngx_http_dummy_loc_conf_t *cf, 
 
1437
                               ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
 
1438
    {
 
1439
      ngx_str_t                 tmp, name;
 
1440
  
 
1441
      if (!r->uri.len)
 
1442
        return ;
 
1443
      if (ctx->block && !cf->learning)
 
1444
        return ;
 
1445
      if (!main_cf->generic_rules && !cf->generic_rules) {
 
1446
        dummy_error_fatal(ctx, r, "no generic rules ?!");
 
1447
        return ;
 
1448
      }
 
1449
      tmp.len = r->uri.len;
 
1450
      tmp.data = ngx_pcalloc(r->pool, r->uri.len+1);
 
1451
      if (!tmp.data) {
 
1452
        dummy_error_fatal(ctx, r, "failed alloc of %d", r->uri.len+1);
 
1453
        return ;
 
1454
      }
 
1455
      memcpy(tmp.data, r->uri.data, r->uri.len);
 
1456
      name.data = NULL;
 
1457
      name.len = 0;
 
1458
      if (cf->generic_rules)
 
1459
        ngx_http_basestr_ruleset_n(r->pool, &name, &tmp, cf->generic_rules, 
 
1460
                                   r, ctx, URL);
 
1461
      if (main_cf->generic_rules)
 
1462
        ngx_http_basestr_ruleset_n(r->pool, &name, &tmp, main_cf->generic_rules, 
 
1463
                                   r, ctx, URL);
 
1464
      ngx_pfree(r->pool, tmp.data);
 
1465
    }
 
1466
 
 
1467
    void        
 
1468
      ngx_http_dummy_args_parse(ngx_http_dummy_main_conf_t *main_cf, 
 
1469
                                ngx_http_dummy_loc_conf_t *cf, 
 
1470
                                ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
 
1471
    {
 
1472
      ngx_str_t                 tmp;
 
1473
  
 
1474
      if (ctx->block && !cf->learning)
 
1475
        return ;
 
1476
      if (!r->args.len)
 
1477
        return ;
 
1478
      if (!cf->get_rules && !main_cf->get_rules)
 
1479
        return ;
 
1480
      tmp.len = r->args.len;
 
1481
      tmp.data = ngx_pcalloc(r->pool, r->args.len+1);
 
1482
      if (!tmp.data) {
 
1483
        dummy_error_fatal(ctx, r, "failed alloc");
 
1484
        return ;
 
1485
      }
 
1486
      memcpy(tmp.data, r->args.data, r->args.len);
 
1487
      if(ngx_http_spliturl_ruleset(r->pool, (char *)tmp.data, 
 
1488
                                   cf->get_rules, main_cf->get_rules, r, 
 
1489
                                   ctx, ARGS)) {
 
1490
        dummy_error_fatal(ctx, r, 
 
1491
                          "spliturl error : malformed url, possible attack");
 
1492
        return ;
 
1493
      }
 
1494
      ngx_pfree(r->pool, tmp.data);
 
1495
    }
 
1496
 
 
1497
    void        
 
1498
      ngx_http_dummy_headers_parse(ngx_http_dummy_main_conf_t *main_cf, 
 
1499
                                   ngx_http_dummy_loc_conf_t *cf, 
 
1500
                                   ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
 
1501
    {
 
1502
      ngx_list_part_t       *part;
 
1503
      ngx_table_elt_t       *h;
 
1504
      unsigned int                   i;
 
1505
 
 
1506
      if (!cf->header_rules && !main_cf->header_rules)
 
1507
        return ;
 
1508
      // this check may be removed, as it shouldn't be needed anymore !
 
1509
      if (ctx->block && !cf->learning)
 
1510
        return ;
 
1511
      part = &r->headers_in.headers.part;
1517
1512
      h = part->elts;
1518
 
      i = 0;
1519
 
    }
1520
 
    if (cf->header_rules)
1521
 
      ngx_http_basestr_ruleset_n(r->pool, &(h[i].key), &(h[i].value), 
1522
 
                                 cf->header_rules, r, ctx, HEADERS);
1523
 
    if (main_cf->header_rules)
1524
 
      ngx_http_basestr_ruleset_n(r->pool, &(h[i].key), &(h[i].value), 
1525
 
                                 main_cf->header_rules, r, ctx, HEADERS);
1526
 
  }
1527
 
  return ;
1528
 
}
1529
 
 
1530
 
void    
1531
 
ngx_http_dummy_data_parse(ngx_http_request_ctx_t *ctx, 
1532
 
                          ngx_http_request_t     *r)
1533
 
{
1534
 
  ngx_http_dummy_loc_conf_t     *cf;
1535
 
  ngx_http_dummy_main_conf_t    *main_cf;
1536
 
  ngx_http_core_main_conf_t  *cmcf;
1537
 
 
1538
 
  cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module);
1539
 
  cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
1540
 
  main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module);
1541
 
  if (!cf || !ctx || !cmcf) {
1542
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1543
 
                  "XX-UNABLE TO PARSE IN DATA PARSE !!");
1544
 
    return ;
1545
 
  }
1546
 
  /* process rules only if request is not already blocked or if
1547
 
     the learning mode is enabled */
1548
 
  ngx_http_dummy_headers_parse(main_cf, cf, ctx, r);
1549
 
  //check uri
1550
 
  ngx_http_dummy_uri_parse(main_cf, cf, ctx, r);
1551
 
  //check args
1552
 
  ngx_http_dummy_args_parse(main_cf, cf, ctx, r);
1553
 
  // check method
1554
 
  if ((r->method == NGX_HTTP_POST || r->method == NGX_HTTP_PUT) && 
1555
 
      //presence of body rules (POST/PUT rules)
1556
 
      (cf->body_rules || main_cf->body_rules) && 
1557
 
      //and the presence of data to parse
1558
 
      r->request_body && (!ctx->block || cf->learning)) 
1559
 
    ngx_http_dummy_body_parse(ctx, r, cf, main_cf);
1560
 
  ngx_http_dummy_update_current_ctx_status(ctx, cf, r);
1561
 
}
1562
 
 
1563
 
 
1564
 
 
1565
 
  //#define custom_score_debug
1566
 
  void  
1567
 
    ngx_http_dummy_update_current_ctx_status(ngx_http_request_ctx_t     *ctx, 
1568
 
                                             ngx_http_dummy_loc_conf_t  *cf, 
1569
 
                                             ngx_http_request_t *r)
1570
 
  {
1571
 
    unsigned int        i, z, matched;
1572
 
    ngx_http_check_rule_t               *cr;
1573
 
    ngx_http_special_score_t    *sc;
1574
 
    /* ngx_http_whitelist_rule_t        *b; */
1575
 
    /* //ngx_http_whitelist_location_t  *cl; */
1576
 
    /* ngx_int_t                        k; */
1577
 
    //ngx_int_t                 *tmp_ptr;
1578
 
 
1579
 
#ifdef custom_score_debug
1580
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1581
 
                  "XX-custom check rules");
1582
 
#endif
1583
 
    /*   /\* check flags : as current_ctx_status updates status regarding flags (weird_request, big_body etc.) we need  */
1584
 
    /*      to check first if those flags are whitelisted for this URL. *\/ */
1585
 
    /*   if (cf->wlr_url_hash && cf->wlr_url_hash->size) { */
1586
 
    /*     /\* check if the rule was not whitelisted *\/   */
1587
 
    /*     k = ngx_hash_key_lc(r->uri.data, r->uri.len); */
1588
 
    /*     b = (ngx_http_whitelist_rule_t*) ngx_hash_find(cf->wlr_url_hash, k,  */
1589
 
    /*                                             (u_char*) r->uri.data,  */
1590
 
    /*                                             r->uri.len); */
1591
 
    /*     if (b) { */
1592
 
    /* #ifdef custom_score_debug */
1593
 
    /*       ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, */
1594
 
    /*              "XX-URL has whitelist, %d items", b->whitelist_locations->nelts); */
1595
 
    /* #endif */
1596
 
    /*       for (i = 0; i < b->ids->nelts; i++) { */
1597
 
        
1598
 
    /*  if (ctx->weird_request && */
1599
 
    /*      ((int *)b->ids->elts)[i] == WEIRD_REQUEST_INTERNAL_RULE_ID) { */
1600
 
    /* #ifdef custom_score_debug */
1601
 
    /*    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, */
1602
 
    /*                  "XX-MATCH WHITELIST !"); */
1603
 
    /* #endif */
1604
 
    /*    ctx->weird_request = 0; */
1605
 
    /*  } */
1606
 
    /*  if (ctx->big_request && */
1607
 
    /*      ((int *)b->ids->elts)[i] == BIG_BODY_INTERNAL_RULE_ID) { */
1608
 
    /* #ifdef custom_score_debug */
1609
 
    /*    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, */
1610
 
    /*                  "XX-MATCH WHITELIST !"); */
1611
 
    /* #endif */
1612
 
    /*    ctx->big_request = 0; */
1613
 
    /*  } */
1614
 
    /*       } */
1615
 
    /*     } */
1616
 
    /*   } */
1617
 
    if (ctx->weird_request) {
1618
 
#ifdef custom_score_debug
1619
 
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1620
 
                    "XX-blocking, weird_request flag set");
1621
 
#endif
1622
 
      ctx->block = 1;
1623
 
    }
1624
 
    if (ctx->big_request) {
1625
 
#ifdef custom_score_debug
1626
 
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1627
 
                    "XX-blocking unexpected big request");
1628
 
#endif
1629
 
      ctx->block = 1;
1630
 
    }
1631
 
    /*cr, sc, cf, ctx*/
1632
 
    if (cf->check_rules && ctx->special_scores) {
1633
 
#ifdef custom_score_debug
1634
 
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1635
 
                    "XX-we have custom check rules and CTX got special score :)");
1636
 
#endif
1637
 
      cr = cf->check_rules->elts;
1638
 
      sc = ctx->special_scores->elts;
1639
 
      for (z = 0; z < ctx->special_scores->nelts; z++)
1640
 
        for (i = 0; i < cf->check_rules->nelts; i++) {
1641
 
#ifdef custom_score_debug
1642
 
          ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1643
 
                        "XX- rule says :(%s:%d) vs current context:(%s:%d) (flag=%d)",
1644
 
                        cr[i].sc_tag.data, cr[i].sc_score,
1645
 
                        sc[z].sc_tag->data, sc[z].sc_score, cr[i].cmp);
1646
 
#endif
1647
 
          if (!ngx_strcmp(sc[z].sc_tag->data, cr[i].sc_tag.data)) {
 
1513
      // this check may be removed, as it shouldn't be needed anymore !
 
1514
      for (i = 0; !ctx->block ; i++) {
 
1515
        if (i >= part->nelts) {
 
1516
          if (part->next == NULL) 
 
1517
            break;
 
1518
          part = part->next;
 
1519
          h = part->elts;
 
1520
          i = 0;
 
1521
        }
 
1522
        if (cf->header_rules)
 
1523
          ngx_http_basestr_ruleset_n(r->pool, &(h[i].key), &(h[i].value), 
 
1524
                                     cf->header_rules, r, ctx, HEADERS);
 
1525
        if (main_cf->header_rules)
 
1526
          ngx_http_basestr_ruleset_n(r->pool, &(h[i].key), &(h[i].value), 
 
1527
                                     main_cf->header_rules, r, ctx, HEADERS);
 
1528
      }
 
1529
      return ;
 
1530
    }
 
1531
 
 
1532
    void        
 
1533
      ngx_http_dummy_data_parse(ngx_http_request_ctx_t *ctx, 
 
1534
                                ngx_http_request_t       *r)
 
1535
    {
 
1536
      ngx_http_dummy_loc_conf_t *cf;
 
1537
      ngx_http_dummy_main_conf_t        *main_cf;
 
1538
      ngx_http_core_main_conf_t  *cmcf;
 
1539
 
 
1540
      cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module);
 
1541
      cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
 
1542
      main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module);
 
1543
      if (!cf || !ctx || !cmcf) {
 
1544
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
1545
                      "XX-UNABLE TO PARSE IN DATA PARSE !!");
 
1546
        return ;
 
1547
      }
 
1548
      /* process rules only if request is not already blocked or if
 
1549
         the learning mode is enabled */
 
1550
      ngx_http_dummy_headers_parse(main_cf, cf, ctx, r);
 
1551
      //check uri
 
1552
      ngx_http_dummy_uri_parse(main_cf, cf, ctx, r);
 
1553
      //check args
 
1554
      ngx_http_dummy_args_parse(main_cf, cf, ctx, r);
 
1555
      // check method
 
1556
      if ((r->method == NGX_HTTP_POST || r->method == NGX_HTTP_PUT) && 
 
1557
          //presence of body rules (POST/PUT rules)
 
1558
          (cf->body_rules || main_cf->body_rules) && 
 
1559
          //and the presence of data to parse
 
1560
          r->request_body && (!ctx->block || cf->learning)) 
 
1561
        ngx_http_dummy_body_parse(ctx, r, cf, main_cf);
 
1562
      ngx_http_dummy_update_current_ctx_status(ctx, cf, r);
 
1563
    }
 
1564
 
 
1565
 
 
1566
 
 
1567
    //#define custom_score_debug
 
1568
    void        
 
1569
      ngx_http_dummy_update_current_ctx_status(ngx_http_request_ctx_t   *ctx, 
 
1570
                                               ngx_http_dummy_loc_conf_t        *cf, 
 
1571
                                               ngx_http_request_t *r)
 
1572
    {
 
1573
      unsigned int      i, z, matched;
 
1574
      ngx_http_check_rule_t             *cr;
 
1575
      ngx_http_special_score_t  *sc;
 
1576
      /* ngx_http_whitelist_rule_t      *b; */
 
1577
      /* //ngx_http_whitelist_location_t        *cl; */
 
1578
      /* ngx_int_t                      k; */
 
1579
      //ngx_int_t                       *tmp_ptr;
 
1580
 
 
1581
#ifdef custom_score_debug
 
1582
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
1583
                    "XX-custom check rules");
 
1584
#endif
 
1585
      if (ctx->weird_request) {
 
1586
#ifdef custom_score_debug
 
1587
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
1588
                      "XX-blocking, weird_request flag set");
 
1589
#endif
 
1590
        ctx->block = 1;
 
1591
      }
 
1592
      if (ctx->big_request) {
 
1593
#ifdef custom_score_debug
 
1594
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
1595
                      "XX-blocking unexpected big request");
 
1596
#endif
 
1597
        ctx->block = 1;
 
1598
      }
 
1599
      /*cr, sc, cf, ctx*/
 
1600
      if (cf->check_rules && ctx->special_scores) {
 
1601
#ifdef custom_score_debug
 
1602
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
1603
                      "XX-we have custom check rules and CTX got special score :)");
 
1604
#endif
 
1605
        cr = cf->check_rules->elts;
 
1606
        sc = ctx->special_scores->elts;
 
1607
        for (z = 0; z < ctx->special_scores->nelts; z++)
 
1608
          for (i = 0; i < cf->check_rules->nelts; i++) {
1648
1609
#ifdef custom_score_debug
1649
1610
            ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1650
1611
                          "XX- rule says :(%s:%d) vs current context:(%s:%d) (flag=%d)",
1651
1612
                          cr[i].sc_tag.data, cr[i].sc_score,
1652
1613
                          sc[z].sc_tag->data, sc[z].sc_score, cr[i].cmp);
1653
1614
#endif
1654
 
            matched=0;
1655
 
            // huglier than your mom :)
1656
 
            switch (cr[i].cmp) {
1657
 
            case SUP:
1658
 
              matched = sc[z].sc_score > cr[i].sc_score ? 1 : 0;
1659
 
              break;
1660
 
            case SUP_OR_EQUAL:
1661
 
              matched = sc[z].sc_score >= cr[i].sc_score ? 1 : 0;
1662
 
              break;
1663
 
            case INF:
1664
 
              matched = sc[z].sc_score < cr[i].sc_score ? 1 : 0;
1665
 
              break;
1666
 
            case INF_OR_EQUAL:
1667
 
              matched = sc[z].sc_score <= cr[i].sc_score ? 1 : 0;
1668
 
              break;
1669
 
            }
1670
 
            if (matched) {
 
1615
            if (!ngx_strcmp(sc[z].sc_tag->data, cr[i].sc_tag.data)) {
1671
1616
#ifdef custom_score_debug
1672
1617
              ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1673
 
                            "XX- custom score rule triggered ..");
 
1618
                            "XX- rule says :(%s:%d) vs current context:(%s:%d) (flag=%d)",
 
1619
                            cr[i].sc_tag.data, cr[i].sc_score,
 
1620
                            sc[z].sc_tag->data, sc[z].sc_score, cr[i].cmp);
 
1621
#endif
 
1622
              matched=0;
 
1623
              // huglier than your mom :)
 
1624
              switch (cr[i].cmp) {
 
1625
              case SUP:
 
1626
                matched = sc[z].sc_score > cr[i].sc_score ? 1 : 0;
 
1627
                break;
 
1628
              case SUP_OR_EQUAL:
 
1629
                matched = sc[z].sc_score >= cr[i].sc_score ? 1 : 0;
 
1630
                break;
 
1631
              case INF:
 
1632
                matched = sc[z].sc_score < cr[i].sc_score ? 1 : 0;
 
1633
                break;
 
1634
              case INF_OR_EQUAL:
 
1635
                matched = sc[z].sc_score <= cr[i].sc_score ? 1 : 0;
 
1636
                break;
 
1637
              }
 
1638
              if (matched) {
 
1639
#ifdef custom_score_debug
 
1640
                ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
1641
                              "XX- custom score rule triggered ..");
1674
1642
#endif
1675
1643
 
1676
 
              if (cr[i].block)
1677
 
                ctx->block = 1;
1678
 
              if (cr[i].allow)
1679
 
                ctx->allow = 1;
 
1644
                if (cr[i].block)
 
1645
                  ctx->block = 1;
 
1646
                if (cr[i].allow)
 
1647
                  ctx->allow = 1;
 
1648
              }
1680
1649
            }
1681
1650
          }
1682
 
        }
 
1651
      }
1683
1652
    }
1684
 
  }
1685
 
 
1686
 
 
1687
 
  /*
1688
 
  ** This function is called when the body is read.
1689
 
  ** Will set-up flags to tell that parsing can be done,
1690
 
  ** and then run the core phases again
1691
 
  ** (WARNING: check backward compatibility of count--
1692
 
  ** with older version of nginx 0.7.x)
1693
 
  */
1694
 
//#define payload_handler_debug
1695
 
  void 
1696
 
    ngx_http_dummy_payload_handler(ngx_http_request_t *r) {
1697
 
    ngx_http_request_ctx_t  *ctx;
1698
 
    ctx = ngx_http_get_module_ctx(r, ngx_http_naxsi_module);
1699
 
    ctx->ready = 1;
1700
 
    r->count--;
1701
 
#ifdef payload_handler_debug
1702
 
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1703
 
                  "XX-dummy PAYLOAD HANDLER !");
1704
 
#endif
1705
 
    if (ctx->wait_for_body) {
 
1653
 
 
1654
 
 
1655
    /*
 
1656
    ** This function is called when the body is read.
 
1657
    ** Will set-up flags to tell that parsing can be done,
 
1658
    ** and then run the core phases again
 
1659
    ** (WARNING: check backward compatibility of count--
 
1660
    ** with older version of nginx 0.7.x)
 
1661
    */
 
1662
    //#define payload_handler_debug
 
1663
    void 
 
1664
      ngx_http_dummy_payload_handler(ngx_http_request_t *r) {
 
1665
      ngx_http_request_ctx_t  *ctx;
 
1666
      ctx = ngx_http_get_module_ctx(r, ngx_http_naxsi_module);
 
1667
      ctx->ready = 1;
 
1668
      r->count--;
1706
1669
#ifdef payload_handler_debug
1707
1670
      ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1708
 
                    "XX-dummy : AFTER NGX_AGAIN");
1709
 
#endif
1710
 
      ctx->wait_for_body = 0;
1711
 
      ngx_http_core_run_phases(r);
 
1671
                    "XX-dummy PAYLOAD HANDLER !");
 
1672
#endif
 
1673
      if (ctx->wait_for_body) {
 
1674
#ifdef payload_handler_debug
 
1675
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
1676
                      "XX-dummy : AFTER NGX_AGAIN");
 
1677
#endif
 
1678
        ctx->wait_for_body = 0;
 
1679
        ngx_http_core_run_phases(r);
 
1680
      }
1712
1681
    }
1713
 
  }
1714
1682