"Fossies" - the Fresh Open Source Software Archive

Member "ettercap-0.8.3.1/utils/etterfilter/ef_encode.c" (1 Aug 2020, 14814 Bytes) of package /linux/privat/ettercap-0.8.3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ef_encode.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.8.3_vs_0.8.3.1.

    1 /*
    2     etterfilter -- the actual compiler
    3 
    4     Copyright (C) ALoR & NaGA
    5 
    6     This program is free software; you can redistribute it and/or modify
    7     it under the terms of the GNU General Public License as published by
    8     the Free Software Foundation; either version 2 of the License, or
    9     (at your option) any later version.
   10 
   11     This program is distributed in the hope that it will be useful,
   12     but WITHOUT ANY WARRANTY; without even the implied warranty of
   13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14     GNU General Public License for more details.
   15 
   16     You should have received a copy of the GNU General Public License
   17     along with this program; if not, write to the Free Software
   18     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   19 
   20 */
   21 
   22 #include <ef.h>
   23 #include <ef_functions.h>
   24 #include <ec_filter.h>
   25 
   26 #include <ctype.h>
   27 
   28 #include <regex.h>
   29 #ifdef HAVE_PCRE
   30    #include <pcre.h>
   31 #endif
   32 
   33 /* protos */
   34 
   35 static char ** decode_args(char *args, int *nargs);
   36 static char * strsep_quotes(char **stringp, const char delim);
   37 
   38 /*******************************************/
   39 
   40 /*
   41  * search an offset and fill the filter_op structure
   42  * return E_SUCCESS on error.
   43  */
   44 int encode_offset(char *string, struct filter_op *fop)
   45 {
   46    char *str, *p, *q, *tok;
   47    int ret;
   48 
   49    memset(fop, 0, sizeof(struct filter_op));
   50    
   51    /* make the modifications on a copy */
   52    str = strdup(string);
   53    
   54    /*
   55     * the offset contains at least one '.'
   56     * we are sure because the syntax parser
   57     * will not have passed it here if it is not
   58     * in the right form.
   59     */
   60    p = ec_strtok(str, ".", &tok);
   61    q = ec_strtok(NULL, ".", &tok);
   62 
   63    /*
   64     * the assumption above is not always true, e.g.:
   65     * log(DATA,d "x.log"); 
   66     * results in q == NULL.
   67     */
   68    if (q == NULL)
   69       return -E_NOTFOUND;
   70 
   71    /* the the virtual pointer from the table */
   72    ret = get_virtualpointer(p, q, &fop->op.test.level, &fop->op.test.offset, &fop->op.test.size);
   73 
   74    SAFE_FREE(str);
   75 
   76    return ret;
   77 }
   78 
   79 /*
   80  * assing the value of the const to the fop.value
   81  *
   82  * all the value are integer32 and are saved in host order
   83  */
   84 int encode_const(char *string, struct filter_op *fop)
   85 {
   86    char *p;
   87    
   88    memset(fop, 0, sizeof(struct filter_op));
   89    
   90    /* it is an hexadecimal value */
   91    if (!strncmp(string, "0x", 2) && isxdigit((int)string[2])) {
   92       fop->op.test.value = strtoul(string, NULL, 16);
   93       return E_SUCCESS;
   94       
   95    /* it is an integer value */
   96    } else if (isdigit((int)string[0])) {
   97       fop->op.test.value = strtoul(string, NULL, 10);
   98       return E_SUCCESS;
   99       
  100    /* it is an ip address */
  101    } else if (string[0] == '\'' && string[strlen(string) - 1] == '\'') {
  102       struct ip_addr ipaddr;
  103       
  104       /* remove the single quote */
  105       p = strchr(string + 1, '\'');
  106       *p = '\0';
  107 
  108       if (ip_addr_pton(string + 1, &ipaddr) == E_SUCCESS) {
  109          switch (ntohs(ipaddr.addr_type)) {
  110             case AF_INET:
  111                /* 4-bytes - handle as a integer */
  112                fop->op.test.value = ntohl(ipaddr.addr32[0]);
  113                break;
  114             case AF_INET6:
  115                /* 16-bytes - handle as a byte pointer */
  116                ip_addr_cpy((u_char*)&fop->op.test.ipaddr, &ipaddr);
  117                break;
  118             default:
  119                return -E_FATAL;
  120          }
  121       }
  122       else {
  123          return -E_FATAL;
  124       }
  125       
  126       return E_SUCCESS;
  127       
  128    /* it is a string */
  129    } else if (string[0] == '\"' && string[strlen(string) - 1] == '\"') {
  130   
  131       /* remove the quotes */
  132       p = strchr(string + 1, '\"');
  133       *p = '\0';
  134 
  135       /* copy the string */
  136       fop->op.test.string = (u_char*)strdup(string + 1);
  137          
  138       /* escape it in the structure */
  139       fop->op.test.slen = strescape((char*)fop->op.test.string, 
  140             (char*)fop->op.test.string, strlen(fop->op.test.string)+1);
  141      
  142       return E_SUCCESS;
  143       
  144    /* it is a constant */
  145    } else if (isalpha((int)string[0])) {
  146       return get_constant(string, &fop->op.test.value);
  147    }
  148    
  149    /* anything else is an error */
  150    return -E_NOTFOUND;
  151 }
  152 
  153 
  154 /*
  155  * parse a function and its arguments and fill the structure
  156  */
  157 int encode_function(char *string, struct filter_op *fop)
  158 {
  159    char *str = strdup(string);
  160    int ret = -E_NOTFOUND;
  161    char *name, *args;
  162    int nargs = 0, i;
  163    char **dec_args = NULL;
  164    char *tok;
  165 
  166    memset(fop, 0, sizeof(struct filter_op));
  167    
  168    /* get the name of the function */
  169    name = ec_strtok(string, "(", &tok);
  170    /* get all the args */
  171    args = name + strlen(name) + 1;
  172 
  173    /* analyze the arguments */
  174    dec_args = decode_args(args, &nargs);
  175 
  176    /* this fop is a function */
  177    fop->opcode = FOP_FUNC;
  178 
  179    /* check if it is a known function */
  180    if (!strcmp(name, "search")) {
  181       if (nargs == 2) {
  182          /* get the level (DATA or DECODED) */
  183          if (encode_offset(dec_args[0], fop) == E_SUCCESS) {
  184             /* encode offset wipe the fop !! */
  185             fop->opcode = FOP_FUNC;
  186             fop->op.func.op = FFUNC_SEARCH;
  187             fop->op.func.string = (u_char*)strdup(dec_args[1]);
  188             fop->op.func.slen = strescape((char*)fop->op.func.string, 
  189                   (char*)fop->op.func.string, strlen(fop->op.func.string)+1);
  190             ret = E_SUCCESS;
  191          } else
  192             SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
  193       } else
  194          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  195    } else if (!strcmp(name, "regex")) {
  196       if (nargs == 2) {
  197          int err;
  198          regex_t regex;
  199          char errbuf[100];
  200          
  201          /* get the level (DATA or DECODED) */
  202          if (encode_offset(dec_args[0], fop) == E_SUCCESS) {
  203             /* encode offset wipe the fop !! */
  204             fop->opcode = FOP_FUNC;
  205             fop->op.func.op = FFUNC_REGEX;
  206             fop->op.func.string = (u_char*)strdup(dec_args[1]);
  207             fop->op.func.slen = strescape((char*)fop->op.func.string, 
  208                   (char*)fop->op.func.string, strlen(fop->op.func.string)+1);
  209             ret = E_SUCCESS;
  210          } else
  211             SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
  212 
  213          /* check if the regex is valid */
  214          err = regcomp(&regex, (const char*)fop->op.func.string, REG_EXTENDED | REG_NOSUB | REG_ICASE );
  215          if (err) {
  216             regerror(err, &regex, errbuf, sizeof(errbuf));
  217             SCRIPT_ERROR("%s", errbuf);
  218          } 
  219          
  220          regfree(&regex);
  221                         
  222       } else
  223          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  224    } else if (!strcmp(name, "pcre_regex")) {
  225 #ifndef HAVE_PCRE
  226       WARNING("The script contains pcre_regex, but you don't have support for it.");
  227 #else
  228       pcre *pregex;
  229       const char *errbuf = NULL;
  230       int erroff;
  231       
  232       if (nargs == 2) {
  233                      
  234          /* get the level (DATA or DECODED) */
  235          if (encode_offset(dec_args[0], fop) == E_SUCCESS) {
  236             /* encode offset wipe the fop !! */
  237             fop->opcode = FOP_FUNC;
  238             fop->op.func.op = FFUNC_PCRE;
  239             fop->op.func.string = strdup(dec_args[1]);
  240             fop->op.func.slen = strlen(fop->op.func.string);
  241             ret = E_SUCCESS;
  242          } else
  243             SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
  244 
  245          /* check if the pcre is valid */
  246          pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL );
  247          if (pregex == NULL)
  248             SCRIPT_ERROR("%s\n", errbuf);
  249 
  250          pcre_free(pregex);
  251       } else if (nargs == 3) {
  252             
  253          fop->opcode = FOP_FUNC;
  254          fop->op.func.op = FFUNC_PCRE;
  255          /* substitution always at layer DATA */
  256          fop->op.func.level = 5;
  257          fop->op.func.string = strdup(dec_args[1]);
  258          fop->op.func.slen = strlen(fop->op.func.string);
  259          fop->op.func.replace = strdup(dec_args[2]);
  260          fop->op.func.rlen = strlen(fop->op.func.replace);
  261          ret = E_SUCCESS;
  262          
  263          /* check if the pcre is valid */
  264          pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL );
  265          if (pregex == NULL)
  266             SCRIPT_ERROR("%s\n", errbuf);
  267 
  268          pcre_free(pregex);
  269       } else
  270          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  271 #endif
  272    } else if (!strcmp(name, "replace")) {
  273       if (nargs == 2) {
  274          fop->op.func.op = FFUNC_REPLACE;
  275          /* replace always operate at DATA level */
  276          fop->op.func.level = 5;
  277          fop->op.func.string = (u_char*)strdup(dec_args[0]);
  278          fop->op.func.slen = strescape((char*)fop->op.func.string, 
  279                (char*)fop->op.func.string, strlen(fop->op.func.string)+1);
  280          fop->op.func.replace = (u_char*)strdup(dec_args[1]);
  281          fop->op.func.rlen = strescape((char*)fop->op.func.replace, 
  282                (char*)fop->op.func.replace, strlen(fop->op.func.replace)+1);
  283          ret = E_SUCCESS;
  284       } else
  285          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  286    } else if (!strcmp(name, "inject")) {
  287       if (nargs == 1) {
  288          fop->op.func.op = FFUNC_INJECT;
  289          /* inject always operate at DATA level */
  290          fop->op.func.level = 5;
  291          fop->op.func.string = (u_char*)strdup(dec_args[0]);
  292          fop->op.func.slen = strlen((const char*)fop->op.func.string);
  293          ret = E_SUCCESS;
  294       } else
  295          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  296    } else if (!strcmp(name, "execinject")) {
  297       if (nargs == 1) {
  298          fop->op.func.op = FFUNC_EXECINJECT;
  299          /* execinject always operate at DATA level */
  300          fop->op.func.level = 5;
  301          fop->op.func.string = (u_char*)strdup(dec_args[0]);
  302          fop->op.func.slen = strlen((const char*)fop->op.func.string);
  303          ret = E_SUCCESS;
  304       } else
  305          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  306    } else if (!strcmp(name, "execreplace")) {
  307       if (nargs == 1) {
  308          fop->op.func.op = FFUNC_EXECREPLACE;
  309          /* execreplace always operate at DATA level */
  310          fop->op.func.level = 5;
  311          fop->op.func.string = (u_char*)strdup(dec_args[0]);
  312          fop->op.func.slen = strlen((const char*)fop->op.func.string);
  313          ret = E_SUCCESS;
  314       } else
  315          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  316    } else if (!strcmp(name, "log")) {
  317       if (nargs == 2) {
  318          /* get the level (DATA or DECODED) */
  319          if (encode_offset(dec_args[0], fop) == E_SUCCESS) {
  320             /* encode offset wipe the fop !! */
  321             fop->opcode = FOP_FUNC;
  322             fop->op.func.op = FFUNC_LOG;
  323             fop->op.func.string = (u_char*)strdup(dec_args[1]);
  324             fop->op.func.slen = strlen((const char*)fop->op.func.string);
  325             ret = E_SUCCESS;
  326          } else
  327             SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
  328       } else
  329          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  330    } else if (!strcmp(name, "drop")) {
  331       if (nargs == 0) {
  332          fop->op.func.op = FFUNC_DROP;
  333          ret = E_SUCCESS;
  334       } else
  335          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  336    } else if (!strcmp(name, "kill")) {
  337       if (nargs == 0) {
  338          fop->op.func.op = FFUNC_KILL;
  339          ret = E_SUCCESS;
  340       } else
  341          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  342    } else if (!strcmp(name, "msg")) {
  343       if (nargs == 1) {
  344          fop->op.func.op = FFUNC_MSG;
  345          fop->op.func.string = (u_char*)strdup(dec_args[0]);
  346          fop->op.func.slen = strescape((char*)fop->op.func.string, 
  347                (char*)fop->op.func.string, strlen(fop->op.func.string)+1);
  348          ret = E_SUCCESS;
  349       } else
  350          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  351    } else if (!strcmp(name, "exec")) {
  352       if (nargs == 1) {
  353          fop->op.func.op = FFUNC_EXEC;
  354          fop->op.func.string = (u_char*)strdup(dec_args[0]);
  355          fop->op.func.slen = strlen((const char*)fop->op.func.string);
  356          ret = E_SUCCESS;
  357       } else
  358          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  359    } else if (!strcmp(name, "exit")) {
  360       if (nargs == 0) {
  361          fop->opcode = FOP_EXIT;
  362          ret = E_SUCCESS;
  363       } else
  364          SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
  365    }
  366 
  367    /* free the array */
  368    for (i = 0; i < nargs; i++)
  369       SAFE_FREE(dec_args[i]);
  370       
  371    SAFE_FREE(dec_args);
  372    SAFE_FREE(str);
  373    return ret;
  374 }
  375 
  376 /*
  377  * split the args of a function and return
  378  * the number of found args
  379  */
  380 static char ** decode_args(char *args, int *nargs)
  381 {
  382    char *p, *q, *arg;
  383    int i = 0;
  384    char **parsed;
  385 
  386    *nargs = 0;
  387   
  388    /* get the end */
  389    if ((p = strrchr(args, ')')) != NULL)
  390       *p = '\0';
  391    
  392    /* trim the empty spaces */
  393    for (; *args == ' '; args++);
  394    for (q = args + strlen(args) - 1; *q == ' '; q--)
  395       *q = '\0';
  396 
  397    /* there are no arguments */
  398    if (!strchr(args, ',') && strlen(args) == 0)
  399       return NULL;
  400   
  401    SAFE_CALLOC(parsed, 1, sizeof(char *));
  402    
  403    /* split the arguments */
  404    for (p = strsep_quotes(&args, ','), i = 1; p != NULL; p = strsep_quotes(&args, ','), i++) {
  405       
  406       /* alloc the array for the arguments */
  407       SAFE_REALLOC(parsed, (i + 1) * sizeof(char *));
  408       
  409       /* trim the empty spaces */
  410       for (arg = p; *arg == ' '; arg++);
  411       for (q = arg + strlen(arg) - 1; *q == ' '; q--)
  412          *q = '\0';
  413     
  414       /* remove the quotes (if there are) */
  415       if (*arg == '\"' && arg[strlen(arg) - 1] == '\"') {      
  416          arg[strlen(arg) - 1] = '\0';
  417          arg++;
  418       }
  419       /* put in in the array */
  420       parsed[i - 1] = strdup(arg);
  421       
  422       ef_debug(5, "ARGUMENT: %s\n", arg);
  423    }
  424 
  425    /* return the number of args */
  426    *nargs = i - 1;
  427    
  428    return parsed;
  429 }
  430 
  431 
  432 
  433 /*
  434  * split the string in tokens separated by 'delim'.
  435  * ignore 'delim' if it is between two quotes "..."
  436  */
  437 static char * strsep_quotes(char **stringp, const char delim)
  438 {
  439     char *s;
  440     int c;
  441     char *tok;
  442 
  443    /* sanity check */
  444     if ((s = *stringp) == NULL)
  445         return (NULL);
  446 
  447    /* parse the string */
  448     for (tok = s;;) {
  449 
  450       /* XXX - 
  451        * this does not parses correctly string in the form:
  452        *
  453        *  "foo, bar, "tic,tac""
  454        */
  455 
  456       /* skip string between quotes */
  457       if (*s == '\"')
  458          while(*(++s) != '\"' && *s != '\0');
  459 
  460       c = *s++;
  461      
  462       /* search for the delimiter */
  463       if ( c == delim || c == 0) {
  464          if (c == 0)
  465             s = NULL;
  466          else
  467             s[-1] = 0;
  468          
  469          *stringp = s;
  470          
  471          return (tok);
  472       }
  473     }
  474     /* NOTREACHED */
  475 }
  476 
  477 /* EOF */
  478 
  479 // vim:ts=3:expandtab
  480