shithub: riscv

Download patch

ref: 56e71d5260182e2ac32e09767b7c9440048a1d2f
parent: 4ff5a4febb8a3bf7f58fcf8524761d2c3565778f
author: cinap_lenrek <[email protected]>
date: Thu Jun 20 08:13:51 EDT 2019

upas/smtp: handle temporary authentication failures

under heavy load, factotum can return a "too much activity" error,
which upas/smtpd and upas/smtp should consider a temporary error
instead of a permanent one.

--- a/sys/src/cmd/upas/common/aux.c
+++ b/sys/src/cmd/upas/common/aux.c
@@ -108,3 +108,12 @@
 {
 	return strcmp(path, "/dev/null") != 0;
 }
+
+int
+temperror(void)
+{
+	char err[ERRMAX];
+
+	rerrstr(err, sizeof(err));
+	return strstr(err, "too much activity") != nil || strstr(err, "temporary problem") != nil;
+}
--- a/sys/src/cmd/upas/common/common.h
+++ b/sys/src/cmd/upas/common/common.h
@@ -37,6 +37,7 @@
 String	*escapespecial(String*);
 String	*unescapespecial(String*);
 int	returnable(char*);
+int	temperror(void);
 
 /* folder.c */
 Biobuf	*openfolder(char*, long);
--- a/sys/src/cmd/upas/smtp/smtp.c
+++ b/sys/src/cmd/upas/smtp/smtp.c
@@ -30,8 +30,8 @@
 char*	rcptto(char*);
 char	*rewritezone(char *);
 
-#define Retry	"Retry, Temporary Failure"
-#define Giveup	"Permanent Failure"
+char	Retry[] = "Retry, Temporary Failure";
+char	Giveup[] = "Permanent Failure";
 
 String	*reply;		/* last reply */
 String	*toline;
@@ -468,8 +468,12 @@
 	n = auth_respond(ch, l, usr, sizeof usr, rbuf, sizeof rbuf, auth_getkey,
 		"proto=cram role=client server=%q user=%q",
 		ds->host, user);
-	if(n == -1)
-		return "cannot find SMTP password";
+	if(n == -1){
+		if(temperror())
+			return Retry;
+		syslog(0, "smtp.fail", "failed to get challenge response: %r");
+		return Giveup;
+	}
 	if(usr[0] == 0)
 		return "cannot find user name";
 	for(i = 0; i < n; i++)
@@ -498,6 +502,8 @@
 		"proto=pass service=smtp server=%q user=%q",
 		ds.host, user);
 	if (p == nil) {
+		if(temperror())
+			return Retry;
 		syslog(0, "smtp.fail", "failed to get userpasswd: %r");
 		return Giveup;
 	}
--- a/sys/src/cmd/upas/smtp/smtpd.c
+++ b/sys/src/cmd/upas/smtp/smtpd.c
@@ -1685,9 +1685,7 @@
 		memset(s_to_c(s_resp1_64), 'X', s_len(s_resp1_64));
 		user = s_to_c(s_resp1) + strlen(s_to_c(s_resp1)) + 1;
 		pass = user + strlen(user) + 1;
-//		ai = auth_userpasswd(user, pass);
-//		authenticated = ai != nil;
-authenticated = passauth(user, pass) != -1;
+		authenticated = passauth(user, pass) != -1;
 		memset(pass, 'X', strlen(pass));
 		goto windup;
 	}
@@ -1727,8 +1725,13 @@
 			reply("235 2.0.0 Authentication successful\r\n");
 		} else {
 			rejectcount++;
-			reply("535 5.7.1 Authentication failed\r\n");
-			syslog(0, "smtpd", "authentication failed: %r");
+			if(temperror()){
+				syslog(0, "smtpd", "temporary authentication failure: %r");
+				reply("454 4.7.0 Temporary authentication failure\r\n");
+			} else {
+				syslog(0, "smtpd", "authentication failed: %r");
+				reply("535 5.7.1 Authentication failed\r\n");
+			}
 		}
 		goto bomb_out;
 	}
@@ -1738,7 +1741,10 @@
 		chs = auth_challenge("proto=cram role=server");
 		if (chs == nil) {
 			rejectcount++;
-			reply("501 5.7.5 Couldn't get CRAM-MD5 challenge\r\n");
+			if(temperror())
+				reply("454 4.7.0 Temporary authentication failure\r\n");
+			else
+				reply("501 5.7.5 Couldn't get CRAM-MD5 challenge\r\n");
 			goto bomb_out;
 		}
 		reply("334 %.*[\r\n", chs->nchal, chs->chal);