Scan early if possible

git-svn: trunk@1948
remotes/push_mirror/metadata
Nigel Horne 20 years ago
parent 0f7f7682a1
commit a603478f5a
  1. 35
      clamav-devel/libclamav/blob.c
  2. 6
      clamav-devel/libclamav/blob.h
  3. 106
      clamav-devel/libclamav/mbox.c
  4. 25
      clamav-devel/libclamav/message.c
  5. 5
      clamav-devel/libclamav/message.h
  6. 27
      clamav-devel/libclamav/pst.c

@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
static char const rcsid[] = "$Id: blob.c,v 1.45 2006/05/03 09:36:40 nigelhorne Exp $";
static char const rcsid[] = "$Id: blob.c,v 1.46 2006/05/03 15:41:44 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -461,20 +461,17 @@ fileblobAddData(fileblob *fb, const unsigned char *data, size_t len)
assert(data != NULL);
if(fb->fp) {
#if 0
extern cli_ctx *current_ctx;
if(current_ctx) {
if(current_ctx->scanned)
*current_ctx->scanned += len / CL_COUNT_PRECISION;
if(cli_scanbuff((char *) data, len, current_ctx->virname, current_ctx->engine, 0) == CL_VIRUS) {
cli_dbgmsg("found %s\n", *current_ctx->virname);
/*ret = CL_VIRUS;
break;*/
if(fb->isInfected) /* pretend all was written */
return 0;
if(fb->ctx) {
if(fb->ctx->scanned)
*fb->ctx->scanned += len / CL_COUNT_PRECISION;
if((len > 5) && (cli_scanbuff((char *)data, len, fb->ctx->virname, fb->ctx->engine, 0) == CL_VIRUS)) {
cli_dbgmsg("found %s\n", *fb->ctx->virname);
fb->isInfected = 1;
}
}
#endif
if(fwrite(data, len, 1, fb->fp) != 1) {
cli_errmsg("fileblobAddData: Can't write %u bytes to temporary file %s: %s\n", len, fb->b.name, strerror(errno));
@ -492,6 +489,18 @@ fileblobGetFilename(const fileblob *fb)
return blobGetFilename(&(fb->b));
}
void
fileblobSetCTX(fileblob *fb, cli_ctx *ctx)
{
fb->ctx = ctx;
}
int
fileblobContainsVirus(const fileblob *fb)
{
return fb->isInfected ? TRUE : FALSE;
}
/*
* Different operating systems allow different characters in their filenames
* FIXME: What does QNX want? There is no #ifdef C_QNX, but if there were

@ -52,14 +52,18 @@ void blobGrow(blob *b, size_t len);
typedef struct fileblob {
FILE *fp;
blob b;
int isNotEmpty;
int isNotEmpty : 1;
int isInfected : 1;
cli_ctx *ctx;
} fileblob;
fileblob *fileblobCreate(void);
void fileblobDestroy(fileblob *fb);
void fileblobSetFilename(fileblob *fb, const char *dir, const char *filename);
const char *fileblobGetFilename(const fileblob *fb);
void fileblobSetCTX(fileblob *fb, cli_ctx *ctx);
int fileblobAddData(fileblob *fb, const unsigned char *data, size_t len);
int fileblobContainsVirus(const fileblob *fb);
void sanitiseName(char *name);
/* Maximum filenames under various systems */

@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
static char const rcsid[] = "$Id: mbox.c,v 1.294 2006/05/03 09:36:40 nigelhorne Exp $";
static char const rcsid[] = "$Id: mbox.c,v 1.295 2006/05/03 15:41:44 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -196,7 +196,7 @@ static int rfc1341(message *m, const char *dir);
#endif
static bool usefulHeader(int commandNumber, const char *cmd);
static char *getline_from_mbox(char *buffer, size_t len, FILE *fin);
static bool mailStart(const char *line);
static bool isBounceStart(const char *line);
static void checkURLs(message *m, const char *dir);
#ifdef WITH_CURL
@ -673,6 +673,9 @@ cli_mbox(const char *dir, int desc, cli_ctx *ctx)
}
messageSetEncoding(m, "base64");
messageSetCTX(m, ctx);
fileblobSetCTX(fb, ctx);
lastline = 0;
do {
int length = 0, datalen;
@ -809,6 +812,7 @@ cli_mbox(const char *dir, int desc, cli_ctx *ctx)
return CL_EMEM;
}
messageSetEncoding(m, "quoted-printable");
messageSetCTX(m, ctx);
line = NULL;
@ -1074,6 +1078,7 @@ cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx)
segv = signal(SIGSEGV, sigsegv);
#endif
retcode = CL_SUCCESS;
/*
* Is it a UNIX style mbox with more than one
* mail message, or just a single mail message?
@ -1120,6 +1125,7 @@ cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx)
lastLineWasEmpty = FALSE;
messagenumber = 1;
messageSetCTX(m, ctx);
do {
cli_chomp(buffer);
@ -1133,13 +1139,22 @@ cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx)
messageReset(m);
continue;
}
messageSetCTX(body, ctx);
messageDestroy(m);
if(messageGetBody(body))
if(!parseEmailBody(body, NULL, dir, rfc821, subtype, ctx)) {
if(messageGetBody(body)) {
int rc = parseEmailBody(body, NULL, dir, rfc821, subtype, ctx);
if(rc == 0) {
messageReset(body);
m = body;
continue;
} else if(rc == 3) {
cli_dbgmsg("Message number %d is infected\n",
messagenumber);
retcode = CL_VIRUS;
m = body = NULL;
break;
}
}
/*
* Starting a new message, throw away all the
* information about the old one. It would
@ -1150,6 +1165,7 @@ cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx)
*/
m = body;
messageReset(body);
messageSetCTX(body, ctx);
cli_dbgmsg("Finished processing message\n");
} else
@ -1170,9 +1186,12 @@ cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx)
fclose(fd);
cli_dbgmsg("Extract attachments from email %d\n", messagenumber);
body = parseEmailHeaders(m, rfc821);
messageDestroy(m);
if(retcode == CL_SUCCESS) {
cli_dbgmsg("Extract attachments from email %d\n", messagenumber);
body = parseEmailHeaders(m, rfc821);
}
if(m)
messageDestroy(m);
} else {
/*
* It's a single message, parse the headers then the body
@ -1198,15 +1217,21 @@ cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx)
fclose(fd);
}
retcode = CL_SUCCESS;
if(body) {
/*
* Write out the last entry in the mailbox
*/
if(messageGetBody(body))
if(!parseEmailBody(body, NULL, dir, rfc821, subtype, ctx))
retcode = CL_EFORMAT;
if((retcode == CL_SUCCESS) && messageGetBody(body)) {
messageSetCTX(body, ctx);
switch(parseEmailBody(body, NULL, dir, rfc821, subtype, ctx)) {
case 0:
retcode = CL_EFORMAT;
break;
case 3:
retcode = CL_VIRUS;
break;
}
}
/*
* Tidy up and quit
@ -1720,6 +1745,7 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821)
* 0 for fail
* 1 for success, attachments saved
* 2 for success, attachments not saved
* 3 for virus found
*/
static int /* success or fail */
parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t *rfc821Table, const table_t *subtypeTable, cli_ctx *ctx)
@ -1730,6 +1756,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
const char *cptr;
message *mainMessage;
fileblob *fb;
bool infected = FALSE;
cli_dbgmsg("in parseEmailBody\n");
@ -1899,6 +1926,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
multiparts--;
continue;
}
messageSetCTX(aMessage, ctx);
cli_dbgmsg("Now read in part %d\n", multiparts);
@ -2327,8 +2355,13 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
messageSetEncoding(mainMessage, "x-bunhex");
fb = messageToFileblob(mainMessage, dir);
if(fb)
if(fb) {
if(fileblobContainsVirus(fb)) {
infected = TRUE;
rc = 3;
}
fileblobDestroy(fb);
}
}
if(mainMessage != messageIn)
messageDestroy(mainMessage);
@ -2339,8 +2372,13 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
messageSetEncoding(aMessage, "x-binhex");
fb = messageToFileblob(aMessage, dir);
if(fb)
if(fb) {
if(fileblobContainsVirus(fb)) {
infected = TRUE;
rc = 3;
}
fileblobDestroy(fb);
}
assert(aMessage == messages[i]);
messageReset(messages[i]);
}
@ -2455,9 +2493,16 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
messageDestroy(messages[i]);
messages[i] = NULL;
if(body) {
messageSetCTX(body, ctx);
rc = parseEmailBody(body, NULL, dir, rfc821Table, subtypeTable, ctx);
if(messageContainsVirus(body))
infected = TRUE;
messageDestroy(body);
}
if(infected) {
rc = 3;
break;
}
#endif
continue;
case MULTIPART:
@ -2496,12 +2541,21 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
} else {
fb = messageToFileblob(aMessage, dir);
if(fb)
if(fb) {
if(fileblobContainsVirus(fb))
infected = TRUE;
fileblobDestroy(fb);
}
}
assert(aMessage == messages[i]);
messageDestroy(messages[i]);
if(messageContainsVirus(aMessage))
infected = TRUE;
messageDestroy(aMessage);
messages[i] = NULL;
if(infected) {
rc = 3;
break;
}
}
/* rc = parseEmailBody(NULL, NULL, dir, rfc821Table, subtypeTable, ctx); */
@ -2545,10 +2599,11 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
messageDestroy(mainMessage);
if(aText && (textIn == NULL)) {
if((fb = fileblobCreate()) != NULL) {
if((!infected) && (fb = fileblobCreate()) != NULL) {
cli_dbgmsg("Save non mime and/or text/plain part\n");
fileblobSetFilename(fb, dir, "textpart");
/*fileblobAddData(fb, "Received: by clamd (textpart)\n", 30);*/
fileblobSetCTX(fb, ctx);
(void)textToFileblob(aText, fb);
fileblobDestroy(fb);
@ -2585,6 +2640,8 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
if(m) {
cli_dbgmsg("Decode rfc822");
messageSetCTX(m, ctx);
if(mainMessage && (mainMessage != messageIn)) {
messageDestroy(mainMessage);
mainMessage = NULL;
@ -2667,7 +2724,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
if(l == NULL)
continue;
if(!mailStart(lineGetData(l)))
if(!isBounceStart(lineGetData(l)))
continue;
/*
@ -2733,6 +2790,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
break;
cli_dbgmsg("Save non mime part bounce message\n");
fileblobSetFilename(fb, dir, "bounce");
fileblobSetCTX(fb, ctx);
fileblobAddData(fb, (unsigned char *)"Received: by clamd (bounce)\n", 28);
inheader = TRUE;
@ -2757,7 +2815,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
l = t->t_line;
if((!inheader) && l) {
s = lineGetData(l);
if(mailStart(s)) {
if(isBounceStart(s)) {
cli_dbgmsg("Found the start of another bounce candidate (%s)\n", s);
break;
}
@ -2853,6 +2911,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
if(t && ((fb = fileblobCreate()) != NULL)) {
cli_dbgmsg("Found a bounce message\n");
fileblobSetFilename(fb, dir, "bounce");
fileblobSetCTX(fb, ctx);
if(textToFileblob(start, fb) == NULL)
cli_dbgmsg("Nothing new to save in the bounce message");
else
@ -2883,6 +2942,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
cli_dbgmsg("Found a bounce message with no header at '%s'\n",
lineGetData(t_line->t_line));
fileblobSetFilename(fb, dir, "bounce");
fileblobSetCTX(fb, ctx);
fileblobAddData(fb,
(const unsigned char *)"Received: by clamd (bounce)\n",
28);
@ -2925,6 +2985,9 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
if(messages)
free(messages);
if((rc == CL_SUCCESS) && infected)
rc = CL_VIRUS;
cli_dbgmsg("parseEmailBody() returning %d\n", rc);
return rc;
@ -4221,8 +4284,11 @@ getline_from_mbox(char *buffer, size_t len, FILE *fin)
return ret;
}
/*
* Is this line a candidate for the start of a bounce message?
*/
static bool
mailStart(const char *line)
isBounceStart(const char *line)
{
if(line == NULL)
return FALSE;

@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
static char const rcsid[] = "$Id: message.c,v 1.166 2006/05/03 09:36:40 nigelhorne Exp $";
static char const rcsid[] = "$Id: message.c,v 1.167 2006/05/03 15:41:44 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -83,7 +83,7 @@ static const char *messageGetArgument(const message *m, int arg);
/*
* http://oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/callback/callback.html
*/
static void *messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy)(void *), void (*setFilename)(void *, const char *, const char *), void (*addData)(void *, const unsigned char *, size_t), void *(*exportText)(const text *, void *));
static void *messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy)(void *), void (*setFilename)(void *, const char *, const char *), void (*addData)(void *, const unsigned char *, size_t), void *(*exportText)(const text *, void *), void (*setCTX)(void *, cli_ctx *));
static int usefulArg(const char *arg);
static void messageDedup(message *m);
static char *rfc2231(const char *in);
@ -1008,7 +1008,7 @@ messageClean(message *m)
* last item that was exported. That's sufficient for now.
*/
static void *
messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy)(void *), void (*setFilename)(void *, const char *, const char *), void (*addData)(void *, const unsigned char *, size_t), void *(*exportText)(const text *, void *))
messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy)(void *), void (*setFilename)(void *, const char *, const char *), void (*addData)(void *, const unsigned char *, size_t), void *(*exportText)(const text *, void *), void(*setCTX)(void *, cli_ctx *))
{
void *ret;
const text *t_line;
@ -1027,6 +1027,9 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
cli_dbgmsg("messageExport: numberOfEncTypes == %d\n", m->numberOfEncTypes);
if(setCTX && m->ctx)
(*setCTX)(ret, m->ctx);
if((t_line = binhexBegin(m)) != NULL) {
unsigned char byte;
unsigned long newlen = 0L, len, l;
@ -1514,7 +1517,7 @@ fileblob *
messageToFileblob(message *m, const char *dir)
{
cli_dbgmsg("messageToFileblob\n");
return messageExport(m, dir, (void *)fileblobCreate, (void *)fileblobDestroy, (void *)fileblobSetFilename, (void *)fileblobAddData, (void *)textToFileblob);
return messageExport(m, dir, (void *)fileblobCreate, (void *)fileblobDestroy, (void *)fileblobSetFilename, (void *)fileblobAddData, (void *)textToFileblob, (void *)fileblobSetCTX);
}
/*
@ -1524,7 +1527,7 @@ messageToFileblob(message *m, const char *dir)
blob *
messageToBlob(message *m)
{
return messageExport(m, NULL, (void *)blobCreate, (void *)blobDestroy, (void *)blobSetFilename, (void *)blobAddData, (void *)textToBlob);
return messageExport(m, NULL, (void *)blobCreate, (void *)blobDestroy, (void *)blobSetFilename, (void *)blobAddData, (void *)textToBlob, NULL);
}
/*
@ -2207,6 +2210,18 @@ usefulArg(const char *arg)
return 1;
}
void
messageSetCTX(message *m, cli_ctx *ctx)
{
m->ctx = ctx;
}
int
messageContainsVirus(const message *m)
{
return m->isInfected ? TRUE : FALSE;
}
/*
* We've run out of memory. Try to recover some by
* deduping the message

@ -29,9 +29,12 @@ typedef struct message {
char **mimeArguments;
char *mimeDispositionType; /* probably attachment */
text *body_first, *body_last;
cli_ctx *ctx;
char base64_1, base64_2, base64_3;
int base64chars;
int isInfected : 1;
/*
* Markers for the start of various non MIME messages that could
* be included within this message
@ -73,5 +76,7 @@ const text *encodingLine(const message *m);
void messageClearMarkers(message *m);
unsigned char *decodeLine(message *m, encoding_type enctype, const char *line, unsigned char *buf, size_t buflen);
int isuuencodebegin(const char *line);
void messageSetCTX(message *m, cli_ctx *ctx);
int messageContainsVirus(const message *m);
#endif /*_MESSAGE_H*/

@ -35,7 +35,7 @@
* cli_mbox decode it
* TODO: Remove the vcard handling
*/
static char const rcsid[] = "$Id: pst.c,v 1.17 2006/05/02 15:20:12 nigelhorne Exp $";
static char const rcsid[] = "$Id: pst.c,v 1.18 2006/05/03 15:41:43 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h" /* must come first */
@ -55,6 +55,8 @@ static char const rcsid[] = "$Id: pst.c,v 1.17 2006/05/02 15:20:12 nigelhorne Ex
#include "pst.h"
#include "blob.h"
#define DWORD unsigned int
#define DEBUG_VERSION 1
@ -453,9 +455,9 @@ static char *my_stristr(const char *haystack, const char *needle);
int
cli_pst(const char *dir, int desc)
{
cli_warnmsg("PST files not yet supported\n");
return CL_EFORMAT;
/*return pst_decode(dir, desc);*/
/*cli_warnmsg("PST files not yet supported\n");
return CL_EFORMAT;*/
return pst_decode(dir, desc);
}
static const char *
@ -4609,16 +4611,21 @@ struct file_ll {
#define C_TIME_SIZE 500
// char *check_filename(char *fname) {{{1
char *check_filename(char *fname) {
char *t = fname;
if (t == NULL) {
return fname;
}
static char *
check_filename(char *fname)
{
/*char *t = fname;*/
if(fname == NULL)
return fname;
#if 0
while ((t = strpbrk(t, "/\\:")) != NULL) {
// while there are characters in the second string that we don't want
*t = '_'; //replace them with an underscore
}
return fname;
#endif
sanitiseName(fname);
return fname;
}
static int

Loading…
Cancel
Save