aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--TODO-6.3.2011
-rw-r--r--smtp.c4
-rw-r--r--socket.c3
-rw-r--r--transact.c6
5 files changed, 19 insertions, 13 deletions
diff --git a/NEWS b/NEWS
index bcf2537b..4a4e0c39 100644
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,14 @@ removed from a 6.4.0 or newer release.)
fetchmail-6.3.20 (not yet released):
+# SECURITY FIXES
+* Fetchmail's socket timeout handling was incomplete. Network outages in the
+ wrong phase of a communication, combined with unlucky operating systems and
+ their defaults, could cause fetchmail to hang for extended amounts of time.
+ Freezes for beyond a week were reported by Thomas Jarosch. Fetchmail sets
+ UNIX- and Internet-domain socket send and receive timeouts now.
+ This fixes a hang during STARTTLS negotiation reported by Thomas Jarosch.
+
# CHANGES
* fetchmail now always uses its own MD5 implementation. The library and header
variants are too diverse, and we've been bitten before -- and configure
diff --git a/TODO-6.3.20 b/TODO-6.3.20
deleted file mode 100644
index d9d79977..00000000
--- a/TODO-6.3.20
+++ /dev/null
@@ -1,11 +0,0 @@
-- fix STARTTLS timeouts by setting socket timings
- possibly using a different structure than an int to save the fd
- and SSL context -- and then also timeout?
- Or just make set_timeout take an optional fd, which, when != -1,
- also sets the socket timeouts?
-
-- make SSLv2 removal dependent on openssl configuration
- (see Debian FTBFS bug for how to detect that in configure)
-
-- make --with-ssl default?
-
diff --git a/smtp.c b/smtp.c
index 1c99c696..90c35173 100644
--- a/smtp.c
+++ b/smtp.c
@@ -313,10 +313,12 @@ int SMTP_ok(int sock, char smtp_mode, int mintimeout)
{
SIGHANDLERTYPE alrmsave;
char reply[MSGBUFSIZE], *i;
+ int tmo = (mytimeout >= mintimeout) ? mytimeout : mintimeout;
/* set an alarm for smtp ok */
alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
- set_timeout(mytimeout >= mintimeout ? mytimeout : mintimeout);
+ set_timeout(tmo);
+ SockTimeout(sock, tmo);
smtp_response[0] = '\0';
diff --git a/socket.c b/socket.c
index 33b7c40c..d3025b7b 100644
--- a/socket.c
+++ b/socket.c
@@ -251,6 +251,7 @@ int UnixOpen(const char *path)
*/
mailserver_socket_temp = sock;
+ SockTimeout(sock, mytimeout);
if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
{
int olderr = errno;
@@ -390,8 +391,8 @@ va_dcl {
#endif
vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
+ SockTimeout(sock, mytimeout);
return SockWrite(sock, buf, strlen(buf));
-
}
#ifdef SSL_ENABLE
diff --git a/transact.c b/transact.c
index d1e4f6a9..9667bd25 100644
--- a/transact.c
+++ b/transact.c
@@ -487,6 +487,7 @@ int readheaders(int sock,
char *sp, *tp;
set_timeout(mytimeout);
+ SockTimeout(sock, mytimeout);
if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1) {
set_timeout(0);
free(line);
@@ -1408,6 +1409,7 @@ int readbody(int sock, struct query *ctl, flag forward, int len)
while (protocol->delimited || len > 0)
{
set_timeout(mytimeout);
+ SockTimeout(sock, mytimeout);
/* XXX FIXME: for undelimited protocols that ship the size, such
* as IMAP, we might want to use the count of remaining characters
* instead of the buffer size -- not for fetchmail 6.3.X though */
@@ -1551,6 +1553,7 @@ va_dcl
va_end(ap);
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "\r\n");
+ SockTimeout(sock, mytimeout);
SockWrite(sock, buf, strlen(buf));
if (outlevel >= O_MONITOR)
@@ -1571,6 +1574,7 @@ int gen_recv(int sock /** socket to which server is connected */,
phase = SERVER_WAIT;
set_timeout(mytimeout);
+ SockTimeout(sock, mytimeout);
if (SockRead(sock, buf, size) == -1)
{
set_timeout(0);
@@ -1684,6 +1688,7 @@ int gen_recv_split(int sock /** socket to which server is connected */,
phase = SERVER_WAIT;
set_timeout(mytimeout);
+ SockTimeout(sock, mytimeout);
rr = SockRead(sock, buf + n, size - n);
set_timeout(0);
phase = oldphase;
@@ -1755,6 +1760,7 @@ va_dcl
va_end(ap);
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "\r\n");
+ SockTimeout(sock, mytimeout);
ok = SockWrite(sock, buf, strlen(buf));
if (ok == -1 || (size_t)ok != strlen(buf)) {
/* short write, bail out */