Browse code

bb4007 - adding pcre byte sequence comparison functions

Mickey Sola authored on 2018/08/16 06:04:25
Showing 4 changed files
... ...
@@ -37,6 +37,7 @@
37 37
 #include "mpool.h"
38 38
 #include "readdb.h"
39 39
 #include "regex_pcre.h"
40
+#include "str.h"
40 41
 
41 42
 #if HAVE_PCRE
42 43
 #if USING_PCRE2
... ...
@@ -325,7 +326,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *virname, const char *
325 325
             case 'g':  pm->flags |= CLI_PCRE_GLOBAL;            break;
326 326
             case 'r':  pm->flags |= CLI_PCRE_ROLLING;           break;
327 327
             case 'e':  pm->flags |= CLI_PCRE_ENCOMPASS;         break;
328
-            case 'z':  if(CL_SUCCESS == cli_pcre_addbytecomp(&opt, &pm->bcmp_data)) {
328
+            case 'z':  if(CL_SUCCESS == cli_pcre_bcmp_add_opts(&opt, &pm->bcmp_data)) {
329 329
                            pm->flags |= CLI_PCRE_BCOMP;
330 330
                            break;
331 331
                        }
... ...
@@ -409,7 +410,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *virname, const char *
409 409
     return CL_SUCCESS;
410 410
 }
411 411
 
412
-int cli_pcre_addbytecomp (const char **opt, struct cli_pcre_bcomp *bcomp) {
412
+int cli_pcre_bcmp_add_opts(const char **opt, struct cli_pcre_bcomp *bcomp) {
413 413
 
414 414
     if (!opt || !(*opt) || !bcomp)
415 415
         return CL_ENULLARG;
... ...
@@ -889,6 +890,14 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
889 889
             /* move off to the end of the match for next match; offset is relative to adjbuffer
890 890
              * NOTE: misses matches starting within the last match; TODO: start from start of last match? */
891 891
             offset = p_res.match[1];
892
+            
893
+            if(pm->flags & CLI_PCRE_BCOMP) {
894
+                ret = cli_pcre_bcmp_compare_check(buffer, length, offset, pm);
895
+                if (ret != CL_SUCCESS) {
896
+                    break;
897
+                }
898
+            }
899
+
892 900
         } while (global && rc > 0 && offset < adjlength);
893 901
 
894 902
         /* handle error code */
... ...
@@ -899,11 +908,6 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
899 899
         if (ret != CL_SUCCESS)
900 900
             break;
901 901
     }
902
-    
903
-    /* hijack pcre matches for byte comparison 
904
-    if (pm.comp) {
905
-        pm_dbgmsg("cli_pcre_scanbuf: assigning lsigcnt[%d][%d], located @ %d\n",
906
-    }*/
907 902
 
908 903
     /* free match results */
909 904
     cli_pcre_results_free(&p_res);
... ...
@@ -913,6 +917,97 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
913 913
     return ret;
914 914
 }
915 915
 
