Added destroy flag

git-svn: trunk@2058
remotes/push_mirror/metadata
Nigel Horne 19 years ago
parent f9a1a860f2
commit 2673dc744d
  1. 4
      clamav-devel/ChangeLog
  2. 9
      clamav-devel/libclamav/binhex.c
  3. 5
      clamav-devel/libclamav/blob.c
  4. 73
      clamav-devel/libclamav/mbox.c
  5. 77
      clamav-devel/libclamav/message.c
  6. 22
      clamav-devel/libclamav/message.h
  7. 44
      clamav-devel/libclamav/text.c
  8. 7
      clamav-devel/libclamav/text.h

@ -1,3 +1,7 @@
Sat Jul 1 17:18:17 BST 2006 (njh)
----------------------------------
* libclamav: Free memory earlier
Sat Jul 1 04:49:32 BST 2006 (njh)
----------------------------------
* libclamav: Large binhex files were not being handled gracefully. Tidied

@ -18,6 +18,9 @@
*
* Change History:
* $Log: binhex.c,v $
* Revision 1.21 2006/07/01 16:17:35 njh
* Added destroy flag
*
* Revision 1.20 2006/07/01 03:47:50 njh
* Don't loop if binhex runs out of memory
*
@ -76,7 +79,7 @@
* First draft of binhex.c
*
*/
static char const rcsid[] = "$Id: binhex.c,v 1.20 2006/07/01 03:47:50 njh Exp $";
static char const rcsid[] = "$Id: binhex.c,v 1.21 2006/07/01 16:17:35 njh Exp $";
#include "clamav.h"
@ -195,7 +198,7 @@ cli_binhex(const char *dir, int desc)
/* similar to binhexMessage */
messageSetEncoding(m, "x-binhex");
fb = messageToFileblob(m, dir);
fb = messageToFileblob(m, dir, 1);
if(fb) {
cli_dbgmsg("Binhex file decoded to %s\n", fileblobGetFilename(fb));
fileblobDestroy(fb);
@ -205,6 +208,6 @@ cli_binhex(const char *dir, int desc)
if(fb)
return CL_CLEAN; /* a lie - but it gets things going */
return CL_EIO;
return CL_EIO; /* probably CL_EMEM, but we can't tell at this layer */
#endif
}

