00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef CLAMAV
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #ifdef HAVE_CONFIG_H
00056 #include "config.h"
00057 #endif
00058
00059 #ifndef DEBUG
00060 #ifndef INLINE
00061 #define INLINE inline
00062 #endif
00063 #else
00064 #ifdef INLINE
00065 #undef INLINE
00066 #endif
00067 #define INLINE
00068 #endif
00069
00070 #include <sys/types.h>
00071 #include <stdlib.h>
00072 #include <ctype.h>
00073 #include <rpc/types.h>
00074 #include <errno.h>
00075 #include "generators.h"
00076 #include "event_wrapper.h"
00077 #include "util.h"
00078 #include "plugbase.h"
00079 #include "parser.h"
00080 #include "decode.h"
00081 #include "debug.h"
00082 #include "mstring.h"
00083 #include "log.h"
00084 #include "spp_clamav.h"
00085 #include "stream.h"
00086 #include "preprocessors/spp_stream4.h"
00087 #ifdef GIDS
00088 #include "preprocessors/spp_stickydrop.h"
00089 #include "inline.h"
00090 #endif
00091
00092 #include "snort.h"
00093 #include <clamav.h>
00094
00095 #ifdef HAVE_STRINGS_H
00096 #include <strings.h>
00097 #endif
00098
00099 #ifdef GIDS
00100
00101 extern SDtimeout sdt;
00102 extern Stream4Data s4data;
00103 #endif
00104
00105
00106
00107 #define xstr(s) str(s)
00108 #define str(s) #s
00109
00110
00111 struct ClamAVConfig
00112 {
00113
00114 char toclientonly;
00115 char toserveronly;
00116 char VirusScanPorts[65536/8];
00117
00118
00119 char drop;
00120 char reset;
00121 char rboth;
00122
00123
00124 char dbdir[255];
00125
00126
00127 char desctmpdir[255];
00128
00129
00130 u_int16_t reloadtime;
00131 u_int32_t next_reload_time;
00132
00133 } clamcnf;
00134
00135
00136 struct cl_node *cl_root;
00137
00138 struct cl_limits clam_limits;
00139 static void ClamAVInit(u_char *);
00140 extern void SetupClamAV();
00141 static int VirusInPacket(Packet *);
00142 int check_4_http_headers(u_int8_t *, int);
00143 static void VirusChecker(Packet *, void *);
00144 extern u_int32_t event_id;
00145
00146
00147 struct cl_stat dbstat;
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 void SetupClamAV()
00161 {
00162 RegisterPreprocessor("ClamAV", ClamAVInit);
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 static void ProcessPorts(u_char *portlist)
00177 {
00178 int j = 0;
00179 int i = 0;
00180 char **ports;
00181 int num_ports;
00182 char *port;
00183 u_int32_t portnum;
00184
00185
00186 bzero(&clamcnf.VirusScanPorts, sizeof(clamcnf.VirusScanPorts));
00187
00188 ports = mSplit(portlist, " ", 40, &num_ports, 0);
00189
00190
00191 for(j = 0; j < num_ports; j++)
00192 {
00193 port = ports[j];
00194
00195
00196 if(isdigit((int)port[0]))
00197 {
00198 portnum = atoi(port);
00199 if(portnum > 65535)
00200 {
00201 FatalError("%s(%d) => Bad port list to scan: "
00202 "port '%d' out of range\n", portnum, file_name, file_line);
00203 }
00204
00205
00206
00207
00208 clamcnf.VirusScanPorts[(portnum/8)] |= 1<<(portnum%8);
00209 }
00210
00211 else if(port[0] == '!')
00212 {
00213 for(i = 0; i < strlen(port) && port[i+1] != '\0'; i++)
00214 {
00215 port[i] = port[i+1];
00216 }
00217 port[i] = '\0';
00218
00219 if(isdigit((int)port[0]))
00220 {
00221 portnum = atoi(port);
00222 if(portnum > 65535)
00223 {
00224 FatalError("%s(%d) => Bad port list to scan: "
00225 "port '%d' out of range\n", portnum, file_name, file_line);
00226 }
00227
00228
00229 clamcnf.VirusScanPorts[(portnum/8)] &= ~(1<<(portnum%8));
00230 }
00231 else
00232 {
00233 FatalError("%s(%d) => Bad port list to scan: "
00234 "bad port\n", file_name, file_line);
00235 }
00236 }
00237
00238 else if(!strncasecmp(port, "all", 3))
00239 {
00240
00241 for(portnum = 0; portnum <= 65535; portnum++)
00242 clamcnf.VirusScanPorts[(portnum/8)] |= 1<<(portnum%8);
00243 }
00244 else if(!strncasecmp(port, "ports", 5));
00245 else
00246 {
00247 FatalError("%s(%d) => Bad port list to scan: "
00248 "bad port\n", file_name, file_line);
00249 }
00250 }
00251
00252 mSplitFree(&ports, num_ports);
00253
00254
00255 if(!pv.quiet_flag)
00256 {
00257
00258 LogMessage(" Ports: ");
00259
00260 for(portnum = 0, j = 0; portnum <= 65535; portnum++)
00261 {
00262 if((clamcnf.VirusScanPorts[(portnum/8)] & (1<<(portnum%8))))
00263 {
00264 LogMessage("%d ", portnum);
00265 j++;
00266 }
00267
00268 if(j > 20)
00269 {
00270 LogMessage("...\n");
00271 return;
00272 }
00273 }
00274 }
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 void ParseClamAVArgs(u_char *args)
00288 {
00289 char **toks;
00290 int num_toks;
00291 int i = 0;
00292 char *index;
00293 int ports_done = 0;
00294 char **dbdirtoks;
00295 int num_dbdirtoks = 0;
00296 char **dbtimetoks;
00297 int num_dbtimetoks = 0;
00298 char **desctmptoks;
00299 int num_desctmptoks = 0;
00300
00301
00302
00303 u_char *default_ports = "21 25 80 81 110 119 139 445 143 8080";
00304
00305 #ifdef GIDS
00306 clamcnf.drop = 0;
00307 clamcnf.reset = 0;
00308 clamcnf.rboth = 0;
00309 #endif
00310 clamcnf.toclientonly = 0;
00311 clamcnf.toserveronly = 0;
00312
00313
00314 if(strlcpy(clamcnf.desctmpdir, "/tmp", sizeof(clamcnf.desctmpdir)) >= sizeof(clamcnf.desctmpdir))
00315 {
00316 FatalError("The tempdir supplied at compile time is too long\n");
00317 }
00318
00319 #ifdef CLAMAV_DEFDIR
00320
00321 if(strlcpy(clamcnf.dbdir, xstr(CLAMAV_DEFDIR), sizeof(clamcnf.dbdir)) >= sizeof(clamcnf.dbdir))
00322 #else
00323
00324 if(strlcpy(clamcnf.dbdir, "/var/lib/clamav/", sizeof(clamcnf.dbdir)) >= sizeof(clamcnf.dbdir))
00325 #endif
00326 {
00327 FatalError("The defdir supplied at compile time is too long\n");
00328 }
00329
00330
00331
00332 clamcnf.reloadtime = 600;
00333
00334
00335 if(!pv.quiet_flag)
00336 {
00337 LogMessage("ClamAV config:\n");
00338 }
00339
00340
00341
00342 if(args == NULL)
00343 {
00344 if(!pv.quiet_flag)
00345 {
00346 LogMessage(" no options, using defaults.\n");
00347 }
00348 }
00349
00350 else
00351 {
00352 toks = mSplit(args, ",", 12, &num_toks, 0);
00353
00354 for(i = 0; i < num_toks; i++)
00355 {
00356 index = toks[i];
00357 while(isspace((int)*index)) index++;
00358
00359 if(!strncasecmp(index, "ports", 5))
00360 {
00361 ProcessPorts(toks[i]);
00362 ports_done = 1;
00363 }
00364 #ifdef GIDS
00365 else if(!strncasecmp(index, "action-reset", 12))
00366 {
00367 clamcnf.reset = 1;
00368 }
00369 else if(!strncasecmp(index, "action-rboth", 12))
00370 {
00371 clamcnf.rboth = 1;
00372 }
00373 else if(!strncasecmp(index, "action-drop", 11))
00374 {
00375 clamcnf.drop = 1;
00376 }
00377 #endif
00378 else if(!strncasecmp(index, "toclientonly", 12))
00379 {
00380 clamcnf.toclientonly = 1;
00381 }
00382 else if(!strncasecmp(index, "toserveronly", 12))
00383 {
00384 clamcnf.toserveronly = 1;
00385 }
00386 else if(!strncasecmp(index, "dbdir", 5))
00387 {
00388
00389 dbdirtoks = mSplit(index, " ", 1, &num_dbdirtoks, 0);
00390
00391
00392 if(strlcpy(clamcnf.dbdir, dbdirtoks[1], sizeof(clamcnf.dbdir)) >= sizeof(clamcnf.dbdir))
00393 {
00394 FatalError("The defdir supplied in the config is too long\n");
00395 }
00396 mSplitFree(&dbdirtoks, num_dbdirtoks);
00397 }
00398 else if(!strncasecmp(index, "dbreload-time", 13))
00399 {
00400
00401 dbtimetoks = mSplit(index, " ", 1, &num_dbtimetoks, 0);
00402
00403 if(isdigit((int)dbtimetoks[1][0]))
00404 {
00405 clamcnf.reloadtime = atoi(dbtimetoks[1]);
00406 }
00407 else
00408 {
00409 FatalError("We need an integer in seconds for dbreload interval\n");
00410 }
00411 mSplitFree(&dbtimetoks, num_dbtimetoks);
00412 }
00413 else if((!strncasecmp(index, "descriptor-temp-dir", 19)))
00414 {
00415
00416 desctmptoks = mSplit(index, " ", 1, &num_desctmptoks, 0);
00417
00418
00419 if(strlcpy(clamcnf.desctmpdir, desctmptoks[1], sizeof(clamcnf.desctmpdir)) >= sizeof(clamcnf.desctmpdir))
00420 {
00421 FatalError("The tmpdir supplied in the config is too long\n");
00422 }
00423 mSplitFree(&desctmptoks, num_desctmptoks);
00424 }
00425 else
00426 {
00427 FatalError("%s(%d) => Bad ClamAV option specified: "
00428 "\"%s\"\n", file_name, file_line, toks[i]);
00429 }
00430 }
00431
00432 mSplitFree(&toks, num_toks);
00433 }
00434
00435 #ifdef GIDS
00436
00437 if(clamcnf.drop && clamcnf.reset)
00438 {
00439 FatalError("Can't set action-drop and action-reset together!\n");
00440 }
00441 #endif
00442 if(clamcnf.toclientonly && clamcnf.toserveronly)
00443 {
00444 FatalError("Can't set toclientonly and toserveronly together!\n");
00445 }
00446
00447
00448
00449 if(!ports_done)
00450 ProcessPorts(default_ports);
00451
00452
00453
00454 if(!pv.quiet_flag)
00455 {
00456
00457 #ifdef GIDS
00458 if(clamcnf.drop == 1)
00459 LogMessage(" Virus found action: DROP\n");
00460 else if(clamcnf.reset == 1)
00461 LogMessage(" Virus found action: RESET\n");
00462 else if(clamcnf.rboth == 1)
00463 LogMessage(" Virus found action: RESET-BOTH\n");
00464 else
00465 LogMessage(" Virus found action: ALERT\n");
00466 #endif
00467
00468 LogMessage(" Virus definitions dir: '%s'\n", clamcnf.dbdir);
00469
00470 LogMessage(" Virus DB reload time: '%i'\n", clamcnf.reloadtime);
00471 if(clamcnf.toclientonly == 1)
00472 LogMessage(" Scan only traffic to the client\n");
00473 else if(clamcnf.toserveronly == 1)
00474 LogMessage(" Scan only traffic to the server\n");
00475 LogMessage(" Directory for tempfiles (file descriptor mode): '%s'\n",
00476 clamcnf.desctmpdir);
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485
00486 void ClamAVInit(u_char *args)
00487 {
00488 int ret = 0;
00489 int n = 0;
00490 struct timeval t;
00491 cl_root = NULL;
00492
00493
00494 ParseClamAVArgs(args);
00495
00496
00497
00498 memset(&t, 0, sizeof(struct timeval));
00499 gettimeofday(&t, NULL);
00500 clamcnf.next_reload_time = t.tv_sec + clamcnf.reloadtime;
00501
00502
00503 memset(&dbstat, 0, sizeof(struct cl_stat));
00504 cl_statinidir(clamcnf.dbdir, &dbstat);
00505
00506
00507 ret = cl_loaddbdir(clamcnf.dbdir, &cl_root, &n);
00508 if(ret != 0)
00509 {
00510 FatalError("ClamAV: cl_loaddbdir() %s\n", cl_strerror(ret));
00511 }
00512
00513
00514 #ifdef CLAMAV_HAVE_CL_BUILD
00515 if((ret = cl_build(cl_root)))
00516 #else
00517 if((ret = cl_buildtrie(cl_root)))
00518 #endif
00519 {
00520 FatalError("ClamAV: cl_build() %s\n", cl_strerror(ret));
00521 }
00522
00523
00524 memset(&clam_limits, 0, sizeof(clam_limits));
00525 ;
00526 clam_limits.maxfiles = 1000;
00527
00528 clam_limits.maxfilesize = 10 * 1048576;
00529
00530 clam_limits.maxreclevel = 5;
00531
00532 clam_limits.maxratio = 200;
00533
00534 clam_limits.archivememlim = 0;
00535
00536
00537 AddFuncToPreprocList(VirusChecker);
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 static void ClamAVReloadDB(Packet *p)
00553 {
00554 int ret = 0;
00555 int n = 0;
00556
00557 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"going to Reload ClamAV Database\n"););
00558 clamcnf.next_reload_time = p->pkth->ts.tv_sec + clamcnf.reloadtime;
00559
00560
00561 if(cl_statchkdir(&dbstat) == 1)
00562 {
00563
00564 #ifdef CLAMAV_HAVE_CL_BUILD
00565 cl_free(cl_root);
00566 #else
00567 cl_freetrie(cl_root);
00568 #endif
00569 cl_root = NULL;
00570
00571
00572 ret = cl_loaddbdir(clamcnf.dbdir, &cl_root, &n);
00573 if(ret != 0)
00574 {
00575 FatalError("ClamAV: cl_loaddbdir() %s\n", cl_strerror(ret));
00576 }
00577
00578
00579 #ifdef CLAMAV_HAVE_CL_BUILD
00580 if((ret = cl_build(cl_root)))
00581 #else
00582 if((ret = cl_buildtrie(cl_root)))
00583 #endif
00584 {
00585 FatalError("ClamAV: cl_build() %s\n", cl_strerror(ret));
00586 }
00587
00588 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"New ClamAV Database loaded\n"););
00589
00590
00591 cl_statfree(&dbstat);
00592
00593 memset(&dbstat, 0, sizeof(struct cl_stat));
00594 cl_statinidir(clamcnf.dbdir, &dbstat);
00595 }
00596 else
00597 {
00598 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"Database is up2date\n"););
00599 }
00600
00601 return;
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 int
00625 strip_http_headers_p(Packet *p, u_int8_t **data, int *dsize)
00626 {
00627 u_int8_t *needle = NULL;
00628 int offset = 0;
00629 int tmpsize = 0;
00630 int chunked = 0;
00631 u_int8_t *newbuf = NULL;
00632
00633
00634 needle = p->data + 5;
00635
00636
00637 needle = strstr(needle, "Transfer-Encoding: chunked");
00638
00639 if(needle != NULL)
00640 {
00641
00642 chunked = 1;
00643 }
00644 else
00645 {
00646
00647 needle = p->data + 5;
00648 }
00649
00650 needle = strstr(needle, "\r\n\r\n");
00651 if(needle == NULL)
00652 {
00653 return 0;
00654 }
00655
00656 newbuf = needle + 4;
00657
00658 offset = newbuf - p->data;
00659
00660
00661 if(chunked)
00662 {
00663
00664 needle = needle + 4;
00665 needle = strstr(needle, "\r\n");
00666 if(needle == NULL)
00667 {
00668
00669 return 0;
00670 }
00671
00672 newbuf = needle + 2;
00673
00674
00675 offset = newbuf - p->data;
00676 }
00677
00678 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"p->data %p, needle %p, newbuf %p, offset %d, p->dsize %u\n",
00679 p->data, needle, newbuf, offset, p->dsize););
00680
00681
00682 if(offset >= p->dsize)
00683 return 0;
00684 if(offset < 0)
00685 return 0;
00686
00687 tmpsize = p->dsize - offset;
00688
00689 while(check_4_http_headers(newbuf,tmpsize))
00690 {
00691 needle = newbuf + 5;
00692
00693 needle = strstr(needle, "\r\n\r\n");
00694 if(needle == NULL)
00695 {
00696 return 0;
00697 }
00698
00699
00700 newbuf = needle + 4;
00701 offset = newbuf - p->data;
00702 tmpsize = p->dsize - offset;
00703 }
00704
00705
00706 if(offset >= p->dsize)
00707 return 0;
00708 if(offset < 0)
00709 return 0;
00710
00711
00712 *data = newbuf;
00713 *dsize = p->dsize - offset;
00714 return 1;
00715 }
00716
00717
00718 int
00719 check_4_http_headers(u_int8_t *buf, int dsize)
00720 {
00721 if((dsize > 5) &&
00722 (buf[0] == 'H' || buf[1] == 'T' ||
00723 buf[2] == 'T' || buf[3] == 'P'))
00724 {
00725
00726 return 1;
00727 }
00728
00729
00730 return 0;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 static INLINE int ScanPort(Packet *p)
00748 {
00749
00750 if(p->tcph)
00751 {
00752 if(p->packet_flags & PKT_FROM_SERVER && !clamcnf.toserveronly)
00753 {
00754
00755 if(!(clamcnf.VirusScanPorts[(p->sp/8)] & (1<<(p->sp%8))))
00756 return 0;
00757 else
00758 return 1;
00759 }
00760 else if(p->packet_flags & PKT_FROM_CLIENT && !clamcnf.toclientonly)
00761 {
00762
00763 if(!(clamcnf.VirusScanPorts[(p->dp/8)] & (1<<(p->dp%8))))
00764 return 0;
00765 else
00766 return 1;
00767 }
00768 else
00769 {
00770
00771
00772 return 0;
00773 }
00774 }
00775
00776
00777 else if(!(clamcnf.VirusScanPorts[(p->dp/8)] & (1<<(p->dp%8))) &&
00778 !(clamcnf.VirusScanPorts[(p->sp/8)] & (1<<(p->sp%8))))
00779 {
00780 return 0;
00781 }
00782 else
00783 {
00784 return 1;
00785 }
00786 }
00787
00788
00789 static ssize_t writepacket(int fd, const void *pbuffer, size_t psize)
00790 {
00791 ssize_t pdwritten = 0, pd;
00792
00793 do {
00794 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"we have written %i of %i bytes in writepacket loop\n",pdwritten,psize););
00795
00796 if((pd = write(fd, &((const char *)pbuffer)[pdwritten], psize - pdwritten)) == -1)
00797 {
00798 if(errno == EINTR)
00799 {
00800 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"we wrote %i of %i bytes to disk and got a signal interrupt looping\n",pdwritten,psize););
00801 }
00802 else
00803 {
00804 return -1;
00805 }
00806 }
00807 pdwritten += pd;
00808
00809 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"we have written %i of %i bytes in writepacket loop\n",pdwritten,psize););
00810 } while (pdwritten < psize);
00811
00812 return pdwritten;
00813 }
00814
00815
00816
00817
00818
00819
00820 static INLINE int StoreAndScan(Packet *p)
00821 {
00822 int fd = 0;
00823 char tempfilename[256]="";
00824 size_t size = 0;
00825 int ret = 0, retval = 0;
00826 Event event;
00827 char outstring[255];
00828 const char *cl_virusname = NULL;
00829 u_int8_t *buf = p->data;
00830 int dsize = p->dsize;
00831
00832
00833 size = snprintf(tempfilename, sizeof(tempfilename), "%s/snort_inline-clamav-XXXXXX", clamcnf.desctmpdir);
00834 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"tempfilename is %s\n",tempfilename););
00835 if(size >= sizeof(tempfilename))
00836 {
00837 FatalError("buffer too small");
00838 }
00839 fd = mkstemp(tempfilename);
00840 if(fd == -1)
00841 {
00842 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"mkstemp error: %s.\n", strerror(errno)););
00843 return 1;
00844 }
00845
00846
00847
00848 if(check_4_http_headers(buf,dsize))
00849 {
00850 if(strip_http_headers_p(p, &buf, &dsize))
00851 {
00852
00853 }
00854 }
00855
00856
00857 ret = writepacket(fd, buf, dsize);
00858 if(ret < dsize)
00859 {
00860 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"tmpfile too small\n"););
00861 }
00862
00863
00864 ret = cl_scandesc(fd, &cl_virusname, NULL, cl_root, &clam_limits, CL_SCAN_STDOPT);
00865 if(ret == CL_CLEAN)
00866 {
00867 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"Packet is clean\n"););
00868 }
00869 else if(ret == CL_VIRUS)
00870 {
00871 snprintf(outstring, sizeof(outstring), "%s %s", CLAMAV_VIRUSFOUND_STR, cl_virusname);
00872
00873 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"tempfile and or packet is infected: '%s'.\n", outstring););
00874
00875
00876 SetEvent(&event, GENERATOR_SPP_CLAMAV, CLAMAV_VIRUSFOUND, 1, 0, 0, 0);
00877 CallAlertFuncs(p, outstring, NULL, &event);
00878 CallLogFuncs(p, outstring, NULL, &event);
00879 retval = 1;
00880 }
00881 else
00882 {
00883
00884 if(ret < 0)
00885 {
00886
00887 close(fd);
00888
00889 unlink(tempfilename);
00890
00891 FatalError("ClamAV scan error: %s.\n", cl_strerror(ret));
00892 }
00893 else
00894
00895
00896
00897 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"ClamAV scan error: %s.\n", cl_strerror(ret)););
00898 }
00899
00900
00901 close(fd);
00902
00903 unlink(tempfilename);
00904
00905 return retval;
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 static int VirusInPacket(Packet *p)
00921 {
00922
00923 if(p->pkth->ts.tv_sec >= clamcnf.next_reload_time)
00924 {
00925 ClamAVReloadDB(p);
00926 }
00927
00928
00929
00930 if(p->dsize == 0)
00931 {
00932 return 0;
00933 }
00934
00935
00936
00937 if(!ScanPort(p))
00938 {
00939 return 0;
00940 }
00941
00942
00943
00944 if(!cl_root)
00945 {
00946 return 0;
00947 }
00948
00949
00950
00951 return(StoreAndScan(p));
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 static void VirusChecker(Packet *p, void *context)
00969 {
00970 if(VirusInPacket(p))
00971 {
00972 #ifdef GIDS
00973 if(clamcnf.reset)
00974 {
00975 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"ClamAV virus found sending Reject\n"););
00976 InlineReject(p);
00977 }
00978 else if(clamcnf.rboth)
00979 {
00980 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"ClamAV virus found sending Reject\n"););
00981 InlineRejectBoth(p);
00982 }
00983 else if(clamcnf.drop)
00984 {
00985 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"ClamAV virus found sending Drop\n"););
00986 InlineDrop();
00987 }
00988 else
00989 {
00990
00991
00992
00993 AlertFlushStream(p);
00994
00995
00996
00997 DisableDetect(p);
00998 }
00999 if((SppStickydIsRunning()) && sdt.clamav)
01000 {
01001 DEBUG_WRAP(DebugMessage(DEBUG_CLAMAV,"ClamAV adding ip to StickyDrop treei\n"););
01002 AddIpToBlockTree(p, 0, sdt.clamav);
01003 }
01004 #endif
01005 }
01006 return;
01007 }
01008
01009 #endif