916
+int cli_pcre_bcmp_compare_check(const unsigned char *buffer, uint32_t length, int offset, struct cli_pcre_meta *pm)
917
+{
918
+    if (!buffer || !pm) {
919
+        return CL_ENULLARG;
920
+    }
921
+
922
+    const uint32_t byte_len = pm->bcmp_data.byte_len;
923
+    unsigned char* conversion_buf[byte_len+1];
924
+    char opt = (char) pm->bcmp_data.options;
925
+    uint32_t value = 0;
926
+    const unsigned char* end_buf = NULL;
927
+
928
+    if (!(pm->flags & CLI_PCRE_BCOMP) || !(offset + pm->bcmp_data.offset + pm->bcmp_data.byte_len < length)) {
929
+            return CL_SUCCESS;
930
+            
931
+    }
932
+
933
+    offset += pm->bcmp_data.offset;
934
+    memcpy(conversion_buf, buffer+offset, byte_len);
935
+    conversion_buf[byte_len] = '\0';
936
+
937
+    switch(opt) {
938
+        /*hb*/
939
+        case CLI_PCRE_BCOMP_HEX | CLI_PCRE_BCOMP_LE:
940
+            value = cli_strntoul(buffer+offset, byte_len, &end_buf, 16);
941
+            if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) {
942
+                return CL_SUCCESS;
943
+            }
944
+
945
+            value = le32_to_host(value);
946
+            break;
947
+
948
+        /*hl*/  
949
+        case CLI_PCRE_BCOMP_HEX | CLI_PCRE_BCOMP_BE:
950
+            value = cli_strntoul(buffer+offset, byte_len, &end_buf, 16);
951
+            if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) {
952
+                return CL_SUCCESS;
953
+            }
954
+
955
+            value = be32_to_host(value);
956
+            break;
957
+
958
+        /*dl*/
959
+        case CLI_PCRE_BCOMP_DEC | CLI_PCRE_BCOMP_LE:
960
+            value = cli_strntoul(buffer+offset, byte_len, &end_buf, 10);
961
+            if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) {
962
+                return CL_SUCCESS;
963
+            }
964
+
965
+            value = le32_to_host(value);
966
+            break;
967
+
968
+        /*db*/
969
+        case CLI_PCRE_BCOMP_DEC | CLI_PCRE_BCOMP_BE:
970
+            value = cli_strntoul(buffer+offset, byte_len, &end_buf, 10);
971
+            if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) {
972
+                return CL_SUCCESS;
973
+            }
974
+
975
+            value = be32_to_host(value);
976
+            break;
977
+
978
+        default:
979
+            return CL_ENULLARG;
980
+    }
981
+
982
+    switch (pm->bcmp_data.comp_symbol) {
983
+
984
+        case '>':
985
+            if (value > pm->bcmp_data.comp_value) {
986
+                return CL_VIRUS;
987
+            }
988
+
989
+        case '<':
990
+            if (value < pm->bcmp_data.comp_value) {
991
+                return CL_VIRUS;
992
+            }
993
+
994
+        case '=':
995
+            if (value == pm->bcmp_data.comp_value) {
996
+                return CL_VIRUS;
997
+            }
998
+
999
+        default:
1000
+            return CL_ENULLARG;
1001
+    }
1002
+
1003
+    return CL_SUCCESS;
1004
+}
1005
+
1006
+
916 1007
 void cli_pcre_freemeta(struct cli_matcher *root, struct cli_pcre_meta *pm)
917 1008
 {
918 1009
     if (!pm)
... ...
@@ -96,6 +96,8 @@ void cli_pcre_freeoff(struct cli_pcre_off *data);
96 96
 int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **virname, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, const struct cli_pcre_off *data, cli_ctx *ctx);
97 97
 void cli_pcre_freemeta(struct cli_matcher *root, struct cli_pcre_meta *pm);
98 98
 void cli_pcre_freetable(struct cli_matcher *root);
99
+int cli_pcre_bcmp_compare_check(const unsigned char *buffer, uint32_t length, int offset, struct cli_pcre_meta *pm);
100
+int cli_pcre_bcmp_add_opts(const char **opt, struct cli_pcre_bcomp *bcomp);
99 101
 #else
100 102
 /* NO-PCRE DECLARATIONS - defined because encasing everything in '#if' is a pain and because dynamic library mappings are weird */
101 103
 #define PCRE_BYPASS ""
... ...
@@ -539,7 +539,7 @@ size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count,
539 539
  *                      between 2 and 36 inclusive, or be the special value 0.
540 540
  * @return long         The signed long value.
541 541
  */
542
-static long cli_strntol(const char* nptr, size_t n, char** endptr, register int base)
542
+long cli_strntol(const char* nptr, size_t n, char** endptr, register int base)
543 543
 {
544 544
     register const char* s = nptr;
545 545
     register unsigned long acc = 0;
... ...
@@ -662,7 +662,7 @@ done:
662 662
  *                      between 2 and 36 inclusive, or be the special value 0.
663 663
  * @return unsigned long The unsigned long value.
664 664
  */
665
-static unsigned long
665
+unsigned long
666 666
 cli_strntoul(const char* nptr, size_t n, char** endptr, register int base)
667 667
 {
668 668
     register const char* s = nptr;
... ...
@@ -73,7 +73,9 @@ const char *cli_memstr(const char *haystack, unsigned int hs, const char *needle
73 73
 char *cli_strrcpy(char *dest, const char *source);
74 74
 size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens);
75 75
 size_t cli_ldbtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens, int token_skip);
76
-cl_error_t cli_strntol_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, long *result);
76
+long cli_strntol(const char* nptr, size_t n, char** endptr, register int base);
77
+unsigned long cli_strntoul(const char* nptr, size_t n, char** endptr, register int base);
78
+cl_errot_t cli_strntol_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, long *result);
77 79
 cl_error_t cli_strntoul_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, unsigned long *result);
78 80
 int cli_isnumber(const char *str);
79 81
 char *cli_unescape(const char *str);