From 8517cf573fdb368fa69d776bc113cd95c6646edb Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 13 Mar 1998 18:02:14 +0000 Subject: Nailed. svn path=/trunk/; revision=1698 --- NEWS | 4 +++- driver.c | 52 ++++++++++++++++++++++++++++------------------------ pop3.c | 2 +- rpa.c | 62 +++++++++++++++++++++++++++++++------------------------------- 4 files changed, 63 insertions(+), 57 deletions(-) diff --git a/NEWS b/NEWS index 006cbc7f..6a19dbc4 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ * Add an "ident" per-user option for debugging that produces an "X-Fetchmail-ID" header in fetched messages for debugging. * Total byte count in status message? +* -U/--userdefault option to specify postmaster overriding USER. Release Notes: @@ -18,8 +19,9 @@ fetchmail-4.4.0 (): * Fix bug that prevented graceful exit from POP3 validation on wrong password. * Dominique Unruh's patch that copes gracefully with bodiless messages. +* Fix timer-leak problem pointed ouit by Dave Bodenstab. -There are 275 people on fetchmail-friends and 153 on fetchmail-announce. +There are 268 people on fetchmail-friends and 160 on fetchmail-announce. fetchmail-4.3.9 (Fri Mar 6 10:45:32 EST 1998): * Relax the LOGIN capability check in IMAP. diff --git a/driver.c b/driver.c index be85b040..b14d9a61 100644 --- a/driver.c +++ b/driver.c @@ -110,9 +110,10 @@ static int mytimeout; /* value of nonreponse timeout */ static int msglen; /* actual message length */ /* use these to track what was happening when the nonresponse timer fired */ -#define GENERAL_WAIT 0 -#define SERVER_WAIT 1 -#define FORWARDING_WAIT 2 +#define GENERAL_WAIT 0 /* unknown wait type */ +#define SERVER_WAIT 1 /* waiting for mailserver response */ +#define LISTENER_WAIT 2 /* waiting for listener initialization */ +#define FORWARDING_WAIT 3 /* waiting for listener response */ static phase; static void set_timeout(int timeleft) @@ -466,6 +467,7 @@ static int smtp_open(struct query *ctl) */ struct idlist *idp; char *id_me = use_invisible ? ctl->server.truename : fetchmailhost; + int oldphase = phase; errno = 0; @@ -474,6 +476,10 @@ static int smtp_open(struct query *ctl) * Use both explicit hunt entries (value TRUE) and implicit * (default) ones (value FALSE). */ + oldphase = phase; + phase = LISTENER_WAIT; + + set_timeout(ctl->server.timeout); for (idp = ctl->smtphunt; idp; idp = idp->next) { char *cp, *parsed_host = alloca(strlen(idp->id) + 1); @@ -523,6 +529,8 @@ static int smtp_open(struct query *ctl) close(ctl->smtp_socket); ctl->smtp_socket = -1; } + set_timeout(0); + phase = oldphase; } if (outlevel >= O_VERBOSE && ctl->smtp_socket != -1) @@ -661,11 +669,14 @@ int num; /* index of message */ linelen = 0; line[0] = '\0'; do { + set_timeout(ctl->server.timeout); if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1) { + set_timeout(0); free(line); free(headers); return(PS_SOCKET); } + set_timeout(0); linelen += n; msglen += n; @@ -681,7 +692,6 @@ int num; /* index of message */ } } - set_timeout(ctl->server.timeout); line = (char *) realloc(line, strlen(line) + strlen(buf) +1); @@ -1532,8 +1542,10 @@ flag forward; /* TRUE to forward */ /* pass through the text lines */ while (protocol->delimited || len > 0) { + set_timeout(ctl->server.timeout); if ((linelen = SockRead(sock, buf, sizeof(buf)-1)) == -1) { + set_timeout(0); if (ctl->mda) { if (sinkfp) @@ -1542,7 +1554,7 @@ flag forward; /* TRUE to forward */ } return(PS_SOCKET); } - set_timeout(ctl->server.timeout); + set_timeout(0); /* write the message size dots */ if (linelen > 0) @@ -1755,7 +1767,7 @@ const struct method *proto; /* protocol method table */ /* set up the server-nonresponse timeout */ sigsave = signal(SIGALRM, timeout_handler); - set_timeout(mytimeout = ctl->server.timeout); + mytimeout = ctl->server.timeout; if ((js = setjmp(restart)) == 1) { @@ -1768,6 +1780,9 @@ const struct method *proto; /* protocol method table */ "timeout after %d seconds waiting for %s.", ctl->server.timeout, ctl->mda ? "MDA" : "SMTP"); + else if (phase == LISTENER_WAIT) + error(0, 0, + "timeout after %d seconds waiting for listener to respond."); else error(0, 0, "timeout after %d seconds.", ctl->server.timeout); @@ -1843,20 +1858,22 @@ const struct method *proto; /* protocol method table */ #ifdef KERBEROS_V4 if (ctl->server.preauthenticate == A_KERBEROS_V4) { + set_timeout(ctl->server.timeout); ok = kerberos_auth(sock, ctl->server.truename); + set_timeout(0); if (ok != 0) goto cleanUp; - set_timeout(ctl->server.timeout); } #endif /* KERBEROS_V4 */ #ifdef KERBEROS_V5 if (ctl->server.preauthenticate == A_KERBEROS_V5) { + set_timeout(ctl->server.timeout); ok = kerberos5_auth(sock, ctl->server.truename); + set_timeout(0); if (ok != 0) goto cleanUp; - set_timeout(ctl->server.timeout); } #endif /* KERBEROS_V5 */ @@ -1864,7 +1881,6 @@ const struct method *proto; /* protocol method table */ ok = (protocol->parse_response)(sock, buf); if (ok != 0) goto cleanUp; - set_timeout(ctl->server.timeout); /* try to get authorized to fetch mail */ if (protocol->getauth) @@ -1888,7 +1904,6 @@ const struct method *proto; /* protocol method table */ } goto cleanUp; } - set_timeout(ctl->server.timeout); } ctl->errcount = fetches = 0; @@ -1911,7 +1926,6 @@ const struct method *proto; /* protocol method table */ ok = (protocol->getrange)(sock, ctl, idp->id, &count, &new); if (ok != 0) goto cleanUp; - set_timeout(ctl->server.timeout); /* show user how many messages we downloaded */ if (idp->id) @@ -1997,7 +2011,6 @@ const struct method *proto; /* protocol method table */ ok = (proto->getsizes)(sock, count, msgsizes); if (ok != 0) goto cleanUp; - set_timeout(ctl->server.timeout); } /* read, forward, and delete messages */ @@ -2050,7 +2063,6 @@ const struct method *proto; /* protocol method table */ ok = (protocol->fetch_headers)(sock,ctl,num, &len); if (ok != 0) goto cleanUp; - set_timeout(ctl->server.timeout); /* -1 means we didn't see a size in the response */ if (len == -1 && msgsizes) @@ -2092,7 +2104,6 @@ const struct method *proto; /* protocol method table */ suppress_readbody = TRUE; else if (ok) goto cleanUp; - set_timeout(ctl->server.timeout); /* * If we're using IMAP4 or something else that @@ -2109,7 +2120,6 @@ const struct method *proto; /* protocol method table */ if ((ok = (protocol->trail)(sock, ctl, num))) goto cleanUp; - set_timeout(ctl->server.timeout); len = 0; if (!suppress_forward) { @@ -2117,7 +2127,6 @@ const struct method *proto; /* protocol method table */ goto cleanUp; if (outlevel > O_SILENT && !wholesize) error_build(" (%d body bytes) ", len); - set_timeout(ctl->server.timeout); } } @@ -2143,7 +2152,6 @@ const struct method *proto; /* protocol method table */ suppress_delete = suppress_forward = TRUE; else if (ok) goto cleanUp; - set_timeout(ctl->server.timeout); /* tell server we got it OK and resynchronize */ if (protocol->trail) @@ -2154,7 +2162,6 @@ const struct method *proto; /* protocol method table */ ok = (protocol->trail)(sock, ctl, num); if (ok != 0) goto cleanUp; - set_timeout(ctl->server.timeout); } } @@ -2261,7 +2268,6 @@ const struct method *proto; /* protocol method table */ ok = (protocol->delete)(sock, ctl, num); if (ok != 0) goto cleanUp; - set_timeout(ctl->server.timeout); #ifdef POP3_ENABLE delete_str(&ctl->newsaved, num); #endif /* POP3_ENABLE */ @@ -2284,7 +2290,6 @@ const struct method *proto; /* protocol method table */ } no_error: - set_timeout(ctl->server.timeout); ok = (protocol->logout_cmd)(sock, ctl); /* * Hmmmm...arguably this would be incorrect if we had fetches but @@ -2292,15 +2297,12 @@ const struct method *proto; /* protocol method table */ */ if (ok == 0) ok = (fetches > 0) ? PS_SUCCESS : PS_NOMAIL; - set_timeout(0); close(sock); goto closeUp; cleanUp: - set_timeout(ctl->server.timeout); if (ok != 0 && ok != PS_SOCKET) (protocol->logout_cmd)(sock, ctl); - set_timeout(0); close(sock); } @@ -2421,13 +2423,16 @@ int size; /* length of buffer */ int oldphase = phase; /* we don't have to be re-entrant */ phase = SERVER_WAIT; + set_timeout(mytimeout); if (SockRead(sock, buf, size) == -1) { + set_timeout(0); phase = oldphase; return(PS_SOCKET); } else { + set_timeout(0); if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; if (buf[strlen(buf)-1] == '\r') @@ -2497,7 +2502,6 @@ va_dcl /* we presume this does its own response echoing */ ok = (protocol->parse_response)(sock, buf); - set_timeout(mytimeout); phase = oldphase; return(ok); diff --git a/pop3.c b/pop3.c index 11ef1105..3004e747 100644 --- a/pop3.c +++ b/pop3.c @@ -117,7 +117,7 @@ int pop3_getauth(int sock, struct query *ctl, char *greeting) #ifdef RPA_ENABLE /* * CompuServe has changed its RPA behavior. Used to be they didn't - * accept PASS, but I'm told this changed in mid-November. + * accept PASS, but I'm told this changed in mid-November 1997. */ if (strstr(greeting, "csi.com")) { diff --git a/rpa.c b/rpa.c index e6b015a8..4643076d 100644 --- a/rpa.c +++ b/rpa.c @@ -6,6 +6,9 @@ compiler: GCC 2.7.2 environment: RedHat 4.0 Linux 2.0.18 description: RPA authorisation code for POP3 client + + The sole entry point is POP3_auth_rpa() + ***********************************************************************/ #include "config.h" @@ -29,19 +32,20 @@ extern int linecount; #ifndef NO_PROTO /* prototypes for internal functions */ - int POP3_rpa_resp(unsigned char* argbuf, int socket ); - void LenAppend(unsigned char** pptr, int len); - int LenSkip(unsigned char** pptr, int rxlen); - int DecBase64(unsigned char* bufp); - void EncBase64(unsigned char* bufp, int len); - void ToUnicode(unsigned char** pptr, unsigned char delim, - unsigned char* buf, int* plen, int conv); - int SetRealmService(unsigned char* bufp); - void GenChallenge(unsigned char* buf, int len); - int DigestPassphrase(unsigned char* passphrase,unsigned char* rbuf, int unicodeit); - void CompUserResp(); - int CheckUserAuth(); - void md5(unsigned char* in, int len, unsigned char* out); + static int POP3_rpa_resp(unsigned char* argbuf, int socket ); + static void LenAppend(unsigned char** pptr, int len); + static int LenSkip(unsigned char** pptr, int rxlen); + static int DecBase64(unsigned char* bufp); + static void EncBase64(unsigned char* bufp, int len); + static void ToUnicode(unsigned char** pptr, unsigned char delim, + unsigned char* buf, int* plen, int conv); + static int SetRealmService(unsigned char* bufp); + static void GenChallenge(unsigned char* buf, int len); + static int DigestPassphrase(unsigned char* passphrase, + unsigned char* rbuf, int unicodeit); + static void CompUserResp(); + static int CheckUserAuth(); + static void md5(unsigned char* in, int len, unsigned char* out); #endif /* RPA protocol definitions */ @@ -345,7 +349,7 @@ int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) globals: reads outlevel. *********************************************************************/ -int POP3_rpa_resp (argbuf,socket) +static int POP3_rpa_resp (argbuf,socket) unsigned char *argbuf; int socket; { @@ -355,7 +359,7 @@ int socket; int sockrc; fprintf(stderr, "Get response\n"); #ifndef TESTMODE - sockrc = SockRead(socket, buf, sizeof(buf)); + sockrc = gen_recv(socket, buf, sizeof(buf)); #else linecount++; if (linecount == 1) strcpy(buf,line1); @@ -363,13 +367,9 @@ int socket; if (linecount == 3) strcpy(buf,line3); /* fprintf(stderr,"--> "); fflush(stderr); */ /* scanf("%s",&buf) */ - sockrc = 0; + sockrc = PS_SUCCESS; #endif - if (sockrc > 0) { - buf[sockrc] = 0; - if (outlevel == O_VERBOSE) - fprintf(stderr,"%s\n",buf); - + if (sockrc == PS_SUCCESS) { bufp = buf; if ((*buf) == '+') { @@ -405,7 +405,7 @@ int socket; globals: none *********************************************************************/ -void LenAppend(pptr,len) +static void LenAppend(pptr,len) unsigned char **pptr; int len; { @@ -500,7 +500,7 @@ int rxlen; globals: reads outlevel. *********************************************************************/ -int DecBase64(bufp) +static int DecBase64(bufp) unsigned char *bufp; { unsigned int new, bits=0, cnt=0, i, part=0; @@ -559,7 +559,7 @@ unsigned char *bufp; globals: reads outlevel; *********************************************************************/ -void EncBase64(bufp,len) +static void EncBase64(bufp,len) unsigned char *bufp; int len; { @@ -613,7 +613,7 @@ int len; globals: reads outlevel; *********************************************************************/ -void ToUnicode(pptr,delim,buf,plen,conv) +static void ToUnicode(pptr,delim,buf,plen,conv) unsigned char **pptr; /* input string */ unsigned char delim; unsigned char *buf; /* output buffer */ @@ -660,7 +660,7 @@ int conv; writes Ns Nsl Nr Nrl *********************************************************************/ -int SetRealmService(bufp) +static int SetRealmService(bufp) unsigned char* bufp; { /* For the moment we pick the first available realm. It would */ @@ -689,7 +689,7 @@ unsigned char* bufp; reads /dev/random *********************************************************************/ -void GenChallenge(buf,len) +static void GenChallenge(buf,len) unsigned char *buf; int len; { @@ -732,7 +732,7 @@ int len; writes Pu. *********************************************************************/ -int DigestPassphrase(passphrase,rbuf,unicodeit) +static int DigestPassphrase(passphrase,rbuf,unicodeit) unsigned char *passphrase; unsigned char *rbuf; int unicodeit; @@ -771,7 +771,7 @@ int unicodeit; writes Ru. *********************************************************************/ -void CompUserResp() +static void CompUserResp() { unsigned char workarea[Pul+48+STRMAX*5+Tsl+Pul]; unsigned char* p; @@ -803,7 +803,7 @@ void CompUserResp() writes Ru. *********************************************************************/ -int CheckUserAuth() +static int CheckUserAuth() { unsigned char workarea[Pul+48+STRMAX*7+Tsl+Pul]; unsigned char* p; @@ -854,7 +854,7 @@ int CheckUserAuth() globals: reads outlevel *********************************************************************/ -void md5(in,len,out) +static void md5(in,len,out) unsigned char* in; int len; unsigned char* out; -- cgit v1.2.3