From 71bc7ce6858ee50574dc574a948ea24b5d2d0bfc Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 1 Apr 2002 07:50:04 +0000 Subject: [PATCH] Debian 5.9.10 fixes. svn path=/trunk/; revision=3603 --- NEWS | 16 ++++++++++ conf.c | 4 +++ daemon.c | 9 +++++- driver.c | 35 +++++++++++++++------ fetchmail-FAQ.html | 6 ++-- fetchmailconf | 6 ++-- imap.c | 4 +++ rcfile_y.y | 8 +---- sink.c | 12 ++++++- socket.c | 78 ++++++++++++++++++++++++++-------------------- 10 files changed, 121 insertions(+), 57 deletions(-) diff --git a/NEWS b/NEWS index cfc271c0..bb67df7e 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,22 @@ * Updated Turkish translation. * Added warning about auth failures on the GMX server. +* HMH's Debian 5.9.10 patches: +1. Fix minor typo in FAQ +2. Fix partial implementation of ESMTP auth, and some minor + fetchmailconf stuff +3. Add proper error reporting to bad logfile creation. + patch by Sunil Shetye +4. Fix incredible aggravating bug that caused dataloss + risks if 4xx errors were returned by the MTA +5. Corrected version of the fix-timeouts-for-ssl and descriptor + leaking patches from Sylvain Benoist + Also fix outdated comments in driver.c +6. Sunil Shetye's patch to stop fetchmail from trying to fetch + twice with IMAP +7. Stop stupid complaint about turning off SSL being illegal + without SSL support. +8. Byrial Jensen i18n fixes fetchmail-5.9.10 (Sun Mar 10 15:09:57 EST 2002), 21529 lines: diff --git a/conf.c b/conf.c index b969e15c..089bb93a 100644 --- a/conf.c +++ b/conf.c @@ -311,6 +311,10 @@ void dump_config(struct runctl *runp, struct query *querylist) stringdump("plugin", ctl->server.plugin); stringdump("plugout", ctl->server.plugout); stringdump("principal", ctl->server.principal); + if (ctl->server.esmtp_name) + stringdump("esmtpname",ctl->server.esmtp_name); + if (ctl->server.esmtp_password) + stringdump("esmtppassword",ctl->server.esmtp_password); booldump("tracepolls", ctl->tracepolls); indent(0); diff --git a/daemon.c b/daemon.c index 331ca767..d2a5b2d9 100644 --- a/daemon.c +++ b/daemon.c @@ -234,12 +234,19 @@ nottyDetach: } if (logfile) - fd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, 0666); /* stdout */ + { + if ((fd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, 0666)) < 0) { /* stdout */ + report(stderr, "open %s (%s)\n", logfile, strerror(errno)); + return(PS_IOERR); + } + } else + { if (dup(fd) < 0) { /* stdout */ report(stderr, "dup (%s)\n", strerror(errno)); return(PS_IOERR); } + } if (dup(fd) < 0) { /* stderr */ report(stderr, "dup (%s)\n", strerror(errno)); return(PS_IOERR); diff --git a/driver.c b/driver.c index d1a7bb4e..b11d7536 100644 --- a/driver.c +++ b/driver.c @@ -64,6 +64,7 @@ int stage; /* where are we? */ int phase; /* where are we, for error-logging purposes? */ int batchcount; /* count of messages sent in current batch */ flag peek_capable; /* can we peek for better error recovery? */ +int mailserver_socket_temp; /* socket to free if connect timeout */ static int timeoutcount; /* count consecutive timeouts */ @@ -557,11 +558,6 @@ static int fetch_messages(int mailserver_socket, struct query *ctl, { if (suppress_readbody) { - /* When readheaders returns PS_TRUNCATED, - * the body (which has no content) - * has already been read by readheaders, - * so we say readbody returned PS_SUCCESS - */ err = PS_SUCCESS; } else @@ -746,7 +742,12 @@ const int maxfetch; /* maximum number of messages to fetch */ sigfillset(&allsigs); sigprocmask(SIG_UNBLOCK, &allsigs, NULL); #endif /* HAVE_SIGPROCMASK */ - + + /* If there was a connect timeout, the socket should be closed. + * mailserver_socket_temp contains the socket to close. + */ + mailserver_socket = mailserver_socket_temp; + if (js == THROW_SIGPIPE) { signal(SIGPIPE, SIG_IGN); @@ -1008,10 +1009,14 @@ const int maxfetch; /* maximum number of messages to fetch */ phase = oldphase; goto closeUp; } - set_timeout(0); - phase = oldphase; #ifdef SSL_ENABLE + /* Save the socket opened. Usefull if Fetchmail hangs on SSLOpen + * because the socket can be closed + */ + mailserver_socket_temp = mailserver_socket; + set_timeout(mytimeout); + /* perform initial SSL handshake on open connection */ /* Note: We pass the realhost name over for certificate verification. We may want to make this configurable */ @@ -1021,8 +1026,18 @@ const int maxfetch; /* maximum number of messages to fetch */ report(stderr, GT_("SSL connection failed.\n")); goto closeUp; } + + /* Fetchmail didn't hang on SSLOpen, + * then no need to set mailserver_socket_temp + */ + mailserver_socket_temp = -1; #endif - + + /* A timeout is still defined before SSLOpen, + * then Fetchmail hanging on SSLOpen is handled. + */ + set_timeout(0); + phase = oldphase; #ifdef KERBEROS_V4 if (ctl->server.authenticate == A_KERBEROS_V4) { @@ -1352,6 +1367,8 @@ is restored.")); continue; else if (ctl->server.base_protocol->is_old && (ctl->server.base_protocol->is_old)(mailserver_socket,ctl,num)) msgcodes[num-1] = MSGLEN_OLD; +/* else if (msgsizes[num-1] == 512) + msgcodes[num-1] = MSGLEN_OLD; (hmh) sample code to skip message */ } /* read, forward, and delete messages */ diff --git a/fetchmail-FAQ.html b/fetchmail-FAQ.html index f3be2774..0017511f 100644 --- a/fetchmail-FAQ.html +++ b/fetchmail-FAQ.html @@ -10,7 +10,7 @@
Back to Fetchmail Home Page To Site Map -$Date: 2002/03/26 14:41:17 $ +$Date: 2002/04/01 07:49:49 $

Frequently Asked Questions About Fetchmail

@@ -225,7 +225,7 @@ bugs, please include the following:
  1. Your operating system.
  2. Your compiler version, if you built from source; otherwise, the - name and origin ogf the RPM or other binary package you installed. + name and origin of the RPM or other binary package you installed.
  3. A copy of your POP or IMAP server's greeting line.
  4. The name and version of the SMTP listener or MDA you are forwarding to.
  5. Any command-line options you used. @@ -3015,7 +3015,7 @@ date from the last Received header.

    Back to Fetchmail Home Page To Site Map -$Date: 2002/03/26 14:41:17 $ +$Date: 2002/04/01 07:49:49 $

    Eric S. Raymond <esr@thyrsus.com>
    diff --git a/fetchmailconf b/fetchmailconf index fda0d9b7..b7a69fdb 100755 --- a/fetchmailconf +++ b/fetchmailconf @@ -118,6 +118,8 @@ class Server: ('monitor', 'String'), ('plugin', 'String'), ('plugout', 'String'), + ('esmtpname', 'String'), + ('esmtppassword', 'String'), ('netsec', 'String'), ('principal', 'String'), ('tracepolls','Boolean')) @@ -1189,7 +1191,7 @@ class ServerEdit(Frame, MyWidget): for (protocol, port) in (("IMAP",143), ("POP3",110), ("POP2",109)): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: - sock.connect(realhost, port) + sock.connect((realhost, port)) greetline = sock.recv(1024) sock.close() except: @@ -1386,7 +1388,7 @@ You may have to use the fetchall option. if string.find(greetline, " IMS POP3") > 0: warnings = warnings + """ Some servers issuing the greeting line 'IMS POP3' have been known to -do byte-stuffing correctly. This means that if a message you receive +do byte-stuffing incorrectly. This means that if a message you receive has a . (period) at start of line, fetchmail will become confused and probably wedge itself. (This bug was recorded on IMS POP3 0.86.) diff --git a/imap.c b/imap.c index fd850d78..96f485cf 100644 --- a/imap.c +++ b/imap.c @@ -517,6 +517,9 @@ static int imap_getrange(int sock, return(ok); } } + /* if recentcount is 0, return no mail */ + if (recentcount == 0) + count = 0; if (outlevel >= O_DEBUG) report(stdout, GT_("%d messages waiting after re-poll\n"), count); } @@ -617,6 +620,7 @@ static int imap_getrange(int sock, unseen = -1; *newp = unseen; + count = 0; expunged = 0; deletions = 0; diff --git a/rcfile_y.y b/rcfile_y.y index a85a7fa0..5b0c5088 100644 --- a/rcfile_y.y +++ b/rcfile_y.y @@ -366,13 +366,7 @@ user_option : TO localnames HERE | NO MIMEDECODE {current.mimedecode = FLAG_FALSE;} | NO IDLE {current.idle = FLAG_FALSE;} - | NO SSL { -#ifdef SSL_ENABLE - current.use_ssl = FLAG_FALSE; -#else - yyerror(GT_("SSL is not enabled")); -#endif - } + | NO SSL {current.use_ssl = FLAG_FALSE;} | LIMIT NUMBER {current.limit = NUM_VALUE_IN($2);} | WARNINGS NUMBER {current.warnings = NUM_VALUE_IN($2);} diff --git a/sink.c b/sink.c index bd1d9243..74244e10 100644 --- a/sink.c +++ b/sink.c @@ -618,6 +618,7 @@ static int open_smtp_sink(struct query *ctl, struct msgblk *msg, char **from_responses; #endif /* EXPLICIT_BOUNCE_ON_BAD_ADDRESS */ int total_addresses; + int force_transient_error; /* * Compute ESMTP options. @@ -727,7 +728,8 @@ static int open_smtp_sink(struct query *ctl, struct msgblk *msg, #ifdef EXPLICIT_BOUNCE_ON_BAD_ADDRESS char errbuf[POPBUFSIZE]; #endif /* EXPLICIT_BOUNCE_ON_BAD_ADDRESS */ - handle_smtp_report(ctl, msg); + if (handle_smtp_report(ctl, msg) == PS_TRANSIENT) + force_transient_error = 1; #ifdef EXPLICIT_BOUNCE_ON_BAD_ADDRESS #ifdef HAVE_SNPRINTF @@ -774,6 +776,14 @@ static int open_smtp_sink(struct query *ctl, struct msgblk *msg, */ if (!(*good_addresses)) { + 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. + */ + SMTP_rset(ctl->smtp_socket); /* required by RFC1870 */ + return(PS_TRANSIENT); + } if (!run.postmaster[0]) { if (outlevel >= O_VERBOSE) diff --git a/socket.c b/socket.c index 27b928cc..3310b179 100644 --- a/socket.c +++ b/socket.c @@ -36,7 +36,6 @@ #else #include #endif -#include #include "socket.h" #include "fetchmail.h" #include "i18n.h" @@ -68,6 +67,8 @@ static int h_errno; #endif /* ndef h_errno */ +extern int mailserver_socket_temp; /* Socket to close if connect timeout */ + #if NET_SECURITY #include #endif /* NET_SECURITY */ @@ -219,10 +220,6 @@ int SockCheckOpen(int fd) int UnixOpen(const char *path) { -#ifdef HAVE_SIGPROCMASK - sigset_t allsigs; -#endif /* HAVE_SIGPROCMASK */ - int sock = -1; struct sockaddr_un ad; memset(&ad, 0, sizeof(ad)); @@ -236,13 +233,12 @@ int UnixOpen(const char *path) return -1; } -#ifdef HAVE_SIGPROCMASK - /* avoid socket leak on alarm signal during connect(2) */ - sigfillset(&allsigs); - sigprocmask(SIG_BLOCK, &allsigs, NULL); -#endif /* HAVE_SIGPROCMASK */ - - if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0) + /* Socket opened saved. Usefull if connect timeout + * because it can be closed. + */ + mailserver_socket_temp = sock; + + if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0) { int olderr = errno; fm_close(sock); /* don't use SockClose, no traffic yet */ @@ -250,10 +246,9 @@ int UnixOpen(const char *path) errno = olderr; sock = -1; } - -#ifdef HAVE_SIGPROCMASK - sigprocmask(SIG_UNBLOCK, &allsigs, NULL); -#endif /* HAVE_SIGPROCMASK */ + + /* No connect timeout, then no need to set mailserver_socket_temp */ + mailserver_socket_temp = -1; return sock; } @@ -262,10 +257,6 @@ int UnixOpen(const char *path) int SockOpen(const char *host, const char *service, const char *options, const char *plugin) { -#ifdef HAVE_SIGPROCMASK - sigset_t allsigs; -#endif /* HAVE_SIGPROCMASK */ - struct addrinfo *ai, *ai0, req; int i; #if NET_SECURITY @@ -304,29 +295,29 @@ int SockOpen(const char *host, const char *service, const char *options, break; #else -#ifdef HAVE_SIGPROCMASK - /* avoid socket leak on alarm signal during connect(2) */ - sigfillset(&allsigs); - sigprocmask(SIG_BLOCK, &allsigs, NULL); -#endif /* HAVE_SIGPROCMASK */ - i = -1; for (ai = ai0; ai; ai = ai->ai_next) { i = socket(ai->ai_family, ai->ai_socktype, 0); if (i < 0) continue; + + /* Socket opened saved. Usefull if connect timeout + * because it can be closed. + */ + mailserver_socket_temp = i; + if (connect(i, (struct sockaddr *) ai->ai_addr, ai->ai_addrlen) < 0) { fm_close(i); i = -1; continue; } + + /* No connect timeout, then no need to set mailserver_socket_temp */ + mailserver_socket_temp = -1; + break; } -#ifdef HAVE_SIGPROCMASK - sigprocmask(SIG_UNBLOCK, &allsigs, NULL); -#endif /* HAVE_SIGPROCMASK */ - #endif #endif /* NET_SECURITY */ @@ -389,6 +380,12 @@ int SockOpen(const char *host, int clientPort, const char *options, h_errno = 0; return -1; } + + /* Socket opened saved. Usefull if connect timeout because + * it can be closed + */ + mailserver_socket_temp = sock; + if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0) { int olderr = errno; @@ -397,6 +394,10 @@ int SockOpen(const char *host, int clientPort, const char *options, errno = olderr; return -1; } + + /* No connect timeout, then no need to set mailserver_socket_temp */ + mailserver_socket_temp = -1; + #ifndef HAVE_INET_ATON } #else @@ -434,10 +435,19 @@ int SockOpen(const char *host, int clientPort, const char *options, h_errno = 0; return -1; } + + /* Socket opened saved. Usefull if connect timeout because + * it can be closed + */ + mailserver_socket_temp = sock; + ad.sin_port = htons(clientPort); memcpy(&ad.sin_addr, *pptr, sizeof(struct in_addr)); - if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) == 0) - break; /* success */ + if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) == 0) { + /* No connect timeout, then no need to set mailserver_socket_temp */ + mailserver_socket_temp = -1; + break; /* success */ + } fm_close(sock); /* don't use SockClose, no traffic yet */ memset(&ad, 0, sizeof(ad)); ad.sin_family = AF_INET; @@ -804,11 +814,11 @@ int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict ) } tp += esz; } - if (outlevel > O_SILENT) + if (outlevel > O_NORMAL) report(stdout, GT_("%s key fingerprint: %s\n"), _server_label, text); if (_check_digest != NULL) { if (strcmp(text, _check_digest) == 0) { - if (outlevel > O_SILENT) + if (outlevel > O_NORMAL) report(stdout, GT_("%s fingerprints match.\n"), _server_label); } else { if (outlevel > O_SILENT) -- 2.43.2