root/trunk/src/rules_mgmt.c @ 27

Revision 27, 16.8 KB (checked in by andreu, 16 years ago)

explicite output to find wrong definition bug - memory leak in renetcolAgg find

  • Property svn:eol-style set to native
Line 
1/*
2 * File: rules_mgmt.c
3 *
4 * Authors: ANDREU François-Xavier
5 *
6 * Copyright (C) 2005 GIP RENATER
7 */
8
9/*  This file is part of renetcol.
10 *
11 *  renetcol is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  renetcol is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with renetcol; if not, write to the Free Software
23 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24 */
25
26#include <syslog.h>
27#include "rules_mgmt.h"
28
29void 
30printRuleDef(RuleDefPtr rdPtr)
31{
32  if (rdPtr != NULL){
33    fprintf(stderr, "  ft: %hu\n", rdPtr->fieldType);
34    fprintf(stderr, "  check: %hu\n", rdPtr->check);
35    fprintf(stderr, "  operator: %hu\n", rdPtr->operator);
36    if (rdPtr->value!=NULL) {
37      fprintf(stderr, "  mask: %hu\n", rdPtr->value->mask);
38      switch (rdPtr->value->valueLength){
39      case 1:
40        fprintf(stderr, "  char value: %hu\n", rdPtr->value->stor.cvalue);
41        break;
42      case 2:
43        fprintf(stderr, "  short value: %hu\n", rdPtr->value->stor.svalue);
44        break;
45      case 4:
46        fprintf(stderr, "  long value: %lu\n", rdPtr->value->stor.lvalue);
47        break;
48      case 16:
49        fprintf(stderr, "  16 bytes : ");
50        fprintf(stderr, "%hx:", ntohl(rdPtr->value->stor.tabAdd6[0])>>16);
51        fprintf(stderr, "%hx:", ntohl(rdPtr->value->stor.tabAdd6[0])<<16>>16);
52        fprintf(stderr, "%hx:", ntohl(rdPtr->value->stor.tabAdd6[1])>>16);
53        fprintf(stderr, "%hx:", ntohl(rdPtr->value->stor.tabAdd6[1])<<16>>16);
54        fprintf(stderr, "%hx:", ntohl(rdPtr->value->stor.tabAdd6[2])>>16);
55        fprintf(stderr, "%hx:", ntohl(rdPtr->value->stor.tabAdd6[2])<<16>>16);
56        fprintf(stderr, "%hx:", ntohl(rdPtr->value->stor.tabAdd6[3])>>16);
57        fprintf(stderr, "%hx\n", ntohl(rdPtr->value->stor.tabAdd6[3])<<16>>16);
58        break;
59      default:
60        fprintf(stderr,"  no check\n");
61        break;
62      }
63    } else {
64      fprintf(stderr,"  no check\n");
65    }
66    printRuleDef(rdPtr->next);
67  }
68}
69
70void 
71printRule(RulesPtr rPtr)
72{
73  if (rPtr!=NULL){
74    fprintf(stderr, "\nid: %hu\n", rPtr->id);
75    if (rPtr->prev) { fprintf(stderr, "\nid prev: %hu\n", rPtr->prev->id);}
76    if (rPtr->next) { fprintf(stderr, "\nid next: %hu\n", rPtr->next->id);}
77    fprintf(stderr, "Name: %s\n", rPtr->ruleName);   
78/*     puts (asctime (& rPtr->begin)); */
79/*     puts (asctime (& rPtr->end)); */
80    printRuleDef(rPtr->def);
81    if (rPtr->host){
82      printHostDef(rPtr->host);
83    }
84/*     invPrintFieldSet(rPtr->fieldToRecord); */
85    printRule(rPtr->next);
86  }
87}
88
89/*
90 *
91 */
92unsigned short
93getNewId(RulesPtr rPtr){
94  RulesPtr tmp = rPtr;
95  unsigned short ctr = 0;
96
97  while (tmp){
98    if (tmp->id > ctr){
99      ctr = tmp->id;
100    }
101    tmp = tmp->next;
102  }
103  return ctr+1;
104}
105
106void 
107freeValue(ValuesPtr vPtr)
108{
109  free(vPtr);
110  vPtr = NULL;
111}
112
113void
114freeRuleDef(RuleDefPtr rdPtr)
115{
116  RuleDefPtr tmp;
117  if (rdPtr) {
118    tmp = rdPtr->next;
119    freeValue(rdPtr->value);
120    free(rdPtr);
121    rdPtr = NULL;
122    freeRuleDef(tmp);
123  }
124}
125
126void
127freeRule(RulesPtr rPtr)
128{
129  if (rPtr->def) {freeRuleDef(rPtr->def);}
130  if (rPtr->fieldToRecord) {freeField(rPtr->fieldToRecord);}
131  if (rPtr->host) {freeRemoteHost(rPtr->host);}
132  if (rPtr->fileName) {freeFile(rPtr->fileName);}
133  if (rPtr->db) {freeDb(rPtr->db);}
134  free(rPtr);
135  rPtr = NULL;
136}
137
138RulesPtr
139delRule(RulesPtr rPtr, RulesPtr firstrPtr)
140{
141  RulesPtr tmp = NULL;
142  if (rPtr==firstrPtr) {
143    if (rPtr->next) {
144      tmp = rPtr->next;
145      tmp->prev = NULL;
146      freeRule(rPtr);
147      return tmp;
148    }else{
149      freeRule(rPtr);
150      return NULL;
151    }
152  } else {
153    if (rPtr->prev->next) { rPtr->prev->next = rPtr->next;}
154    if (rPtr->next) {rPtr->next->prev = rPtr->prev;}
155    freeRule(rPtr);
156    return firstrPtr;
157  }
158}
159
160RulesPtr
161getRules(RulesPtr rPtr, char *filename)
162{
163  FILE *ruleFile;
164  RulesPtr tmp = NULL;
165  RulesPtr tmp2 = NULL;
166  time_t hour;
167  char line[512];
168  char lineCopy[512];
169  char str1[256];
170  char str2[256];
171  char strTok[1];
172  char strName[100];
173  char strOutputType[20];
174  int cptLine;
175 
176  if ((ruleFile = fopen(filename, "r")) == NULL) {
177    syslog(LOG_ERR, "error during %s opening\n", filename);
178    exit(1);
179  }
180  cptLine=0;
181  time (& hour);
182  /*    tmp->begin = localtime (& hour); */
183  /*    tmp->end = localtime (& hour); */
184  /*     strptime( begin, "%Y%m%d%H%M%S", & tmp->begin); */
185  /*     strptime( end, "%Y%m%d%H%M%S", & tmp->end); */
186  while ( fgets(line, 512, ruleFile) != 0) {   
187    if ( strspn(line, "#") == 0 ) {
188      strcpy(lineCopy, line);
189      if (strncmp("N", lineCopy, 1) == 0){
190        if (sscanf(line, "%1s %s\n",
191                   strTok,       
192                   strName) == 0) {
193          syslog(LOG_ERR, "Error in file %s, line %d\n",
194                  filename, cptLine);
195          exit(1);
196        } else {
197          rPtr = tmp;
198          tmp = NULL;
199          tmp = (RulesPtr) malloc(sizeof(struct Rules));
200          if (tmp==NULL) {
201            syslog(LOG_ERR, "ERROR in malloc in getRule function\n");
202            exit(1);
203          } else {
204            tmp->id = getNewId(rPtr);
205            tmp->def = NULL;
206            tmp->fieldToRecord = NULL;
207            tmp->host = NULL;
208            tmp->fileName = NULL;
209            tmp->db = NULL;
210            tmp->next = rPtr;
211            /* rPtr->prev = tmp; */
212            tmp->prev = NULL;
213          }
214          tmp->ruleName = (char *) malloc((strlen(strName)+1)*sizeof(char));
215          strcpy(tmp->ruleName, strName);
216        }
217      }
218      if (strncmp("O", lineCopy, 1) == 0){
219        if (sscanf(line, "%1s %s %s %s\n",
220                   strTok,       
221                   strOutputType,
222                   str1,
223                   str2) == 0) {
224          syslog(LOG_ERR, "Error in file %s, line %d\n",
225                  filename, cptLine);
226          exit(1);
227        } else {
228          /* switch output type */
229          if (strcmp("file", strOutputType) == 0){
230            tmp->type = 1;
231            tmp->fileName = addFileDef(tmp->fileName, str1, str2);
232          }
233          if (strcmp("socket", strOutputType) == 0){
234            tmp->type = 2;
235            tmp->host = addRemoteHostDef(tmp->host, str1, str2);
236          }
237          if (strcmp("base", strOutputType) == 0){
238            tmp->type = 3;
239            tmp->db = addDataBase(tmp->db, str1, str2);
240          }
241        }
242      }
243      if (strncmp("C", lineCopy, 1) == 0){
244        tmp->def = addRuleDef(tmp->def, lineCopy);
245      }
246      if (strncmp("A", lineCopy, 1) == 0){
247        syslog(LOG_INFO,"Aggregation mode isn't yet implemented\n");
248      }
249      if (strncmp("R", lineCopy, 1) == 0){
250        tmp->fieldToRecord = addFields(tmp->fieldToRecord, lineCopy);
251      }
252      cptLine++;
253    }
254    /*     tmp->prev = NULL; */
255  }
256  tmp2 = tmp;
257  for ( ; tmp2; tmp2=tmp2->next) {
258    if (tmp2->next) {
259      tmp2->next->prev = tmp2;
260    }
261  }
262  fclose(ruleFile);
263  return tmp;
264}
265
266RulesPtr
267getLightRules(RulesPtr rPtr, char *filename)
268{
269  FILE *ruleFile;
270  RulesPtr tmp = NULL;
271  RulesPtr tmp2 = NULL;
272  time_t hour;
273  char line[512];
274  char lineCopy[512];
275  char str1[256];
276  char str2[256];
277  char strTok[1];
278  char strName[100];
279  char strOutputType[20];
280  int cptLine;
281 
282  if (!(ruleFile = fopen(filename, "r"))) {
283    syslog(LOG_ERR, "error during %s opening\n", filename);
284    exit(1);
285  }
286  cptLine=0;
287  time (& hour);
288  /*    tmp->begin = localtime (& hour); */
289  /*    tmp->end = localtime (& hour); */
290  /*     strptime( begin, "%Y%m%d%H%M%S", & tmp->begin); */
291  /*     strptime( end, "%Y%m%d%H%M%S", & tmp->end); */
292  while ( fgets(line, 512, ruleFile) != 0) {   
293    if ( strspn(line, "#") == 0 ) {
294      strcpy(lineCopy, line);
295      if (strncmp("N", lineCopy, 1) == 0){
296        if (sscanf(line, "%1s %s\n",
297                   strTok,       
298                   strName) == 0) {
299          syslog(LOG_ERR, "Error in file %s, line %d\n",
300                  filename, cptLine);
301          exit(1);
302        } else {
303          rPtr = tmp;
304          tmp = NULL;
305          tmp = (RulesPtr) malloc(sizeof(struct Rules));
306          if (tmp==NULL) {
307            syslog(LOG_ERR, "ERROR in malloc in getRule function\n");
308            exit(1);
309          } else {
310            tmp->id = getNewId(rPtr);
311            tmp->def = NULL;
312            tmp->fieldToRecord = NULL;
313            tmp->host = NULL;
314            tmp->fileName = NULL;
315            tmp->db = NULL;
316            tmp->next = rPtr;
317            tmp->prev = NULL;
318          }
319          tmp->ruleName = (char *) malloc((strlen(strName)+1)*sizeof(char));
320          strcpy(tmp->ruleName, strName);
321        }
322      }
323      if (strncmp("O", lineCopy, 1) == 0){
324        if (sscanf(line, "%1s %s %s %s\n",
325                   strTok,       
326                   strOutputType,
327                   str1,
328                   str2) == 0) {
329          syslog(LOG_ERR, "Error in file %s, line %d\n",
330                  filename, cptLine);
331          exit(1);
332        } else {
333          /* switch output type */
334          if (strcmp("file", strOutputType) == 0){
335            tmp->type = 1;
336          }
337          if (strcmp("socket", strOutputType) == 0){
338            tmp->type = 2;
339          }
340          if (strcmp("base", strOutputType) == 0){
341            tmp->type = 3;
342          }
343        }
344      }
345      if (strncmp("C", lineCopy, 1) == 0){
346        tmp->def = addRuleDef(tmp->def, lineCopy);
347      }
348      if (strncmp("A", lineCopy, 1) == 0){
349        syslog(LOG_INFO,"Aggregation mode isn't yet implemented");
350      }
351      if (strncmp("R", lineCopy, 1) == 0){
352        tmp->fieldToRecord = addFields(tmp->fieldToRecord, lineCopy);
353      }
354      cptLine++;
355    }
356  }
357  tmp2 = tmp;
358  for ( ; tmp2; tmp2=tmp2->next) {
359    if (tmp2->next) {
360      tmp2->next->prev = tmp2;
361    }
362  }
363  fclose(ruleFile);
364  return tmp;
365}
366
367FilePtr
368addFileDef(FilePtr fPtr, char *str1, char *str2)
369{
370/*   fprintf(stderr,"add file def: %s %s \n", str1, str2); */
371  return NULL;
372}
373
374RemoteHostPtr
375addRemoteHostDef(RemoteHostPtr rPtr, char *str1, char *str2)
376{
377  RemoteHostPtr tmp = NULL;
378  tmp = (RemoteHostPtr) malloc(sizeof(struct RemoteHost));
379  if (tmp==NULL) {
380    syslog(LOG_ERR, "ERROR in malloc in addRemoteHostDef function");
381    exit(1);
382  } else {
383    tmp->hostAddressPtr = (struct sockaddr_storage*)
384      malloc(sizeof(struct sockaddr_storage));
385    if (tmp->hostAddressPtr==NULL) {
386      syslog(LOG_ERR, "ERROR in malloc in addRemoteHostDef function");
387      exit(1);
388    } else {
389      if ((tmp->sockId=create_socket( str1, str2, tmp->hostAddressPtr))==0)
390        return NULL;
391      tmp->next = rPtr;
392    }
393  }
394  return tmp;
395}
396
397DbPtr
398addDataBase(DbPtr dPtr, char *str1, char *str2){
399  syslog(LOG_INFO,"DB output not in this release");
400  return NULL;
401}
402
403FieldPtr
404addFields (FieldPtr fp, char *ftr)
405{
406  /* for each token "R" in the tests string */
407  /* build a field structure */
408  /* return a list of field */
409  static char * fields;
410  fields = strtok(ftr, "R");
411  while (fields != NULL) {
412    unsigned short type;
413    unsigned short length;
414    if (sscanf(fields, " %hu %hu ", &type, &length) == 0) {
415      syslog(LOG_ERR,
416              "Errors in definition of fields to record: wrong syntax");
417      exit(1);
418    } else {
419      if (type == 0){
420        return NULL; /* all fields must be recorded */
421      } else {
422        fp = addField(fp, type, length);
423      }
424    }
425    fields = strtok(NULL, "R");   
426  }
427  return fp;
428}
429
430RuleDefPtr
431addRuleDef(RuleDefPtr rdPtr, char *tests)
432{
433  /* for each token "C" in the tests string */
434  /* build a rule_def struct */
435  /* return the list of rule_def */
436  RuleDefPtr tmp = NULL;
437  static char * fields;
438  unsigned short operatorToNumber = 0;
439
440  fields = strtok(tests, "C");
441  while (fields != NULL) {
442    static unsigned short ft;
443    char operator[2];
444    char value[42];
445    tmp = (RuleDefPtr) malloc(sizeof(struct RuleDef));
446    if (tmp==NULL) {
447      syslog(LOG_ERR, "ERROR in malloc in addRuleDef function");
448      exit(1);
449    } else {
450      if (sscanf(fields, " %hu %1s %s", &ft, operator, value)==0) {
451        syslog(LOG_ERR, "Errors in Tests definition : wrong syntax");
452        exit(1);
453      }
454      /* operator possibilities : > < = b t (belong, table) */
455      if (strcmp(operator,">")==0) {
456        operatorToNumber = 0; /* FIXME why operatorToNumber ? */
457        tmp->operator = 0;
458      }
459      if (strcmp(operator,"<")==0) {
460        operatorToNumber = 1;
461        tmp->operator = 1;
462      }
463      if (strcmp(operator,"=")==0) {
464        operatorToNumber = 2;
465        tmp->operator = 2;
466      }
467      tmp->fieldType = ft;
468      tmp->value = NULL;
469      if ((ft==1) || (ft==25)){
470          tmp->value = addValue(tmp->value, operatorToNumber, value);
471      } else if ( (ft==0) || (ft==8) || (ft==12) || (ft==15) || (ft==18) ){
472          tmp->value = addAddress(tmp->value, operatorToNumber, value);
473      } else if ( (ft==27) || (ft==28) || (ft==62) || (ft==63) ){
474          tmp->value = addV6Address(tmp->value, operatorToNumber, value);
475      } else if ( (ft==60) || (ft==46) ){
476          tmp->value = addCValue(tmp->value, operatorToNumber, value);
477      } else {
478        syslog(LOG_INFO,
479                "You can't compare the field <%hu> in this release, sorry",
480                ft);
481      }
482      tmp->check = 0;
483      tmp->next = rdPtr;
484      if (rdPtr!=NULL) { rdPtr->prev = tmp;}
485      tmp->prev = NULL;
486      rdPtr=tmp;
487    }
488    fields = strtok(NULL, "C");
489  }
490  return tmp;
491}
492
493ValuesPtr
494addAddress(ValuesPtr vPtr, unsigned short op, char *val)
495{
496  ValuesPtr tmp;
497  unsigned short v0, v1, v2, v3;
498  unsigned char buffer4[4];
499  static char *token;
500  static char mask[4];
501  int lg = 0;
502  int lgMask = 0;
503  static char value[16];
504  tmp = (ValuesPtr) malloc(sizeof(struct Values));
505  if (tmp==NULL) {
506    syslog(LOG_ERR, "ERROR in malloc in addAddress function");
507    exit(1);
508  } else {
509    if ( (token=memccpy(value, val, '/', strlen(val)))==NULL) {
510      /* address case */
511      if (sscanf(value, "%hu.%hu.%hu.%hu", &v0, &v1, &v2, &v3) == 0) {
512        syslog(LOG_ERR, "Errors in Tests definition : wrong IPv4 value");
513        exit(1);
514      }
515      buffer4[3] = (unsigned char)v0;
516      buffer4[2] = (unsigned char)v1;
517      buffer4[1] = (unsigned char)v2;
518      buffer4[0] = (unsigned char)v3;   
519      tmp->valueLength = 4;
520      tmp->mask = 32;
521      tmp->stor.lvalue = *((unsigned long*)(&buffer4));
522      tmp->mask = 32;
523      tmp->next = vPtr;
524    } else {
525      lg = strlen(value);
526      lgMask = strlen(token);
527      value[lg-1-lgMask] = '\0';
528      strcpy( mask, strchr(val,'/')+1);
529      if (sscanf(value, "%hu.%hu.%hu.%hu", &v0, &v1, &v2, &v3) == 0) {
530        syslog(LOG_ERR, "Errors in Tests definition : wrong IPv4 value");
531        exit(1);
532      }
533      buffer4[3] = (unsigned char)v0;
534      buffer4[2] = (unsigned char)v1;
535      buffer4[1] = (unsigned char)v2;
536      buffer4[0] = (unsigned char)v3;   
537      tmp->valueLength = 4;
538      tmp->mask = atoi(mask);
539      tmp->stor.lvalue = *((unsigned long*)(&buffer4));
540      tmp->next = vPtr;     
541    }
542  }
543  return tmp;
544}
545
546ValuesPtr
547addV6Address(ValuesPtr vPtr, unsigned short op, char *val)
548{
549  ValuesPtr tmp;
550  struct in6_addr v6addr;
551  char netw_form[16];
552  int result;
553  static char value[30];
554  static char mask[4];
555  static char *token;
556  int lg = 0;
557  int lgMask = 0;
558  tmp = (ValuesPtr) malloc(sizeof(struct Values));
559  if (tmp==NULL) {
560    syslog(LOG_ERR, "ERROR in malloc in addV6Address function");
561    exit(1);
562  } else {
563    if ( (token=memccpy(value, val, '/', strlen(val)))==NULL) {
564      /* address case */
565      result = inet_pton(AF_INET6, val, netw_form);
566      switch(result) {
567      case 0 :
568        syslog(LOG_ERR," inet_pton : Invalid IPv6 Address");
569        exit(1);
570        break;
571      case -1:
572        syslog(LOG_ERR," inet_pton : AF unknown");
573        exit(1);
574        break;
575      }
576      memcpy(&v6addr, netw_form, sizeof(netw_form));
577      tmp->valueLength = 16;
578      tmp->mask = 128;
579      tmp->stor.tabAdd6[0] = v6addr.s6_addr32[0];
580      tmp->stor.tabAdd6[1] = v6addr.s6_addr32[1];
581      tmp->stor.tabAdd6[2] = v6addr.s6_addr32[2];
582      tmp->stor.tabAdd6[3] = v6addr.s6_addr32[3];
583      tmp->next = vPtr;
584    } else {
585      lg = strlen(value);
586      lgMask = strlen(token);
587      value[lg-1-lgMask] = '\0';
588      strcpy( mask, strchr(val,'/')+1);
589      result = inet_pton(AF_INET6, value, netw_form);
590      switch(result) {
591      case 0 :
592        syslog(LOG_ERR," inet_pton : Invalid IPv6 Address");
593        exit(1);
594        break;
595      case -1:
596        syslog(LOG_ERR," inet_pton : AF unknown");
597        exit(1);
598        break;
599      }
600      memcpy(&v6addr, netw_form, sizeof(netw_form));
601      tmp->valueLength = 16;
602      tmp->mask = atoi(mask);
603      tmp->stor.tabAdd6[0] = v6addr.s6_addr32[0];
604      tmp->stor.tabAdd6[1] = v6addr.s6_addr32[1];
605      tmp->stor.tabAdd6[2] = v6addr.s6_addr32[2];
606      tmp->stor.tabAdd6[3] = v6addr.s6_addr32[3];
607      tmp->next = vPtr;
608    }
609  }
610  return tmp;
611}
612
613ValuesPtr
614addValue(ValuesPtr vPtr, unsigned short op, char *val)
615{
616  ValuesPtr tmp;
617  char value[10];
618
619  tmp = (ValuesPtr) malloc(sizeof(struct Values));
620  if (tmp==NULL) {
621    syslog(LOG_ERR, "ERROR in malloc in addValue function");
622    exit(1);
623  } else {
624    if (sscanf(val, "%s", value) == 0) {
625      syslog(LOG_ERR, "Errors in Tests definition : wrong short value");
626      exit(1);
627    }   
628    tmp->valueLength = 2;
629    tmp->stor.svalue = (unsigned short) atoi(value);
630    tmp->next = vPtr;
631  }
632  return tmp;
633}
634
635ValuesPtr
636addCValue(ValuesPtr vPtr, unsigned short op, char *val)
637{
638  ValuesPtr tmp;
639  char value[10];
640
641  tmp = (ValuesPtr) malloc(sizeof(struct Values));
642  if (tmp==NULL) {
643    syslog(LOG_ERR, "ERROR in malloc in addValue function");
644    exit(1);
645  } else {
646    if (sscanf(val, "%s", value) == 0) {
647      syslog(LOG_ERR, "Errors in Tests definition : wrong char value");
648      exit(1);
649    }   
650    tmp->valueLength = 1;
651    tmp->stor.cvalue = (unsigned short) atoi(value);
652    tmp->next = vPtr;
653  }
654  return tmp;
655}
Note: See TracBrowser for help on using the browser.