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);