Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

signature.c

Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2002 Sourcefire, Inc.
00003 ** Author(s):   Andrew R. Baker <andrewb@sourcefire.com>
00004 **
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 **
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 **
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <string.h>
00021 #include <ctype.h>
00022 #include "signature.h"
00023 #include "util.h"
00024 #include "rules.h"
00025 #include "mstring.h"
00026 
00027 extern char *file_name;
00028 extern int file_line;
00029 
00030 
00031 /********************* Reference Implementation *******************************/
00032 
00033 ReferenceNode *AddReference(ReferenceNode *rn, char *system, char *id)
00034 {
00035     ReferenceNode *newNode;
00036 
00037     if(system == NULL || id == NULL)
00038     {
00039         ErrorMessage("NULL reference argument\n");
00040         return rn;
00041     }
00042     
00043     /* create the new node */
00044     if(!(newNode = (ReferenceNode *)malloc(sizeof(ReferenceNode))))
00045     {
00046         FatalError("Out of memory in AddReference\n");
00047     }
00048     memset(newNode, 0, sizeof(ReferenceNode));
00049     
00050     /* lookup the reference system */
00051     if(!(newNode->system = ReferenceSystemLookup(system)))
00052     {
00053         newNode->system = ReferenceSystemAdd(system, NULL);
00054     }
00055     newNode->id = strdup(id);
00056     
00057     /* add the node to the list */
00058     newNode->next = rn;
00059     
00060     return newNode;
00061 }
00062 
00063 /* print a reference node */
00064 void FPrintReference(FILE *fp, ReferenceNode *refNode)
00065 {
00066     if(refNode)
00067     {
00068         if(refNode->system)
00069         {
00070             if(refNode->system->url)
00071                 fprintf(fp, "[Xref => %s%s]", refNode->system->url, 
00072                         refNode->id);
00073             else
00074                 fprintf(fp, "[Xref => %s %s]", refNode->system->name,
00075                         refNode->id);
00076         }
00077         else
00078         {
00079             fprintf(fp, "[Xref => %s]", refNode->id);
00080         }
00081     }
00082     return;   
00083 }
00084 
00085 void ParseReference(char *args, OptTreeNode *otn)
00086 {
00087     char **toks;
00088     int num_toks;
00089 
00090     /* 2 tokens: system, id */
00091     toks = mSplit(args, ",", 2, &num_toks, 0);
00092     if(num_toks != 2)
00093     {
00094         LogMessage("WARNING %s(%d): invalid Reference spec '%s'.  Ignored\n",
00095                 file_name, file_line, args);
00096     }
00097     else
00098     {
00099     otn->sigInfo.refs = AddReference(otn->sigInfo.refs, toks[0], toks[1]);
00100     }
00101 
00102     mSplitFree(&toks, num_toks);
00103 
00104     return;
00105 }
00106 
00107 
00108 /********************* End of Reference Implementation ************************/
00109 
00110 /********************** Reference System Implementation ***********************/
00111 
00112 ReferenceSystemNode *referenceSystems = NULL;
00113 
00114 ReferenceSystemNode *ReferenceSystemAdd(char *name, char *url)
00115 {   
00116     ReferenceSystemNode *newNode;
00117     if(name == NULL)
00118     {
00119         ErrorMessage("NULL reference system name\n");
00120         return NULL;
00121     }
00122 
00123     /* create the new node */
00124     if(!(newNode = (ReferenceSystemNode *)malloc(sizeof(ReferenceSystemNode))))
00125     {
00126         FatalError("Out of memory in AddReferenceSystem\n");
00127     }
00128     memset(newNode, 0, sizeof(ReferenceSystemNode));
00129 
00130     newNode->name = strdup(name);
00131     if(url)
00132         newNode->url = strdup(url);
00133     else
00134         newNode->url = NULL;
00135 
00136     /* add to the list */
00137     newNode->next = referenceSystems;
00138     referenceSystems = newNode;
00139     return newNode;
00140 }
00141 
00142 ReferenceSystemNode *ReferenceSystemLookup(char *name)
00143 {   
00144     ReferenceSystemNode *refSysNode = referenceSystems;
00145     while(refSysNode)
00146     {
00147         if(strcasecmp(name, refSysNode->name) == 0)
00148             return refSysNode;
00149         refSysNode = refSysNode->next;
00150     }
00151     return NULL;
00152 }
00153 
00154 void ParseReferenceSystemConfig(char *args)
00155 {
00156     char **toks;
00157     char *name = NULL;
00158     char *url = NULL;
00159     int num_toks;
00160 
00161     /* 2 tokens: name <url> */
00162     toks = mSplit(args, " ", 2, &num_toks, 0);
00163     name = toks[0];
00164     if(num_toks == 2)
00165     {
00166         url = toks[1];
00167         while(isspace((int)*url))
00168             url++;
00169         if(url[0] == '\0')
00170             url = NULL;
00171     }
00172     ReferenceSystemAdd(name, url);
00173 
00174     mSplitFree(&toks, num_toks);
00175     return;
00176 }
00177 
00178 /****************** End of Reference System Implementation ********************/
00179 
00180 /********************* Miscellaneous Parsing Functions ************************/
00181 
00182 void ParseSID(char *sid, OptTreeNode *otn)
00183 {
00184     if(sid != NULL)
00185     {
00186         while(isspace((int)*sid)) { sid++; }
00187 
00188         if(isdigit((int)sid[0]))
00189         {
00190             otn->sigInfo.id = atoi(sid);
00191             /* deprecated */
00192             otn->event_data.sig_id = atoi(sid);
00193             return;
00194         }
00195 
00196         LogMessage("WARNING %s(%d) => Bad SID found: %s\n", file_name, 
00197                 file_line, sid);
00198         return;
00199     }
00200 
00201     LogMessage("WARNING %s(%d) => SID found without ID number\n", file_name, 
00202                file_line);
00203 
00204     return;
00205 }
00206 
00207 void ParseRev(char *rev, OptTreeNode *otn)
00208 {
00209     if(rev != NULL)
00210     {
00211         while(isspace((int)*rev)) { rev++; }
00212 
00213         if(isdigit((int)rev[0]))
00214         {
00215             otn->sigInfo.rev = atoi(rev);
00216             /* deprecated */
00217             otn->event_data.sig_rev = atoi(rev);
00218             return;
00219         }
00220 
00221         LogMessage("WARNING %s(%d) => Bad Rev found: %s\n", file_name, 
00222             file_line, rev);
00223                 
00224         return;
00225     }
00226 
00227     LogMessage("WARNING %s(%d) => Rev found without number!\n", file_name, 
00228             file_line);
00229 
00230     return;
00231 }
00232 /****************** End of Miscellaneous Parsing Functions ********************/
00233 
00234 /************************ Class/Priority Implementation ***********************/
00235 
00236 ClassType *classTypes = NULL;
00237 
00238 int AddClassificationConfig(ClassType *newNode);
00239 
00240 void ParsePriority(char *priority, OptTreeNode *otn)
00241 {
00242     if(priority != NULL)
00243     {
00244         while(isspace((int)*priority))
00245             priority++;
00246 
00247         if(isdigit((int)priority[0]))
00248         {
00249             otn->sigInfo.priority = atoi(priority);
00250             /* deprecated */
00251             otn->event_data.priority = atoi(priority);
00252             return;
00253         }
00254 
00255         LogMessage("WARNING %s(%d) => Bad Priority: %s\n", file_name, 
00256                 file_line, priority);
00257 
00258         return;
00259     }
00260 
00261     LogMessage("WARNING %s(%d) => Priority without an argument!\n", file_name, 
00262             file_line);
00263 
00264     return;
00265 }
00266 
00267 
00268 void ParseClassType(char *classtype, OptTreeNode *otn)
00269 {
00270     ClassType *classType;
00271     if(classtype != NULL)
00272     {
00273         while(isspace((int)*classtype)) 
00274             classtype++;
00275 
00276         if(strlen(classtype) > 0)
00277         {
00278             if((classType = ClassTypeLookupByType(classtype)))
00279             {
00280                 otn->sigInfo.classType = classType;
00281 
00282                 /*
00283                 **  Add the class_id to class_id so we can
00284                 **  reference it for all rules, whether they have
00285                 **  a class_id or not.
00286                 */
00287                 otn->sigInfo.class_id = classType->id;
00288                 
00289                 if(otn->sigInfo.priority == 0)
00290                     otn->sigInfo.priority = classType->priority;
00291                 /* deprecated */
00292                 otn->event_data.classification = classType->id;
00293                 if(otn->event_data.priority == 0)
00294                     otn->event_data.priority = classType->priority;
00295                 return;
00296             }
00297         }
00298         FatalError("%s(%d) => Unknown ClassType: %s\n", file_name, 
00299                    file_line, classtype);
00300         return;
00301     }
00302 
00303     LogMessage("WARNING %s(%d) => ClassType without an argument!\n", file_name, 
00304                file_line);
00305 
00306     return;
00307 }
00308 
00309 ClassType *ClassTypeLookupByType(char *type)
00310 {
00311     ClassType *idx = classTypes;
00312     if(!type)
00313         return NULL;
00314 
00315     while(idx)
00316     {
00317         if(strcasecmp(type, idx->type) == 0)
00318             return idx;
00319         idx = idx->next;
00320     }
00321     return NULL;
00322 }
00323 
00324 ClassType *ClassTypeLookupById(int id)
00325 {
00326     ClassType *idx = classTypes;
00327     while(idx)
00328     {
00329         if(idx->id == id)
00330             return idx;
00331         idx = idx->next;
00332     }
00333     return NULL;
00334 }
00335 
00336 
00337 void ParseClassificationConfig(char *args)
00338 {
00339     char **toks;
00340     int num_toks;
00341     char *data;
00342     ClassType *newNode;
00343 
00344     toks = mSplit(args, ",",3, &num_toks, '\\');
00345 
00346     if(num_toks != 3)
00347     {
00348         ErrorMessage("%s(%d): Invalid classification config: %s\n",
00349                      file_name, file_line, args);
00350     }
00351     else
00352     {
00353         /* create the new node */
00354         if(!(newNode = (ClassType *)malloc(sizeof(ClassType))))
00355         {
00356             FatalError("Out of memory in ParseClassificationConfig\n");
00357         }
00358         memset(newNode, 0, sizeof(ClassType));
00359 
00360         data = toks[0];
00361         while(isspace((int)*data)) 
00362             data++;
00363         newNode->type = strdup(data);   /* XXX: oom check */
00364 
00365         data = toks[1];
00366         while(isspace((int)*data))
00367             data++;
00368         newNode->name = strdup(data);   /* XXX: oom check */
00369 
00370         data = toks[2];
00371         while(isspace((int)*data))
00372             data++;
00373         /* XXX: error checking needed */
00374         newNode->priority = atoi(data); /* XXX: oom check */
00375 
00376         if(AddClassificationConfig(newNode) == -1)
00377         {
00378             ErrorMessage("%s(%d): Duplicate classification \"%s\""
00379                     "found, ignoring this line\n", file_name, file_line, 
00380                     newNode->type);
00381 
00382             if(newNode)
00383             {
00384                 if(newNode->name)
00385                     free(newNode->name);
00386                 if(newNode->type)
00387                     free(newNode->type);
00388                 free(newNode);
00389             }
00390         }
00391     }
00392 
00393     mSplitFree(&toks, num_toks);
00394     return;
00395 }
00396 
00397 int AddClassificationConfig(ClassType *newNode)
00398 {
00399     int max_id = 0;
00400     ClassType *current;
00401 
00402     current = classTypes;
00403 
00404     while(current)
00405     {
00406         /* dup check */
00407         if(strcasecmp(current->type, newNode->type) == 0)
00408             return -1;
00409         
00410         if(current->id > max_id)
00411             max_id = current->id;
00412         
00413         current = current->next;
00414     }
00415 
00416     /* insert node */
00417     
00418     newNode->id = max_id + 1;
00419     newNode->next = classTypes;
00420     classTypes = newNode;
00421 
00422     return newNode->id;
00423 }
00424         
00425         
00426 /***************** End of Class/Priority Implementation ***********************/

Generated on Sun May 14 14:51:18 2006 by  doxygen 1.4.2