X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=src%2Fanalysisd%2Fdecoders%2Fdecoder.c;h=cc20b1a806ff4f9bc619fcba32ded2088d2cc8d1;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hp=70ac4cc4f6fd28753d8a910a1549d8f021f43414;hpb=301048b51990573e58a30dc4a5bb4ec285cad554;p=ossec-hids.git diff --git a/src/analysisd/decoders/decoder.c b/src/analysisd/decoders/decoder.c old mode 100755 new mode 100644 index 70ac4cc..cc20b1a --- a/src/analysisd/decoders/decoder.c +++ b/src/analysisd/decoders/decoder.c @@ -1,5 +1,3 @@ -/* @(#) $Id$ */ - /* Copyright (C) 2009 Trend Micro Inc. * All rights reserved. * @@ -7,191 +5,168 @@ * and/or modify it under the terms of the GNU General Public * License (version 2) as published by the FSF - Free Software * Foundation. - * - * License details at the LICENSE file included with OSSEC or - * online at: http://www.ossec.net/en/licensing.html */ - #include "shared.h" #include "os_regex/os_regex.h" #include "os_xml/os_xml.h" - - #include "eventinfo.h" #include "decoder.h" +#include "config.h" -/* DecodeEvent. - * Will use the osdecoders to decode the received event. - */ +/* Use the osdecoders to decode the received event */ void DecodeEvent(Eventinfo *lf) { OSDecoderNode *node; OSDecoderNode *child_node; OSDecoderInfo *nnode; - char *llog; - char *pmatch; - char *cmatch; - char *regex_prev = NULL; - + const char *llog = NULL; + const char *pmatch = NULL; + const char *cmatch = NULL; + const char *regex_prev = NULL; node = OS_GetFirstOSDecoder(lf->program_name); - - /* Return if no node... - * This shouldn't happen here anyways. - */ - if(!node) + if (!node) { return; + } - - #ifdef TESTRULE - if(!alert_only) - { +#ifdef TESTRULE + if (!alert_only) { print_out("\n**Phase 2: Completed decoding."); } - #endif +#endif - do - { + do { nnode = node->osdecoder; - - /* First checking program name */ - if(lf->program_name) - { - if(!OSMatch_Execute(lf->program_name, lf->p_name_size, - nnode->program_name)) - { - continue; + /* First check program name */ + if (lf->program_name) { + if (nnode->program_name) { + if (!OSMatch_Execute(lf->program_name, lf->p_name_size, + nnode->program_name)) { + continue; + } + pmatch = lf->log; + } else if (nnode->program_name_pcre2) { + if (!OSPcre2_Execute(lf->program_name, nnode->program_name_pcre2)) { + continue; + } + pmatch = lf->log; } - pmatch = lf->log; } - /* If prematch fails, go to the next osdecoder in the list */ - if(nnode->prematch) - { - if(!(pmatch = OSRegex_Execute(lf->log, nnode->prematch))) - { + if (nnode->prematch) { + if (!(pmatch = OSRegex_Execute(lf->log, nnode->prematch))) { + continue; + } + } + else if (nnode->prematch_pcre2) { + if (!(pmatch = OSPcre2_Execute(lf->log, nnode->prematch_pcre2))) { continue; } - - /* Next character */ - if(*pmatch != '\0') - pmatch++; } - - #ifdef TESTRULE - if(!alert_only)print_out(" decoder: '%s'", nnode->name); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" decoder: '%s'", nnode->name); + } +#endif lf->decoder_info = nnode; - - child_node = node->child; - /* If no child node is set, set the child node * as if it were the child (ugh) */ - if(!child_node) - { + if (!child_node) { child_node = node; } - else - { + else { /* Check if we have any child osdecoder */ - while(child_node) - { + while (child_node) { nnode = child_node->osdecoder; - /* If we have a pre match and it matches, keep * going. If we don't have a prematch, stop * and go for the regexes. */ - if(nnode->prematch) - { - char *llog; + if (nnode->prematch) { + const char *llog2; + + /* If we have an offset set, use it */ + if (nnode->prematch_offset & AFTER_PARENT) { + llog2 = pmatch; + } else { + llog2 = lf->log; + } - /* If we have an offset set, use it */ - if(nnode->prematch_offset & AFTER_PARENT) - { - llog = pmatch; + if ((cmatch = OSRegex_Execute(llog2, nnode->prematch))) { + lf->decoder_info = nnode; + + break; } - else - { - llog = lf->log; + } else if (nnode->prematch_pcre2) { + const char *llog2; + + /* If we have an offset set, use it */ + if (nnode->prematch_offset & AFTER_PARENT) { + llog2 = pmatch; + } else { + llog2 = lf->log; } - if((cmatch = OSRegex_Execute(llog, nnode->prematch))) - { - if(*cmatch != '\0') - cmatch++; - + if ((cmatch = OSPcre2_Execute(llog2, nnode->prematch_pcre2))) { lf->decoder_info = nnode; break; } - } - else - { + } else { cmatch = pmatch; break; } - /* If we have multiple regex-only childs, * do not attempt to go any further with them. */ - if(child_node->osdecoder->get_next) - { - do - { + if (child_node->osdecoder->get_next) { + do { child_node = child_node->next; - }while(child_node && child_node->osdecoder->get_next); + } while (child_node && child_node->osdecoder->get_next); - if(!child_node) + if (!child_node) { return; + } child_node = child_node->next; - nnode = NULL; - } - else - { + nnode = NULL; + } else { child_node = child_node->next; nnode = NULL; } } } - /* Nothing matched */ - if(!nnode) + if (!nnode) { return; + } - - /* If we have a external decoder, execute it */ - if(nnode->plugindecoder) - { + /* If we have an external decoder, execute it */ + if (nnode->plugindecoder) { nnode->plugindecoder(lf); return; } - - - /* Getting the regex */ - while(child_node) - { - if(nnode->regex) - { - int i = 0; + + /* Get the regex */ + while (child_node) { + if (nnode->regex) { + int i; /* With regex we have multiple options * regarding the offset: @@ -200,34 +175,25 @@ void DecodeEvent(Eventinfo *lf) * after some previous regex, * or any offset */ - if(nnode->regex_offset) - { - if(nnode->regex_offset & AFTER_PARENT) - { + if (nnode->regex_offset) { + if (nnode->regex_offset & AFTER_PARENT) { llog = pmatch; - } - else if(nnode->regex_offset & AFTER_PREMATCH) - { + } else if (nnode->regex_offset & AFTER_PREMATCH) { llog = cmatch; - } - else if(nnode->regex_offset & AFTER_PREVREGEX) - { - if(!regex_prev) + } else if (nnode->regex_offset & AFTER_PREVREGEX) { + if (!regex_prev) { llog = cmatch; - else + } else { llog = regex_prev; + } } - } - else - { + } else { llog = lf->log; } /* If Regex does not match, return */ - if(!(regex_prev = OSRegex_Execute(llog, nnode->regex))) - { - if(nnode->get_next) - { + if (!(regex_prev = OSRegex_Execute(llog, nnode->regex))) { + if (nnode->get_next) { child_node = child_node->next; nnode = child_node->osdecoder; continue; @@ -235,30 +201,86 @@ void DecodeEvent(Eventinfo *lf) return; } + lf->decoder_info = nnode; - /* Fixing next pointer */ - if(*regex_prev != '\0') - regex_prev++; + for (i = 0; nnode->regex->sub_strings[i]; i++) { + if (i >= Config.decoder_order_size) { + ErrorExit("%s: ERROR: Regex has too many groups.", ARGV0); + } + + if (nnode->order[i]) + nnode->order[i](lf, nnode->regex->sub_strings[i], i); + else + /* We do not free any memory used above */ + os_free(nnode->regex->sub_strings[i]); + + nnode->regex->sub_strings[i] = NULL; + } + + /* If we have a next regex, try getting it */ + if (nnode->get_next) { + child_node = child_node->next; + nnode = child_node->osdecoder; + continue; + } - while(nnode->regex->sub_strings[i]) - { - if(nnode->order[i]) - { - nnode->order[i](lf, nnode->regex->sub_strings[i]); - nnode->regex->sub_strings[i] = NULL; - i++; + break; + } + else if (nnode->pcre2) { + int i; + + /* With regex we have multiple options + * regarding the offset: + * after the prematch, + * after the parent, + * after some previous regex, + * or any offset + */ + if (nnode->regex_offset) { + if (nnode->regex_offset & AFTER_PARENT) { + llog = pmatch; + } else if (nnode->regex_offset & AFTER_PREMATCH) { + llog = cmatch; + } else if (nnode->regex_offset & AFTER_PREVREGEX) { + if (!regex_prev) { + llog = cmatch; + } else { + llog = regex_prev; + } + } + } else { + llog = lf->log; + } + + /* If Regex does not match, return */ + if (!(regex_prev = OSPcre2_Execute(llog, nnode->pcre2))) { + if (nnode->get_next) { + child_node = child_node->next; + nnode = child_node->osdecoder; continue; } + return; + } + + + lf->decoder_info = nnode; + + for (i = 0; nnode->pcre2->sub_strings[i]; i++) { + if (i >= Config.decoder_order_size) { + ErrorExit("%s: ERROR: Regex has too many groups.", ARGV0); + } - /* We do not free any memory used above */ - os_free(nnode->regex->sub_strings[i]); - nnode->regex->sub_strings[i] = NULL; - i++; + if (nnode->order[i]) + nnode->order[i](lf, nnode->pcre2->sub_strings[i], i); + else + /* We do not free any memory used above */ + os_free(nnode->pcre2->sub_strings[i]); + + nnode->pcre2->sub_strings[i] = NULL; } /* If we have a next regex, try getting it */ - if(nnode->get_next) - { + if (nnode->get_next) { child_node = child_node->next; nnode = child_node->osdecoder; continue; @@ -267,147 +289,235 @@ void DecodeEvent(Eventinfo *lf) break; } + /* If we don't have a regex, we may leave now */ return; } /* ok to return */ - return; - }while((node=node->next) != NULL); + return; + } while ((node = node->next) != NULL); - #ifdef TESTRULE - if(!alert_only) - { +#ifdef TESTRULE + if (!alert_only) { print_out(" No decoder matched."); } - #endif - +#endif } - /*** Event decoders ****/ -void *DstUser_FP(Eventinfo *lf, char *field) + +void *DstUser_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" dstuser: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" dstuser: '%s'", field); + } +#endif + lf->dstuser = field; - return(NULL); + return (NULL); } -void *SrcUser_FP(Eventinfo *lf, char *field) + +void *SrcUser_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" srcuser: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" srcuser: '%s'", field); + } +#endif + lf->srcuser = field; - return(NULL); + return (NULL); } -void *SrcIP_FP(Eventinfo *lf, char *field) + +void *SrcIP_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { +#ifdef TESTRULE + if (!alert_only) { + print_out(" srcip: '%s'", field); + } +#endif + + lf->srcip = field; + +#ifdef LIBGEOIP_ENABLED + + if(!lf->srcgeoip) { + lf->srcgeoip = GetGeoInfobyIP(lf->srcip); + } + #ifdef TESTRULE - if(!alert_only)print_out(" srcip: '%s'", field); + if (lf->srcgeoip && !alert_only) + print_out(" srcgeoip: '%s'", lf->srcgeoip); #endif - - lf->srcip = field; - return(NULL); + +#endif + return (NULL); + } -void *DstIP_FP(Eventinfo *lf, char *field) + +void *DstIP_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { +#ifdef TESTRULE + if (!alert_only) { + print_out(" dstip: '%s'", field); + } +#endif + + lf->dstip = field; +#ifdef LIBGEOIP_ENABLED + + if(!lf->dstgeoip) { + lf->dstgeoip = GetGeoInfobyIP(lf->dstip); + } #ifdef TESTRULE - if(!alert_only)print_out(" dstip: '%s'", field); + if (lf->dstgeoip && !alert_only) + print_out(" dstgeoip: '%s'", lf->dstgeoip); #endif - - lf->dstip = field; - return(NULL); + +#endif + return (NULL); + } -void *SrcPort_FP(Eventinfo *lf, char *field) + +void *SrcPort_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" srcport: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" srcport: '%s'", field); + } +#endif + lf->srcport = field; - return(NULL); + return (NULL); } -void *DstPort_FP(Eventinfo *lf, char *field) + +void *DstPort_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" dstport: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" dstport: '%s'", field); + } +#endif + lf->dstport = field; - return(NULL); + return (NULL); } -void *Protocol_FP(Eventinfo *lf, char *field) + +void *Protocol_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" proto: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" proto: '%s'", field); + } +#endif + lf->protocol = field; - return(NULL); + return (NULL); } -void *Action_FP(Eventinfo *lf, char *field) + +void *Action_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" action: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" action: '%s'", field); + } +#endif + lf->action = field; - return(NULL); + return (NULL); } -void *ID_FP(Eventinfo *lf, char *field) + +void *ID_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" id: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" id: '%s'", field); + } +#endif + lf->id = field; - return(NULL); + return (NULL); } -void *Url_FP(Eventinfo *lf, char *field) + +void *Url_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" url: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" url: '%s'", field); + } +#endif + lf->url = field; - return(NULL); + return (NULL); } -void *Data_FP(Eventinfo *lf, char *field) + +void *Data_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" extra_data: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" extra_data: '%s'", field); + } +#endif + lf->data = field; - return(NULL); + return (NULL); } -void *Status_FP(Eventinfo *lf, char *field) + +void *Status_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" status: '%s'", field); - #endif - +#ifdef TESTRULE + if (!alert_only) { + print_out(" status: '%s'", field); + } +#endif + lf->status = field; - return(NULL); + return (NULL); } -void *SystemName_FP(Eventinfo *lf, char *field) + +void *SystemName_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - #ifdef TESTRULE - if(!alert_only)print_out(" system_name: '%s'", field); - #endif +#ifdef TESTRULE + if (!alert_only) { + print_out(" system_name: '%s'", field); + } +#endif lf->systemname = field; - return(NULL); + return (NULL); } -void *None_FP(Eventinfo *lf, char *field) + +void *FileName_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) { - free(field); - return(NULL); +#ifdef TESTRULE + if (!alert_only) { + print_out(" filename: '%s'", field); + } +#endif + + lf->filename = field; + return (NULL); } -/* EOF */ +void *DynamicField_FP(Eventinfo *lf, char *field, int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" %s: '%s'", lf->decoder_info->fields[order], field); + } +#endif + + lf->fields[order] = field; + + return (NULL); +} + +void *None_FP(__attribute__((unused)) Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ + free(field); + return (NULL); +} +