diff options
| author | Eric S. Raymond <esr@thyrsus.com> | 1998-10-30 08:06:05 +0000 | 
|---|---|---|
| committer | Eric S. Raymond <esr@thyrsus.com> | 1998-10-30 08:06:05 +0000 | 
| commit | a694daec9878ff7fbfbb8ba2c6e40eb2bce6a77c (patch) | |
| tree | 2fd4e53547331cf3a2ccae9c1621d6ec65249c0d | |
| parent | a379197312a968cc5c705dda5f466ad7dfe9847e (diff) | |
| download | fetchmail-a694daec9878ff7fbfbb8ba2c6e40eb2bce6a77c.tar.gz fetchmail-a694daec9878ff7fbfbb8ba2c6e40eb2bce6a77c.tar.bz2 fetchmail-a694daec9878ff7fbfbb8ba2c6e40eb2bce6a77c.zip | |
Send calling user mail on password failure in daemon mode.
svn path=/trunk/; revision=2153
| -rw-r--r-- | NEWS | 3 | ||||
| -rw-r--r-- | driver.c | 113 | ||||
| -rw-r--r-- | fetchmail.c | 11 | ||||
| -rw-r--r-- | fetchmail.h | 1 | 
4 files changed, 104 insertions, 24 deletions
| @@ -2,7 +2,8 @@  fetchmail-4.6.6 ():  * Fixed a core-dump bug in reply_hack with -v -v on. -* Fix fetchmailconf to be able to edit proprerties. +* Fix fetchmailconf to be able to edit properties. +* Send calling user mail when password authentication fails in daemon mode.  There are 249 people on fetchmail-friends and 309 on fetchmail-announce. @@ -819,7 +819,7 @@ static int readheaders(int sock, long fetchlen, long reallen, struct query *ctl,      }      else      { -	/* set up sinkfp so we can deliver the message body through it */  +	/* set up stuffline() so we can deliver the message body through it */   	if ((n = open_sink(ctl, return_path, xmit_names, reallen,  			   &good_addresses, &bad_addresses)) != PS_SUCCESS)  	{ @@ -1229,15 +1229,71 @@ static void clean_skipped_list(struct idlist **skipped_list)      *skipped_list = head;  } -static void send_warning(struct query *ctl) +static open_warning_by_mail(struct query *ctl) +/* set up output sink for a mailed warning to calling user */ +{ +    int	good, bad; + +    /* +     * We give a null address list as arg 3 because we actually *want* +     * this message to go to run.postmaster.  The zero length arg 4 means +     * we won't pass a SIZE option to ESMTP; the message length would +     * be more trouble than it's worth to compute. +     */ +    return(open_sink(ctl, "FETCHMAIL-DAEMON", NULL, 0, &good, &bad)); +} + +#if defined(HAVE_STDARG_H) +void stuff_warning_line(struct query *ctl, const char *fmt, ... ) +#else +void stuff_warning_line(struct query *ctl, fmt, va_alist) +struct query *ctl; +const char *fmt;	/* printf-style format */ +va_dcl +#endif +/* format and ship a warning message line by mail */ +{ +    char	buf[POPBUFSIZE]; +    va_list ap; + +    /* +     * stuffline() requires its input to be writeable (for CR stripping), +     * so we needed to copy the message to a writeable buffer anyway in +     * case it was a string constant.  We make a virtue of that necessity +     * here by supporting stdargs/varargs. +     */ +#if defined(HAVE_STDARG_H) +    va_start(ap, fmt) ; +#else +    va_start(ap); +#endif +#ifdef HAVE_VSNPRINTF +    vsnprintf(buf, sizeof(buf), fmt, ap); +#else +    vsprintf(buf, fmt, ap); +#endif +    va_end(ap); + +    strcat(buf, "\r\n"); + +    stuffline(ctl, buf); +} + +static close_warning_by_mail(struct query *ctl) +/* sign and send mailed warnings */ +{ +    stuff_warning_line(ctl, "--\r\n\t\t\t\tThe Fetchmail Daemon\r\n"); +    close_sink(ctl, TRUE); +} + +static void send_size_warnings(struct query *ctl)  /* send warning mail with skipped msg; reset msg count when user notified */  {      int size, nbr;      int msg_to_send = FALSE;      struct idlist *head=NULL, *current=NULL;      int max_warning_poll_count, good, bad; -#define OVERHD	"Subject: Fetchmail WARNING.\r\n\r\nThe following oversized messages remain on the mail server:\n\r\n" -    char	buf[sizeof(OVERHD) + 2]; +#define OVERHD	"Subject: Fetchmail oversized-messages warning.\r\n\r\nThe following oversized messages remain on the mail server:"      head = ctl->skipped;      if (!head) @@ -1254,18 +1310,10 @@ static void send_warning(struct query *ctl)       * There's no good way to recover if we can't send notification mail,        * but it's not a disaster, either, since the skipped mail will not       * be deleted. -     * -     * We give a null address list as arg 3 because we actually *want* -     * this message to go to run.postmaster.  The zero length arg 4 means -     * we won't pass a SIZE option to ESMTP; the message length would -     * be more trouble than it's worth to compute.       */ -    if (open_sink(ctl, "FETCHMAIL-DAEMON", NULL, 0, &good, &bad)) +    if (open_warning_by_mail(ctl))  	return; - -    /* stuffline() requires its input to be writeable for CR stripping */ -    strcpy(buf, OVERHD); -    stuffline(ctl, buf); +    stuff_warning_line(ctl, OVERHD);      if (run.poll_interval == 0)  	max_warning_poll_count = 0; @@ -1279,10 +1327,9 @@ static void send_warning(struct query *ctl)  	{  	    nbr = current->val.status.mark;  	    size = atoi(current->id); -	    sprintf(buf,  -		    "\t%d msg %d octets long skipped by fetchmail.\n", +	    stuff_warning_line(ctl,  +		    "\t%d msg %d octets long skipped by fetchmail.",  		    nbr, size); -	    stuffline(ctl, buf);  	}  	current->val.status.num++;  	current->val.status.mark = 0; @@ -1291,7 +1338,7 @@ static void send_warning(struct query *ctl)  	    current->val.status.num = 0;      } -    close_sink(ctl, TRUE); +    close_warning_by_mail(ctl);  #undef OVERHD  } @@ -1510,6 +1557,28 @@ const struct method *proto;	/* protocol method table */  		    error(0, -1, "Authorization failure on %s@%s",   			  ctl->remotename,  			  ctl->server.truename); + +		    /* +		     * If we're running in background, try to mail the +		     * calling user a heads-up about the authentication  +		     * failure the first time it happens. +		     */ +		    if (run.poll_interval && !nodetach  +			&& !ctl->authfailcount && !open_warning_by_mail(ctl)) +		    { +			stuff_warning_line(ctl, +			       "Subject: fetchmail authentication failed\r\n"); +			stuff_warning_line(ctl, +				"Fetchmail could not get mail from %s@%s.",  +				ctl->remotename, +				ctl->server.truename); +			stuff_warning_line(ctl,  +			       "The attempt to get authorization failed."); +			stuff_warning_line(ctl,  +			       "This probably means your password is invalid."); +			close_warning_by_mail(ctl); +			ctl->authfailcount++; +		    }  		}  		goto cleanUp;  	    } @@ -1925,7 +1994,7 @@ const struct method *proto;	/* protocol method table */  		    if (!check_only && ctl->skipped)  		    {  			clean_skipped_list(&ctl->skipped); -			send_warning(ctl); +			send_size_warnings(ctl);  		    }  		}  	    } while @@ -2011,14 +2080,13 @@ closeUp:  #if defined(HAVE_STDARG_H)  void gen_send(int sock, const char *fmt, ... ) -/* assemble command in printf(3) style and send to the server */  #else  void gen_send(sock, fmt, va_alist) -/* assemble command in printf(3) style and send to the server */  int sock;		/* socket to which server is connected */  const char *fmt;	/* printf-style format */  va_dcl  #endif +/* assemble command in printf(3) style and send to the server */  {      char buf [MSGBUFSIZE+1];      va_list ap; @@ -2094,14 +2162,13 @@ int size;	/* length of buffer */  #if defined(HAVE_STDARG_H)  int gen_transact(int sock, const char *fmt, ... ) -/* assemble command in printf(3) style, send to server, accept a response */  #else  int gen_transact(int sock, fmt, va_alist) -/* assemble command in printf(3) style, send to server, accept a response */  int sock;		/* socket to which server is connected */  const char *fmt;	/* printf-style format */  va_dcl  #endif +/* assemble command in printf(3) style, send to server, accept a response */  {      int ok;      char buf [MSGBUFSIZE+1]; diff --git a/fetchmail.c b/fetchmail.c index bcad08fb..0e0d3f46 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -367,6 +367,9 @@ int main (int argc, char **argv)      /* pick up interactively any passwords we need but don't have */       for (ctl = querylist; ctl; ctl = ctl->next) +    { +	ctl->authfailcount = 0; +  	if (ctl->active && !(implicitmode && ctl->server.skip)&&!ctl->password)  	{  	    if (ctl->server.preauthenticate == A_KERBEROS_V4 || @@ -406,6 +409,7 @@ int main (int argc, char **argv)  #undef	PASSWORD_PROMPT  	    }  	} +    }      /*       * Maybe time to go to demon mode... @@ -481,6 +485,13 @@ int main (int argc, char **argv)  	batchcount = 0;  	for (ctl = querylist; ctl; ctl = ctl->next)  	{ +	    if (ctl->authfailcount) +	    { +		error(0, -1,  +		      "poll of %s skipped until authentication is unwedged", +		      ctl->server.pollname); +		continue; +	    }  	    if (ctl->active && !(implicitmode && ctl->server.skip))  	    {  		/* check skip interval first so that it counts all polls */ diff --git a/fetchmail.h b/fetchmail.h index 7558984d..73e0b8ec 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -251,6 +251,7 @@ struct query      flag active;		/* should we actually poll this server? */      const char *destaddr;	/* destination host for this query */      int errcount;		/* count transient errors in last pass */ +    int authfailcount;		/* count authentication failures this run */      int smtp_socket;		/* socket descriptor for SMTP connection */      unsigned int uid;		/* UID of user to deliver to */      struct idlist *skipped;	/* messages skipped on the mail server */ | 
