Some MYDOOM.I were getting through

git-svn: trunk@677
remotes/push_mirror/metadata
Nigel Horne 22 years ago
parent a5373b6417
commit 0c0894b82d
  1. 4
      clamav-devel/ChangeLog
  2. 10
      clamav-devel/libclamav/mbox.c
  3. 241
      clamav-devel/libclamav/message.c
  4. 8
      clamav-devel/libclamav/message.h
  5. 7
      clamav-devel/libclamav/text.c
  6. 5
      clamav-devel/libclamav/text.h

@ -1,3 +1,7 @@
Tue Jul 20 15:38:03 BST 2004 (njh)
----------------------------------
* libclamav: Some MyDoom.I were getting through
Tue Jul 20 03:26:38 CEST 2004 (tk)
----------------------------------
* libclamav: integrate CHM decoder from Trog

@ -17,6 +17,9 @@
*
* Change History:
* $Log: mbox.c,v $
* Revision 1.88 2004/07/20 14:35:29 nigelhorne
* Some MYDOOM.I were getting through
*
* Revision 1.87 2004/07/19 17:54:40 kojm
* Use new patter matching algorithm. Cleanup.
*
@ -249,7 +252,7 @@
* Compilable under SCO; removed duplicate code with message.c
*
*/
static char const rcsid[] = "$Id: mbox.c,v 1.87 2004/07/19 17:54:40 kojm Exp $";
static char const rcsid[] = "$Id: mbox.c,v 1.88 2004/07/20 14:35:29 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -1749,7 +1752,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con
static int
boundaryStart(const char *line, const char *boundary)
{
/*cli_dbgmsg("boundaryStart: line = '%s' boundary = '%s'\n", line, boundary);*/
cli_dbgmsg("boundaryStart: line = '%s' boundary = '%s'\n", line, boundary);
if(line == NULL)
return 0; /* empty line */
@ -1772,7 +1775,7 @@ boundaryStart(const char *line, const char *boundary)
* that has -1 in it instead of starting --1. This needs some more work.
*/
if(strstr(line, boundary) != NULL) {
cli_dbgmsg("found %s in %s\n", boundary, line);
cli_dbgmsg("boundaryStart: found %s in %s\n", boundary, line);
return 1;
}
if(*line++ != '-')
@ -1790,6 +1793,7 @@ endOfMessage(const char *line, const char *boundary)
{
size_t len;
cli_dbgmsg("endOfMessage: line = '%s' boundary = '%s'\n", line, boundary);
if(line == NULL)
return 0;
if(*line++ != '-')

@ -17,6 +17,9 @@
*
* Change History:
* $Log: message.c,v $
* Revision 1.65 2004/07/20 14:35:29 nigelhorne
* Some MYDOOM.I were getting through
*
* Revision 1.64 2004/07/02 23:00:57 kojm
* new method of file type detection; HTML normalisation
*
@ -189,7 +192,7 @@
* uuencodebegin() no longer static
*
*/
static char const rcsid[] = "$Id: message.c,v 1.64 2004/07/02 23:00:57 kojm Exp $";
static char const rcsid[] = "$Id: message.c,v 1.65 2004/07/20 14:35:29 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -238,8 +241,9 @@ static char const rcsid[] = "$Id: message.c,v 1.64 2004/07/02 23:00:57 kojm Exp
typedef enum { FALSE = 0, TRUE = 1 } bool;
static unsigned char *decodeLine(const message *m, const char *line, unsigned char *buf, size_t buflen);
static unsigned char *decode(const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast);
static unsigned char *decodeLine(message *m, const char *line, unsigned char *buf, size_t buflen);
static unsigned char *decode(message *m, const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast);
static void squeeze(char *s);
static unsigned char hex(char c);
static unsigned char base64(char c);
static unsigned char uudecode(char c);
@ -321,6 +325,8 @@ messageReset(message *m)
if(m->body_first)
textDestroy(m->body_first);
assert(m->base64chars == 0);
memset(m, '\0', sizeof(message));
m->mimeType = NOMIME;
m->encodingType = NOENCODING;
@ -947,7 +953,7 @@ messageToBlob(message *m)
unsigned char *uptr, *data;
char *ptr;
int bytenumber;
blob *tmp = blobCreate();
blob *tmp;
/*
* Table look up by Thomas Lamy <Thomas.Lamy@in-online.net>
@ -965,6 +971,13 @@ messageToBlob(message *m)
/* 70-7f */ 0x3d,0x3e,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
tmp = blobCreate();
if(tmp == NULL) {
blobDestroy(b);
return NULL;
}
/*
* Decode BinHex4. First create a temporary blob which contains
* the encoded message. Then decode that blob to the target
@ -1077,6 +1090,11 @@ messageToBlob(message *m)
if(memchr(data, 0x90, newlen)) {
blob *u = blobCreate(); /* uncompressed data */
if(u == NULL) {
blobDestroy(b);
blobDestroy(tmp);
return NULL;
}
/*
* Includes compression
*/
@ -1262,7 +1280,7 @@ messageToBlob(message *m)
* the last byte and should be used as evidence
* of the end of the data. Some mail clients
* annoyingly then put plain text after the '='
* bytes. Sigh
* byte and viruses exploit this bug. Sigh
*/
/*if(messageGetEncoding(m) == BASE64)
if(strchr(line, '='))
@ -1270,6 +1288,17 @@ messageToBlob(message *m)
} while((t_line = t_line->t_next) != NULL);
/* Verify we have nothing left to flush out */
if(m->base64chars) {
unsigned char data[4];
unsigned char *ptr;
ptr = decode(m, NULL, data, base64, FALSE);
if(ptr)
blobAddData(b, data, (size_t)(ptr - data));
m->base64chars = 0;
}
return b;
}
@ -1278,7 +1307,7 @@ messageToBlob(message *m)
* The caller must free the returned text
*/
text *
messageToText(const message *m)
messageToText(message *m)
{
text *first = NULL, *last = NULL;
const text *t_line;
@ -1301,7 +1330,8 @@ messageToText(const message *m)
((last->t_text = strdup(t_line->t_text)) == NULL)) {
if(last)
free(last);
textDestroy(first);
if(first)
textDestroy(first);
return NULL;
}
}
@ -1325,7 +1355,14 @@ messageToText(const message *m)
unsigned char *uptr;
const char *line = t_line->t_text;
if(messageGetEncoding(m) == UUENCODE)
if(messageGetEncoding(m) == BASE64) {
/*
* ignore blanks - breaks RFC which is
* probably the point!
*/
if(line == NULL)
continue;
} else if(messageGetEncoding(m) == UUENCODE)
if(strcasecmp(line, "end") == 0)
break;
@ -1481,7 +1518,7 @@ encodingLine(const message *m)
* len is sizeof(ptr)
*/
static unsigned char *
decodeLine(const message *m, const char *line, unsigned char *buf, size_t buflen)
decodeLine(message *m, const char *line, unsigned char *buf, size_t buflen)
{
size_t len;
bool softbreak;
@ -1513,7 +1550,7 @@ decodeLine(const message *m, const char *line, unsigned char *buf, size_t buflen
*buf++ = '\n';
break;
}
softbreak = FALSE;
while(*line) {
if(*line == '=') {
@ -1562,11 +1599,17 @@ decodeLine(const message *m, const char *line, unsigned char *buf, size_t buflen
p2 = strchr(copy, '=');
if(p2)
*p2 = '\0';
squeeze(copy);
/*
* Klez doesn't always put "=" on the last line
*/
buf = decode(copy, buf, base64, (p2 == NULL) && ((strlen(copy) & 3) == 0));
/*buf = decode(copy, buf, base64, FALSE);*/
buf = decode(m, copy, buf, base64, (p2 == NULL) && ((strlen(copy) & 3) == 0));
if(p2)
/* flush the read ahead bytes */
buf = decode(m, NULL, buf, base64, FALSE);
/*buf = decode(m, copy, buf, base64, FALSE);*/
free(copy);
break;
@ -1592,7 +1635,7 @@ decodeLine(const message *m, const char *line, unsigned char *buf, size_t buflen
*/
cli_warnmsg("uudecode: buffer overflow stopped, attempting to ignore but decoding may fail\n");
else
buf = decode(line, buf, uudecode, (len & 3) == 0);
buf = decode(m, line, buf, uudecode, (len & 3) == 0);
break;
}
@ -1600,11 +1643,180 @@ decodeLine(const message *m, const char *line, unsigned char *buf, size_t buflen
return buf;
}
/*
* Remove the spaces from the middle of a string. Spaces shouldn't appear
* mid string in base64 files, but some broken mail clients ignore such
* errors rather than discarding the mail, and virus writers exploit this bug
*/
static void
squeeze(char *s)
{
while((s = strchr(s, ' ')) != NULL)
strcpy(s, &s[1]);
}
/*
* Returns one byte after the end of the decoded data in "out"
*
* Update m->base64chars with the last few bytes of data that we haven't
* decoded. After the last line is found, decode will be called with in = NULL
* to flush these out
*/
#if 1
static unsigned char *
decode(const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast)
decode(message *m, const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast)
{
unsigned char b1, b2, b3, b4;
unsigned char cb1, cb2, cb3; /* carried over from last line */
/*cli_dbgmsg("decode %s (len %d ifFast %d base64chars %d)\n", in,
in ? strlen(in) : 0,
isFast, m->base64chars);*/
cb1 = cb2 = cb3 = '\0';
switch(m->base64chars) {
case 3:
cb3 = m->base64_3;
/* FALLTHROUGH */
case 2:
cb2 = m->base64_2;
/* FALLTHROUGH */
case 1:
cb1 = m->base64_1;
isFast = FALSE;
break;
default:
assert(m->base64chars <= 3);
}
if(isFast)
/* Fast decoding if not last line */
while(*in) {
b1 = (*decoder)(*in++);
b2 = (*decoder)(*in++);
b3 = (*decoder)(*in++);
/*
* Put this line here to help on some compilers which
* can make use of some architecure's ability to
* multiprocess when different variables can be
* updated at the same time - here b3 is used in
* one line, b1/b2 in the next and b4 in the next after
* that, b3 and b4 rely on in but b1/b2 don't
*/
*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
b4 = (*decoder)(*in++);
*out++ = (b2 << 4) | ((b3 >> 2) & 0xF);
*out++ = (b3 << 6) | (b4 & 0x3F);
}
else {
if(in == NULL) { /* flush */
int nbytes = m->base64chars;
if(nbytes == 0)
return out;
m->base64chars--;
b1 = cb1;
if(m->base64chars) {
m->base64chars--;
b2 = cb2;
if(m->base64chars) {
m->base64chars--;
b3 = cb3;
assert(m->base64chars == 0);
}
}
switch(nbytes) {
case 3:
b4 = '\0';
/* fall through */
case 4:
*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
*out++ = (b2 << 4) | ((b3 >> 2) & 0xF);
*out++ = (b3 << 6) | (b4 & 0x3F);
break;
case 2:
*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
*out++ = b2 << 4;
break;
case 1:
*out++ = b1 << 2;
break;
default:
assert(0);
}
} else while(*in) {
/* Slower decoding for last line */
int nbytes;
if(m->base64chars) {
m->base64chars--;
b1 = cb1;
} else
b1 = (*decoder)(*in++);
if(*in == '\0') {
b2 = '\0';
nbytes = 1;
} else {
if(m->base64chars) {
m->base64chars--;
b2 = cb2;
} else
b2 = (*decoder)(*in++);
if(*in == '\0') {
b3 = '\0';
nbytes = 2;
} else {
if(m->base64chars) {
m->base64chars--;
b3 = cb3;
} else
b3 = (*decoder)(*in++);
if(*in == '\0') {
b4 = '\0';
nbytes = 3;
} else {
b4 = (*decoder)(*in++);
nbytes = 4;
}
}
}
switch(nbytes) {
case 3:
m->base64_3 = b3;
case 2:
m->base64_2 = b2;
case 1:
m->base64_1 = b1;
break;
case 4:
*out++ = (b1 << 2) | ((b2 >> 4) & 0x3);
*out++ = (b2 << 4) | ((b3 >> 2) & 0xF);
*out++ = (b3 << 6) | (b4 & 0x3F);
break;
default:
assert(0);
}
if(nbytes != 4) {
m->base64chars = nbytes;
break;
}
}
}
return out;
}
#else
static unsigned char *
decode(message *m, const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast)
{
unsigned char b1, b2, b3, b4;
@ -1679,6 +1891,7 @@ decode(const char *in, unsigned char *out, unsigned char (*decoder)(char), bool
}
return out;
}
#endif
static unsigned char
hex(char c)

@ -16,6 +16,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: message.h,v $
* Revision 1.12 2004/07/20 14:35:29 nigelhorne
* Some MYDOOM.I were getting through
*
* Revision 1.11 2004/05/06 18:01:25 nigelhorne
* Force attachments marked as RFC822 messages to be scanned
*
@ -53,6 +56,9 @@ typedef struct message {
char **mimeArguments;
char *mimeDispositionType; /* probably attachment */
text *body_first, *body_last;
char base64_1, base64_2, base64_3;
int base64chars;
/*
* Markers for the start of various non MIME messages that could
* be included within this message
@ -82,7 +88,7 @@ int messageAddLineAtTop(message *m, const char *line);
const text *messageGetBody(const message *m);
void messageClean(message *m);
blob *messageToBlob(message *m);
text *messageToText(const message *m);
text *messageToText(message *m);
const text *uuencodeBegin(const message *m);
const text *binhexBegin(const message *m);
const text *bounceBegin(const message *m);

@ -16,6 +16,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: text.c,v $
* Revision 1.8 2004/07/20 14:35:29 nigelhorne
* Some MYDOOM.I were getting through
*
* Revision 1.7 2004/06/22 04:08:02 nigelhorne
* Optimise empty lines
*
@ -30,7 +33,7 @@
*
*/
static char const rcsid[] = "$Id: text.c,v 1.7 2004/06/22 04:08:02 nigelhorne Exp $";
static char const rcsid[] = "$Id: text.c,v 1.8 2004/07/20 14:35:29 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -207,7 +210,7 @@ textAdd(text *t_head, const text *t)
* Add a message's content to the end of the current object
*/
text *
textAddMessage(text *aText, const message *aMessage)
textAddMessage(text *aText, message *aMessage)
{
assert(aMessage != NULL);

@ -16,6 +16,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: text.h,v $
* Revision 1.4 2004/07/20 14:35:29 nigelhorne
* Some MYDOOM.I were getting through
*
* Revision 1.3 2004/06/22 04:08:02 nigelhorne
* Optimise empty lines
*
@ -32,5 +35,5 @@ void textDestroy(text *t_head);
text *textClean(text *t_head);
text *textCopy(const text *t_head);
text *textAdd(text *t_head, const text *t);
text *textAddMessage(text *aText, const message *aMessage);
text *textAddMessage(text *aText, message *aMessage);
blob *textToBlob(const text *t, blob *b);

Loading…
Cancel
Save