@ -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.50 2006/07/01 03:47:50 njh Exp $";
static char const rcsid[] = "$Id: blob.c,v 1.51 2006/07/01 16:17:35 njh Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -172,7 +172,8 @@ blobAddData(blob *b, const unsigned char *data, size_t len)
if(len >= (size_t)pagesize)
growth = ((len / pagesize) + 1) * pagesize;
/*printf("len %u, growth = %u\n", len, growth);*/
/*cli_dbgmsg("blobGrow: b->size %lu, b->len %lu, len %lu, growth = %u\n",
b->size, b->len, len, growth);*/
if(b->data == NULL) {
assert(b->len == 0);

@ -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.313 2006/06/28 21:07:36 njh Exp $";
static char const rcsid[] = "$Id: mbox.c,v 1.314 2006/07/01 16:17:35 njh Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -196,7 +196,7 @@ typedef struct mbox_ctx {
static int cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx);
static message *parseEmailFile(FILE *fin, const table_t *rfc821Table, const char *firstLine, const char *dir);
static message *parseEmailHeaders(const message *m, const table_t *rfc821Table);
static message *parseEmailHeaders(message *m, const table_t *rfc821Table);
static int parseEmailHeader(message *m, const char *line, const table_t *rfc821Table);
static int parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx);
static int boundaryStart(const char *line, const char *boundary);
@ -215,7 +215,7 @@ static int rfc1341(message *m, const char *dir);
static bool usefulHeader(int commandNumber, const char *cmd);
static char *getline_from_mbox(char *buffer, size_t len, FILE *fin);
static bool isBounceStart(const char *line);
static bool binhexMessage(const char *dir, message *message);
static bool binhexMessage(const char *dir, message *m);
static message *do_multipart(message *mainMessage, message **messages, int i, int *rc, mbox_ctx *mctx, message *messageIn, text **tptr);
static void checkURLs(message *m, const char *dir);
@ -908,7 +908,7 @@ cli_mbox(const char *dir, int desc, cli_ctx *ctx)
} while(quotedsize > 0L);
free(line);
fb = messageToFileblob(m, dir);
fb = messageToFileblob(m, dir, 1);
messageDestroy(m);
if(fb)
@ -1676,7 +1676,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch
* TODO: remove the duplication with parseEmailFile
*/
static message *
parseEmailHeaders(const message *m, const table_t *rfc821)
parseEmailHeaders(message *m, const table_t *rfc821)
{
bool inHeader = TRUE;
bool bodyIsEmpty = TRUE;
@ -1937,28 +1937,25 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821)
static int /* success or fail */
parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
{
message **messages; /* parts of a multipart message */
int inMimeHead, i, rc = 1, htmltextPart, multiparts = 0;
text *aText;
message *mainMessage;
int rc = 1;
text *aText = textIn;
message *mainMessage = messageIn;
fileblob *fb;
bool infected = FALSE;
cli_dbgmsg("in parseEmailBody\n");
aText = textIn;
messages = NULL;
mainMessage = messageIn;
/* Anything left to be parsed? */
if(mainMessage && (messageGetBody(mainMessage) != NULL)) {
mime_type mimeType;
int subtype, inhead;
int subtype, inhead, htmltextPart, inMimeHead, i;
const char *mimeSubtype, *boundary;
char *protocol;
const text *t_line;
/*bool isAlternative;*/
message *aMessage;
int multiparts = 0;
message **messages = NULL; /* parts of a multipart message */
cli_dbgmsg("Parsing mail file\n");
@ -2565,7 +2562,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
fileblobSetFilename(fb, mctx->dir, "textpart");
/*fileblobAddData(fb, "Received: by clamd (textpart)\n", 30);*/
fileblobSetCTX(fb, mctx->ctx);
(void)textToFileblob(aText, fb);
(void)textToFileblob(aText, fb, 0);
fileblobDestroy(fb);
}
@ -2646,7 +2643,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
if((strcasecmp(cptr, "octet-stream") == 0) ||
(strcasecmp(cptr, "x-msdownload") == 0)) {*/
{
fb = messageToFileblob(mainMessage, mctx->dir);
fb = messageToFileblob(mainMessage, mctx->dir, 1);
if(fb) {
cli_dbgmsg("Saving main message as attachment\n");
@ -2670,6 +2667,9 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
cli_warnmsg("Message received with unknown mime encoding");
break;
}
if(messages)
free(messages);
}
if(aText && (textIn == NULL)) {
@ -2800,26 +2800,16 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
* No attachments - scan the text portions, often files
* are hidden in HTML code
*/
cli_dbgmsg("%d multiparts found\n", multiparts);
for(i = 0; i < multiparts; i++) {
fb = messageToFileblob(messages[i], mctx->dir);
if(fb) {
cli_dbgmsg("Saving multipart %d\n", i);
fileblobDestroy(fb);
}
}
if(mainMessage && (rc != 3)) {
/*
* Look for uu-encoded main file
*/
const text *t_line;
text *t_line;
if((encodingLine(mainMessage) != NULL) &&
((t_line = bounceBegin(mainMessage)) != NULL)) {
const text *t, *start;
text *t, *start;
/*
* Attempt to save the original (unbounced)
* message - clamscan will find that in the
@ -2873,7 +2863,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
cli_dbgmsg("Found a bounce message\n");
fileblobSetFilename(fb, mctx->dir, "bounce");
/*fileblobSetCTX(fb, ctx);*/
if(textToFileblob(start, fb) == NULL)
if(textToFileblob(start, fb, 0) == NULL)
cli_dbgmsg("Nothing new to save in the bounce message\n");
else
rc = 1;
@ -2908,20 +2898,18 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
28);
/*fileblobSetCTX(fb, ctx);*/
fb = textToFileblob(t_line, fb);
fb = textToFileblob(t_line, fb, 0);
fileblobDestroy(fb);
}
saveIt = FALSE;
} else if(multiparts == 0)
} else
/*
* Save the entire text portion,
* since it it may be an HTML file with
* a JavaScript virus or a phish
*/
saveIt = TRUE;
else
saveIt = FALSE;
if(saveIt) {
cli_dbgmsg("Saving text part to scan\n");
@ -2938,14 +2926,11 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx)
}
}
} else
rc = (multiparts) ? 1 : 2; /* anything saved? */
rc = 2; /* nothing saved */
if(mainMessage && (mainMessage != messageIn))
messageDestroy(mainMessage);
if(messages)
free(messages);
if((rc != 0) && infected)
rc = 3;
@ -3411,7 +3396,7 @@ saveTextPart(message *m, const char *dir)
fileblob *fb;
messageAddArgument(m, "filename=textportion");
if((fb = messageToFileblob(m, dir)) != NULL) {
if((fb = messageToFileblob(m, dir, 0)) != NULL) {
/*
* Save main part to scan that
*/
@ -3581,7 +3566,7 @@ rfc2047(const char *in)
messageSetEncoding(m, "base64");
break;
}
b = messageToBlob(m);
b = messageToBlob(m, 1);
len = blobGetDataSize(b);
cli_dbgmsg("Decoded as '%*.*s'\n", len, len, blobGetData(b));
memcpy(pout, blobGetData(b), len);
@ -3673,7 +3658,7 @@ rfc1341(message *m, const char *dir)
free(oldfilename);
}
if((fb = messageToFileblob(m, pdir)) == NULL) {
if((fb = messageToFileblob(m, pdir, 0)) == NULL) {
free(id);
free(number);
return -1;
@ -3805,7 +3790,7 @@ rfc1341(message *m, const char *dir)
static void
checkURLs(message *m, const char *dir)
{
blob *b = messageToBlob(m);
blob *b = messageToBlob(m, 0);
size_t len;
table_t *t;
int i, n;
@ -4294,7 +4279,7 @@ binhexMessage(const char *dir, message *m)
if(messageGetEncoding(m) == NOENCODING)
messageSetEncoding(m, "x-binhex");
fb = messageToFileblob(m, dir);
fb = messageToFileblob(m, dir, 0);
if(fb) {
if(fileblobContainsVirus(fb))
@ -4518,7 +4503,7 @@ do_multipart(message *mainMessage, message **messages, int i, int *rc, mbox_ctx
cli_dbgmsg("Adding to non mime-part\n");
*tptr = textAdd(*tptr, messageGetBody(aMessage));
} else {
fileblob *fb = messageToFileblob(aMessage, mctx->dir);
fileblob *fb = messageToFileblob(aMessage, mctx->dir, 1);
if(fb) {
if(fileblobContainsVirus(fb))

@ -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.176 2006/07/01 03:47:50 njh Exp $";
static char const rcsid[] = "$Id: message.c,v 1.177 2006/07/01 16:17:35 njh Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -78,7 +78,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 *), void (*setCTX)(void *, cli_ctx *));
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)(text *, void *, int), void (*setCTX)(void *, cli_ctx *), int destroy_text);
static int usefulArg(const char *arg);
static void messageDedup(message *m);
static char *rfc2231(const char *in);
@ -983,8 +983,8 @@ messageIsEncoding(message *m)
* Returns a pointer to the body of the message. Note that it does NOT return
* a copy of the data
*/
const text *
messageGetBody(const message *m)
text *
messageGetBody(message *m)
{
assert(m != NULL);
return m->body_first;
@ -1010,10 +1010,10 @@ 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 *), void(*setCTX)(void *, cli_ctx *))
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)(text *, void *, int), void(*setCTX)(void *, cli_ctx *), int destroy_text)
{
void *ret;
const text *t_line;
text *t_line;
char *filename;
int i;
@ -1069,8 +1069,17 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
(t_line->t_line == NULL))
;
tmp = textToBlob(t_line, NULL);
tmp = textToBlob(t_line, NULL,
((m->numberOfEncTypes == 1) && (m->encodingTypes[0] == BINHEX)) ? destroy_text : 0);
if(tmp == NULL) {
/*
* FIXME: We've probably run out of memory during the
* text to blob.
* TODO: if m->numberOfEncTypes == 1 we could delete
* the text object as we decode it
*/
cli_warnmsg("Couldn't start binhex parser\n");
(*destroy)(ret);
return NULL;
}
@ -1334,7 +1343,7 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
free((char *)filename);
if(m->numberOfEncTypes == 0)
return exportText(messageGetBody(m), ret);
return exportText(messageGetBody(m), ret, destroy_text);
}
if(setCTX && m->ctx)
@ -1432,7 +1441,12 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
/*
* Fast copy
*/
(void)exportText(t_line, ret);
if(i == m->numberOfEncTypes - 1) {
/* last one */
(void)exportText(t_line, ret, destroy_text);
break;
}
(void)exportText(t_line, ret, 0);
continue;
}
@ -1529,10 +1543,17 @@ base64Flush(message *m, unsigned char *buf)
* The caller must free the returned fileblob
*/
fileblob *
messageToFileblob(message *m, const char *dir)
messageToFileblob(message *m, const char *dir, int destroy)
{
fileblob *fb;
cli_dbgmsg("messageToFileblob\n");
return messageExport(m, dir, (void *)fileblobCreate, (void *)fileblobDestroy, (void *)fileblobSetFilename, (void *)fileblobAddData, (void *)textToFileblob, (void *)fileblobSetCTX);
fb = messageExport(m, dir, (void *)fileblobCreate, (void *)fileblobDestroy, (void *)fileblobSetFilename, (void *)fileblobAddData, (void *)textToFileblob, (void *)fileblobSetCTX, destroy);
if(destroy && m->body_first) {
textDestroy(m->body_first);
m->body_first = m->body_last = NULL;
}
return fb;
}
/*
@ -1540,9 +1561,15 @@ messageToFileblob(message *m, const char *dir)
* The caller must free the returned blob
*/
blob *
messageToBlob(message *m)
messageToBlob(message *m, int destroy)
{
return messageExport(m, NULL, (void *)blobCreate, (void *)blobDestroy, (void *)blobSetFilename, (void *)blobAddData, (void *)textToBlob, NULL);
blob *b = messageExport(m, NULL, (void *)blobCreate, (void *)blobDestroy, (void *)blobSetFilename, (void *)blobAddData, (void *)textToBlob, NULL, destroy);
if(destroy && m->body_first) {
textDestroy(m->body_first);
m->body_first = m->body_last = NULL;
}
return b;
}
/*
@ -1728,8 +1755,8 @@ messageToText(message *m)
return first;
}
const text *
yEncBegin(const message *m)
text *
yEncBegin(message *m)
{
return m->yenc;
}
@ -1738,8 +1765,8 @@ yEncBegin(const message *m)
* Scan to find the BINHEX message (if any)
*/
#if 0
static const text *
binhexBegin(const message *m)
const text *
binhexBegin(message *m)
{
const text *t_line;
@ -1750,8 +1777,8 @@ binhexBegin(const message *m)
return NULL;
}
#else
const text *
binhexBegin(const message *m)
text *
binhexBegin(message *m)
{
return m->binhex;
}
@ -1762,8 +1789,8 @@ binhexBegin(const message *m)
* even a convention, so don't expect this to be foolproof
*/
#if 0
const text *
bounceBegin(const message *m)
text *
bounceBegin(message *m)
{
const text *t_line;
@ -1774,8 +1801,8 @@ bounceBegin(const message *m)
return NULL;
}
#else
const text *
bounceBegin(const message *m)
text *
bounceBegin(message *m)
{
return m->bounce;
}
@ -1806,8 +1833,8 @@ messageIsAllText(const message *m)
return 1;
}
#else
const text *
encodingLine(const message *m)
text *
encodingLine(message *m)
{
return m->encoding;
}

