File fetchmail-re-read-passwordfile-on-every-poll.patch of Package fetchmail.22690

From: Matthew Ogilvie <mmogilvi+fml@zoho.com>
Date: Fri, 9 Jun 2017 18:20:40 -0600
Subject: re-read passwordfile on every poll
Git-repo: https://gitlab.com/fetchmail/fetchmail.git
Git-commit: c2b96715bb39b9cfd1c751eae6b0111bed9c8581

---
 fetchmail.c   | 101 +++++++++++++++++++++++++++++++++-----------------
 fetchmail.man |   9 ++---
 2 files changed, 70 insertions(+), 40 deletions(-)

diff --git a/fetchmail.c b/fetchmail.c
index e2828a4f..eb277c28 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -586,48 +586,19 @@ int main(int argc, char **argv)
 		}
 
 		ctl->password = xstrdup(msg);
+		ctl->passwordfile = NULL;
 		memset(msg, 0x55, mi-msg);
 	    } else if (ctl->passwordfile) {
-		int fd = open(ctl->passwordfile, O_RDONLY);
-		char msg[PASSWORDLEN+1];
-		char *newline;
-		int res;
-
-		if (fd == -1) {
-		    int saveErrno = errno;
-		    fprintf(stderr,
-			    GT_("fetchmail: unable to open %s: %s\n"),
-			    ctl->passwordfile,
-			    strerror(saveErrno));
-		    return PS_AUTHFAIL;
-		}
-
-		res = read(fd, msg, sizeof(msg)-1);
-		if (res == -1 || close(fd) == -1) {
+		if (access(ctl->passwordfile, R_OK) != 0) {
 		    int saveErrno = errno;
 		    fprintf(stderr,
-			    GT_("fetchmail: error reading %s: %s\n"),
+			    GT_("fetchmail: unable to access %s: %s\n"),
 			    ctl->passwordfile,
 			    strerror(saveErrno));
 		    return PS_AUTHFAIL;
 		}
-		msg[res] = '\0';
-
-		newline = memchr(msg, '\n', res);
-		if (newline != NULL) {
-		    *newline = '\0';
-		}
-
-		if (strlen(msg) == 0) {
-		    fprintf(stderr,
-			    GT_("fetchmail: empty password read from %s\n"),
-			    ctl->passwordfile);
-		    memset(msg, 0x55, res);
-		    return PS_AUTHFAIL;
-		}
-
-		ctl->password = xstrdup(msg);
-		memset(msg, 0x55, res);
+		ctl->password = xstrdup("dummy");
+		/* file will be read/re-read on each poll interval below */
 	    } else if (!isatty(0)) {
 		fprintf(stderr,
 			GT_("fetchmail: can't find a password for %s@%s.\n"),
@@ -643,6 +614,8 @@ int main(int argc, char **argv)
 		ctl->password = xstrdup((char *)fm_getpassword(tmpbuf));
 		free(tmpbuf);
 	    }
+	} else {
+	    ctl->passwordfile = NULL;
 	}
     }
 
@@ -843,6 +816,65 @@ int main(int argc, char **argv)
 
 		    dofastuidl = 0; /* this is reset in the driver if required */
 
+		    if (ctl->passwordfile) {
+			int fd = open(ctl->passwordfile, O_RDONLY);
+			char msg[PASSWORDLEN+1];
+			char *newline;
+			int res;
+
+			if (fd == -1) {
+			    int saveErrno = errno;
+			    report(stderr,
+				   GT_("fetchmail: unable to open %s: %s\n"),
+				   ctl->passwordfile,
+				   strerror(saveErrno));
+			    continue;
+			}
+
+			res = read(fd, msg, sizeof(msg)-1);
+			close(fd);
+			if (res == -1) {
+			    int saveErrno = errno;
+			    report(stderr,
+				   GT_("fetchmail: error reading %s: %s\n"),
+				   ctl->passwordfile,
+				   strerror(saveErrno));
+			    continue;
+			}
+			msg[res] = '\0';
+
+			newline = memchr(msg, '\n', res);
+			if (newline != NULL) {
+			    *newline = '\0';
+			}
+
+			if (strlen(msg) == 0) {
+			    report(stderr,
+				   GT_("fetchmail: empty password read from %s\n"),
+				   ctl->passwordfile);
+			    memset(msg, 0x55, res);
+			    continue;
+			}
+
+			if (ctl->password) {
+			    memset(ctl->password, 0x55, strlen(ctl->password));
+			    xfree(ctl->password);
+			}
+			ctl->password = xstrdup(msg);
+			memset(msg, 0x55, res);
+		    }
+
+		    if (!ctl->password) {
+			/* This shouldn't be reachable (all cases caught
+			 * earlier), but keep it for safety since there
+			 * are many cases.
+			 */
+			report(stderr,
+			       GT_("password is unexpectedly NULL querying %s\n"),
+			       ctl->server.pollname);
+			continue;
+		    }
+
 		    querystatus = query_host(ctl);
 
 		    if (NUM_NONZERO(ctl->fastuidl))
diff --git a/fetchmail.man b/fetchmail.man
index b6309d40..6b375d89 100644
--- a/fetchmail.man
+++ b/fetchmail.man
@@ -877,12 +877,9 @@ See USER AUTHENTICATION below for a complete description.
 .br
 Specifies a file name from which to read the first line to use as the password.
 Useful if something changes the password/token often without regenerating a
-long fetchmailrc file, such as with typical xoauth2 authentication tokens.
+long fetchmailrc file, such as with typical oauth2 authentication tokens.
 Protect the file with appropriate permissions to avoid leaking your password.
-Fetchmail might not re-read the file in daemon mode (-d) unless the
-fetchmailrc file also changes, so it might make sense to run it in
-non-daemon mode from some other background process (cron and/or whatever
-updates the password).
+Fetchmail will re-read the file for each poll when in daemon mode.
 .TP
 .B \-\-passwordfd <integer>
 (Keyword: passwordfd)
@@ -895,7 +892,7 @@ although it could also be a redirected input file
 (equivalent to "fetchmail \-\-passwordfd 5 5</path/to/file").
 Useful if something wants to manage password ownership more securely
 than files, or if the password/token changes often,
-such as with typical xoauth2 authentication tokens.  Normal interactive
+such as with typical oauth2 authentication tokens.  Normal interactive
 mode passwords requires that standard input is a terminal and disables
 echo, but passwordfd does not care.  Do not do something
 like "echo 'password' | fetchmail ...", since echo's arguments are
-- 
2.31.1

openSUSE Build Service is sponsored by