Index: base64.c =================================================================== RCS file: /home/cvs/debian/fetchmail/base64.c,v retrieving revision 1.1.1.2 retrieving revision 1.3 diff -u -r1.1.1.2 -r1.3 --- base64.c 3 Oct 2001 23:28:22 -0000 1.1.1.2 +++ base64.c 9 Apr 2002 17:51:11 -0000 1.3 @@ -54,6 +54,7 @@ int from64tobits(char *out, const char *in, int maxlen) /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */ +/* maxlen limits output buffer size, set to zero to ignore */ { int len = 0; register unsigned char digit1, digit2, digit3, digit4; @@ -78,17 +79,21 @@ return(-1); in += 4; ++len; - if (len && len >= maxlen) /* prevent buffer overflow */ + if (maxlen && len > maxlen) return(-1); *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4); if (digit3 != '=') { - *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2); ++len; + if (maxlen && len > maxlen) + return(-1); + *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2); if (digit4 != '=') { + ++len; + if (maxlen && len > maxlen) + return(-1); *out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4); - ++len; } } } while Index: imap.c =================================================================== RCS file: /home/cvs/debian/fetchmail/imap.c,v retrieving revision 1.1.1.22 retrieving revision 1.25 diff -u -r1.1.1.22 -r1.25 --- imap.c 1 Apr 2002 07:55:20 -0000 1.1.1.22 +++ imap.c 9 Apr 2002 17:51:11 -0000 1.25 @@ -186,7 +186,7 @@ if ((gen_recv(sock, msgbuf, sizeof msgbuf))) return result; - len = from64tobits ((unsigned char*)&challenge, msgbuf, sizeof(msgbuf)); + len = from64tobits ((char*)&challenge, msgbuf, sizeof(challenge)); if (outlevel >= O_DEBUG) dumpSmbNtlmAuthChallenge(stdout, &challenge); Index: sink.c =================================================================== RCS file: /home/cvs/debian/fetchmail/sink.c,v retrieving revision 1.1.1.25 retrieving revision 1.36 diff -u -r1.1.1.25 -r1.36 --- sink.c 1 Apr 2002 07:46:57 -0000 1.1.1.25 +++ sink.c 9 Apr 2002 17:51:11 -0000 1.36 @@ -618,7 +618,7 @@ char **from_responses; #endif /* EXPLICIT_BOUNCE_ON_BAD_ADDRESS */ int total_addresses; - int force_transient_error; + int force_transient_error = 0; /* * Compute ESMTP options. @@ -728,33 +728,36 @@ #ifdef EXPLICIT_BOUNCE_ON_BAD_ADDRESS char errbuf[POPBUFSIZE]; #endif /* EXPLICIT_BOUNCE_ON_BAD_ADDRESS */ - if (handle_smtp_report(ctl, msg) == PS_TRANSIENT) - force_transient_error = 1; - + switch (handle_smtp_report(ctl, msg)) { + case PS_REFUSED: break; + case PS_TRANSIENT: force_transient_error = 1; + /* fallthrough to default! */ + default: #ifdef EXPLICIT_BOUNCE_ON_BAD_ADDRESS #ifdef HAVE_SNPRINTF - snprintf(errbuf, sizeof(errbuf), "%s: %s", - idp->id, smtp_response); + snprintf(errbuf, sizeof(errbuf), "%s: %s", + idp->id, smtp_response); #else - strncpy(errbuf, idp->id, sizeof(errbuf)); - strcat(errbuf, ": "); - strcat(errbuf, smtp_response); + strncpy(errbuf, idp->id, sizeof(errbuf)); + strcat(errbuf, ": "); + strcat(errbuf, smtp_response); #endif /* HAVE_SNPRINTF */ - xalloca(from_responses[*bad_addresses], - char *, - strlen(errbuf)+1); - strcpy(from_responses[*bad_addresses], errbuf); + xalloca(from_responses[*bad_addresses], + char *, + strlen(errbuf)+1); + strcpy(from_responses[*bad_addresses], errbuf); #endif /* EXPLICIT_BOUNCE_ON_BAD_ADDRESS */ - (*bad_addresses)++; - idp->val.status.mark = XMIT_RCPTBAD; - if (outlevel >= O_VERBOSE) - report(stderr, - GT_("%cMTP listener doesn't like recipient address `%s'\n"), - ctl->listener, addr); - } - } + (*bad_addresses)++; + idp->val.status.mark = XMIT_RCPTBAD; + if (outlevel >= O_VERBOSE) + report(stderr, + GT_("%cMTP listener doesn't like recipient address `%s'\n"), + ctl->listener, addr); + } /* switch */ + } /* else */ + } /* if and loop */ #ifdef EXPLICIT_BOUNCE_ON_BAD_ADDRESS /* @@ -779,10 +782,17 @@ if (force_transient_error) { /* do not risk dataloss due to overengineered multidrop * crap. If one of the recipients returned PS_TRANSIENT, - * we return exactly that. + * we return exactly that. And we don't bounce the mail + * either. Yes, some people might get duplicates. So + * what? There is no decent fix for THAT one. */ SMTP_rset(ctl->smtp_socket); /* required by RFC1870 */ return(PS_TRANSIENT); + } + /* All recipients were PS_REFUSED? No bouncing in that case */ + if (!(*bad_addresses)) { + SMTP_rset(ctl->smtp_socket); /* required by RFC1870 */ + return(PS_REFUSED); } if (!run.postmaster[0]) {