@ -39,10 +39,10 @@ typedef struct message {
* Markers for the start of various non MIME messages that could
* be included within this message
*/
const text *bounce; /* start of a bounced message */
const text *binhex; /* start of a binhex message */
const text *yenc; /* start of a yEnc message */
const text *encoding; /* is the non MIME message encoded? */
text *bounce; /* start of a bounced message */
text *binhex; /* start of a binhex message */
text *yenc; /* start of a yEnc message */
text *encoding; /* is the non MIME message encoded? */
const text *dedupedThisFar;
} message;
@ -63,16 +63,16 @@ encoding_type messageGetEncoding(const message *m);
int messageAddLine(message *m, line_t *line);
int messageAddStr(message *m, const char *data);
int messageAddStrAtTop(message *m, const char *data);
const text *messageGetBody(const message *m);
text *messageGetBody(message *m);
void messageClean(message *m);
unsigned char *base64Flush(message *m, unsigned char *buf);
fileblob *messageToFileblob(message *m, const char *dir);
blob *messageToBlob(message *m);
fileblob *messageToFileblob(message *m, const char *dir, int destroy);
blob *messageToBlob(message *m, int destroy);
text *messageToText(message *m);
const text *binhexBegin(const message *m);
const text *yEncBegin(const message *m);
const text *bounceBegin(const message *m);
const text *encodingLine(const message *m);
text *binhexBegin(message *m);
text *yEncBegin(message *m);
text *bounceBegin(message *m);
text *encodingLine(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);

