Skip to content

Commit 92b90de

Browse files
author
Rehan
committed
Retry up to 3 times on password authentication failure
1 parent b96106b commit 92b90de

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

doas.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ char **prepenv(const struct rule *, const struct passwd *,
4444
#define PERSIST 0x4
4545
#define NOLOG 0x8
4646

47+
#define AUTH_RETRIES 3
48+
4749
#ifdef USE_PAM
4850
void pamauth(const char *, const char *, int, int, int);
4951
#endif

pam.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,20 @@ pamauth(const char *user, const char *myname, int interactive, int nopass, int p
286286
"\rdoas (%.32s@%.32s) password: ", myname, host);
287287

288288
/* authenticate */
289-
ret = pam_authenticate(pamh, 0);
290-
if (ret != PAM_SUCCESS) {
291-
pamcleanup(ret, sess, cred);
292-
syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname);
293-
errx(1, "Authentication failed");
289+
for (int i = 0; i < AUTH_RETRIES; i++) {
290+
ret = pam_authenticate(pamh, 0);
291+
if (ret != PAM_SUCCESS) {
292+
syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname);
293+
294+
if (i == AUTH_RETRIES - 1) {
295+
pamcleanup(ret, sess, cred);
296+
errx(1, "Authentication failed");
297+
}
298+
else
299+
warnx("Authentication failed");
300+
}
301+
else
302+
break;
294303
}
295304
}
296305

shadow.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,23 +80,32 @@ shadowauth(const char *myname, int persist)
8080
snprintf(cbuf, sizeof(cbuf),
8181
"\rdoas (%.32s@%.32s) password: ", myname, host);
8282
challenge = cbuf;
83-
84-
response = readpassphrase(challenge, rbuf, sizeof(rbuf), RPP_REQUIRE_TTY);
85-
if (response == NULL && errno == ENOTTY) {
86-
syslog(LOG_AUTHPRIV | LOG_NOTICE,
87-
"tty required for %s", myname);
88-
errx(1, "a tty is required");
89-
}
90-
if (response == NULL)
91-
err(1, "readpassphrase");
92-
if ((encrypted = crypt(response, hash)) == NULL) {
83+
int success;
84+
for (int i = 0; i < AUTH_RETRIES; i++) {
85+
success = 1;
86+
response = readpassphrase(challenge, rbuf, sizeof(rbuf), RPP_REQUIRE_TTY);
87+
if (response == NULL && errno == ENOTTY) {
88+
syslog(LOG_AUTHPRIV | LOG_NOTICE,
89+
"tty required for %s", myname);
90+
errx(1, "a tty is required");
91+
}
92+
if (response == NULL)
93+
err(1, "readpassphrase");
94+
if ((encrypted = crypt(response, hash)) == NULL) {
95+
explicit_bzero(rbuf, sizeof(rbuf));
96+
success = 0;
97+
}
9398
explicit_bzero(rbuf, sizeof(rbuf));
94-
errx(1, "Authentication failed");
95-
}
96-
explicit_bzero(rbuf, sizeof(rbuf));
97-
if (strcmp(encrypted, hash) != 0) {
98-
syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname);
99-
errx(1, "Authentication failed");
99+
if (strcmp(encrypted, hash) != 0) {
100+
syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname);
101+
success = 0;
102+
}
103+
if (success)
104+
break;
105+
if (i == AUTH_RETRIES - 1)
106+
errx(1, "Authentication failed");
107+
else
108+
warnx("Authentication failed");
100109
}
101110

102111
#ifdef USE_TIMESTAMP

0 commit comments

Comments
 (0)