1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
diff -Nur mpop-1.0.5/src/pop3.c mpop-1.0.5.new/src/pop3.c
--- mpop-1.0.5/src/pop3.c 2006-09-23 01:35:03.000000000 +0000
+++ mpop-1.0.5.new/src/pop3.c 2007-05-27 06:14:08.000000000 +0000
@@ -407,11 +407,13 @@
* see pop3.h
*/
+char *pop3_get_addr(const char *s);
+
int pop3_get_greeting(pop3_session_t *session, char *greeting,
char **errmsg, char **errstr)
{
int e;
- char *p, *q;
+ char *p, *q, *a;
if ((e = pop3_get_msg(session, 0, errstr)) != POP3_EOK)
{
@@ -429,17 +431,23 @@
/* 'greeting' is large enough */
strcpy(greeting, session->buffer + 4);
}
- /* search APOP timestamp */
- if ((p = strchr(session->buffer, '<')) != NULL)
- {
- if ((q = strchr(p, '>')) != NULL)
- {
- session->cap.flags |= POP3_CAP_AUTH_APOP;
- session->cap.apop_timestamp = xmalloc((q - p + 2) * sizeof(char));
- strncpy(session->cap.apop_timestamp, p, q - p + 1);
- session->cap.apop_timestamp[q - p + 1] = '\0';
- }
+ /* Search APOP timestamp. Make sure that it is a valid RFC822 message id as
+ * required by RFC 1939. This should make man-in-the-middle attacks as
+ * described in CVE-2007-1558 harder. */
+ a = NULL;
+ if ((p = strchr(session->buffer, '<')) != NULL /* start of timestamp */
+ && (q = strchr(p + 1, '>')) != NULL /* end of timestamp */
+ && (a = pop3_get_addr(p)) /* valid address */
+ && strchr(a, '@') /* has domain part */
+ && strlen(a) + 2 == (size_t)(q - p + 1) /* no specials */
+ && strncmp(p + 1, a, q - p - 1) == 0) /* no invalid chars */
+ {
+ session->cap.flags |= POP3_CAP_AUTH_APOP;
+ session->cap.apop_timestamp = xmalloc((q - p + 2) * sizeof(char));
+ strncpy(session->cap.apop_timestamp, p, q - p + 1);
+ session->cap.apop_timestamp[q - p + 1] = '\0';
}
+ free(a);
return POP3_EOK;
}
|