@ -17,6 +17,9 @@
* MA 02110-1301, USA.
*
* $Log: text.c,v $
* Revision 1.21 2006/07/01 16:17:35 njh
* Added destroy flag
*
* Revision 1.20 2006/07/01 03:47:50 njh
* Don't loop if binhex runs out of memory
*
@ -70,7 +73,7 @@
*
*/
static char const rcsid[] = "$Id: text.c,v 1.20 2006/07/01 03:47:50 njh Exp $";
static char const rcsid[] = "$Id: text.c,v 1.21 2006/07/01 16:17:35 njh Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -104,7 +107,7 @@ static text *textCopy(const text *t_head);
static void addToFileblob(const line_t *line, void *arg);
static void getLength(const line_t *line, void *arg);
static void addToBlob(const line_t *line, void *arg);
static void *textIterate(const text *t_text, void (*cb)(const line_t *line, void *arg), void *arg);
static void *textIterate(text *t_text, void (*cb)(const line_t *line, void *arg), void *arg, int destroy);
void
textDestroy(text *t_head)
@ -233,7 +236,7 @@ textAddMessage(text *aText, message *aMessage)
* The caller must free the returned blob if b is NULL
*/
blob *
textToBlob(const text *t, blob *b)
textToBlob(text *t, blob *b, int destroy)
{
size_t s;
blob *bin;
@ -243,11 +246,16 @@ textToBlob(const text *t, blob *b)
s = 0;
(void)textIterate(t, getLength, &s);
(void)textIterate(t, getLength, &s, 0);
if(s == 0)
return b;
/*
* copy b. If b is NULL and an error occurs we know we need to free
* before returning
*/
bin = b;
if(b == NULL) {
b = blobCreate();
@ -255,14 +263,26 @@ textToBlob(const text *t, blob *b)
return NULL;
}
bin = b;
if(blobGrow(b, s) != CL_SUCCESS) {
cli_warnmsg("Couldn't grow the blob we may be low on memory\n");
#if 0
if(!destroy) {
if(bin == NULL)
blobDestroy(b);
return NULL;
}
/*
* We may be able to recover enough memory as we destroy to
* create the blob
*/
#else
if(bin == NULL)
blobDestroy(b);
return NULL;
#endif
}
(void)textIterate(t, addToBlob, b);
(void)textIterate(t, addToBlob, b, destroy);
blobClose(b);
@ -270,7 +290,7 @@ textToBlob(const text *t, blob *b)
}
fileblob *
textToFileblob(const text *t, fileblob *fb)
textToFileblob(text *t, fileblob *fb, int destroy)
{
assert(fb != NULL);
assert(t != NULL);
@ -283,7 +303,7 @@ textToFileblob(const text *t, fileblob *fb)
} else
fb->ctx = NULL; /* no need to scan */
return textIterate(t, addToFileblob, fb);
return textIterate(t, addToFileblob, fb, destroy);
}
static void
@ -324,10 +344,16 @@ addToFileblob(const line_t *line, void *arg)
}
static void *
textIterate(const text *t_text, void (*cb)(const line_t *item, void *arg), void *arg)
textIterate(text *t_text, void (*cb)(const line_t *item, void *arg), void *arg, int destroy)
{
while(t_text) {
(*cb)(t_text->t_line, arg);
if(destroy && t_text->t_line) {
lineUnlink(t_text->t_line);
t_text->t_line = NULL;
}
t_text = t_text->t_next;
}
return arg;

@ -17,6 +17,9 @@
* MA 02110-1301, USA.
*
* $Log: text.h,v $
* Revision 1.9 2006/07/01 16:17:35 njh
* Added destroy flag
*
* Revision 1.8 2006/04/09 19:59:28 kojm
* update GPL headers with new address for FSF
*
@ -48,5 +51,5 @@ void textDestroy(text *t_head);
text *textClean(text *t_head);
text *textAdd(text *t_head, const text *t);
text *textAddMessage(text *aText, message *aMessage);
blob *textToBlob(const text *t, blob *b);
fileblob *textToFileblob(const text *t, fileblob *fb);
blob *textToBlob(text *t, blob *b, int destroy);
fileblob *textToFileblob(text *t, fileblob *fb, int destroy);

Loading…
Cancel
Save