summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-06-20 12:13:51 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-06-20 12:13:51 +0200
commit56e71d5260182e2ac32e09767b7c9440048a1d2f (patch)
treeffe72d2b5433be952c25ffe861d737d9cd760fad
parent4ff5a4febb8a3bf7f58fcf8524761d2c3565778f (diff)
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.
-rw-r--r--sys/src/cmd/upas/common/aux.c9
-rw-r--r--sys/src/cmd/upas/common/common.h1
-rw-r--r--sys/src/cmd/upas/smtp/smtp.c14
-rw-r--r--sys/src/cmd/upas/smtp/smtpd.c18
4 files changed, 32 insertions, 10 deletions
diff --git a/sys/src/cmd/upas/common/aux.c b/sys/src/cmd/upas/common/aux.c
index 985e3f296..28e4492b1 100644
--- a/sys/src/cmd/upas/common/aux.c
+++ b/sys/src/cmd/upas/common/aux.c
@@ -108,3 +108,12 @@ returnable(char *path)
{
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;
+}
diff --git a/sys/src/cmd/upas/common/common.h b/sys/src/cmd/upas/common/common.h
index f7e8ad5e9..c2bc45878 100644
--- a/sys/src/cmd/upas/common/common.h
+++ b/sys/src/cmd/upas/common/common.h
@@ -37,6 +37,7 @@ int shellchars(char*);
String *escapespecial(String*);
String *unescapespecial(String*);
int returnable(char*);
+int temperror(void);
/* folder.c */
Biobuf *openfolder(char*, long);
diff --git a/sys/src/cmd/upas/smtp/smtp.c b/sys/src/cmd/upas/smtp/smtp.c
index db8febfec..674682345 100644
--- a/sys/src/cmd/upas/smtp/smtp.c
+++ b/sys/src/cmd/upas/smtp/smtp.c
@@ -30,8 +30,8 @@ void quit(char*);
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 @@ smtpcram(DS *ds)
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 @@ doauth(char *methods)
"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;
}
diff --git a/sys/src/cmd/upas/smtp/smtpd.c b/sys/src/cmd/upas/smtp/smtpd.c
index 677717509..aa05c6a45 100644
--- a/sys/src/cmd/upas/smtp/smtpd.c
+++ b/sys/src/cmd/upas/smtp/smtpd.c
@@ -1685,9 +1685,7 @@ auth(String *mech, String *resp)
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 @@ windup:
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 @@ windup:
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);