COMMAND
outlook
SYSTEMS AFFECTED
Those using OE (all versions?)
PROBLEM
YoDuh found following. He found a problem in qualcomm popper (and
presumabley others) in that it doesn't check for an existing
X-UIDL: headers, but simpley uses it when the client sends in a
uidl request. This problem can manifest itself as an effective
denial of service attack against microsoft outlook clients because
outlook looks for unique uidl's for each message and if there
are duplicates it will hang prior to downloading any mail. It
was tested on all known versions of outlook (specifically tested:
Outlook Express, Outlook 97, Outlook 98, Outlook 2000 and with
applied appropriate service packs with no change in behavior).
MUA's use a messages uidl as part of a pop transaction to check
whether they have received the message before (most include other
checks also). Usually the field is calculated when the message
is first read by the popper. A lot of poppers will store the uidl
for that message in an X-UIDL: header to avoid having to
recalculate it every time the client checks thier e-mail.
However, mail messages may arrive into a mailbox with a predefined
X-UIDL: header. Most popper daemons will use this header instead
of calculating a new header. If two messages arrive with the same
(duplicate) X-UIDL: header outlook will freak on the initial
negotiation where is sends a uidl command to the pop server. Most
of the time Outlook will simply stop all activity at that point
and you won't be able to download anything, very rarely (one in
about 20 tries) it will give you an error and then let you
continue the download.
SOLUTION
Other mail clients seem to handle this more intelligently
(Netscape, and Eudora light at least are unaffected). It is
possible that some clients will handle this differently (ie:
skipping messages, etc..), but that is unverified.
Some tested it with Outlook 2000 with Windows 98 and had no
problem. As Neil Christie pointed out this is the fault of
Outlook and not Qpopper. Here is what he had to say. The POP3
RFC suggests that duplicate UIDLs are acceptable for example in
the situation that there are two identical copies of 1 message in
a mailbox. As such the fault is with Outlook etc in failing to
handle this as opposed to in qpopper for generating / allowing
them. Whether the POP server should accept incoming UIDL
headers in the message or always generate its own is another
issue. From
ftp://ftp.isi.edu/in-notes/rfc1939.txt
This is sort of a broken way to handle it, properly qpopper should
be smarter about checking for duplicates in the file, or comparing
a calculated UID against the stored one (although that defeats the
purpose of storing it in the first place). Applying this patch may
result in an increased load on busy mail servers as they will have
to recalculate the uidl for each message every time the client
accesses it. I'm sure that there are a lot of other (better) ways
to solve it. If you can't patch your popper you can fix the
offending mailbox by simply stripping X-UIDL: headers from the
mailbox (something like
grep -v ^X-UIDL:" mailbox > mailbox.tmp; mv mailbox.tmp mailbox
should work in most cases). Uknown source posted following:
*** ../qpopper2.53.orig/pop_dropcopy.c Thu Jul 9 16:44:07 1998
--- pop_dropcopy.c Tue Jun 22 12:11:47 1999
***************
*** 412,417 ****
--- 412,418 ----
}
if (inheader) {
+ pop_log(p,POP_DEBUG, "HEADER: %s", buffer);
if (*buffer == '\n') {
inheader = 0;
content_length = cont_len;
***************
*** 429,434 ****
--- 430,440 ----
*cp++ = '\n';
*cp = '\0';
+ #ifdef DEBUG
+ if(p->debug)
+ pop_log(p,POP_DEBUG, "Msg %d generated UID %s", mp->number, cp);
+ #endif
+
mp->length += strlen("X-UIDL: ") + strlen(mp->uidl_str) + 1;
p->drop_size += strlen("X-UIDL: ") + strlen(mp->uidl_str)+1;
***************
*** 457,462 ****
--- 463,469 ----
int len;
/* Skip over header string */
+ /*
cp = &buffer[7];
while (*cp && (*cp == ' ' || *cp == '\t')) cp++;
if( (len = strlen(cp)) > MIN_UIDL_LENGTH && len < MAX_UIDL_LENGTH ) {
***************
*** 465,470 ****
--- 472,478 ----
mp->length += nchar + 1;
p->drop_size += nchar + 1;
}
+ */
}
continue; /* Do not include this value in the message size */
} else if ((strncasecmp(buffer,"Status:",7) == 0)) {
***************
*** 691,699 ****
--- 699,710 ----
int len;
char *cp;
+ /*
uidl_found++;
+ */
/* Skip over header */
+ /*
cp = &buffer[7];
while (*cp && (*cp == ' ' || *cp == '\t')) cp++;
if( (len = strlen(cp)) > MIN_UIDL_LENGTH && len < MAX_UIDL_LENGTH ) {
***************
*** 702,707 ****
--- 713,719 ----
mp->length += nchar + 1;
p->drop_size += nchar + 1;
}
+ */
}
continue; /* Do not include this value in the message size */
} else if (!strncasecmp(buffer,"Status:",7)) {