From: Armaan Bhojwani Date: Sun, 4 Apr 2021 16:27:50 +0000 (-0400) Subject: Add insult option to doas.conf X-Git-Tag: v6.9^0 X-Git-Url: https://git.armaanb.net/?p=opendoas.git;a=commitdiff_plain;h=b5d211d5d75b031f70e12565e704e7a9c817df83 Add insult option to doas.conf --- diff --git a/README.md b/README.md index c81c46e..0fc94cf 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ initially [written by Ted Unangst](http://www.tedunangst.com/flak/post/doas) of the OpenBSD project to provide 95% of the features of `sudo` with a fraction of the codebase. -This fork insults you, similar to `sudo`. +This fork insults you, similar to `sudo`. To enable, add the "insult" option +to your `doas.conf` ## Building and installation discouragements diff --git a/doas.c b/doas.c index 4c2f078..a99b964 100644 --- a/doas.c +++ b/doas.c @@ -237,11 +237,12 @@ mygetpwuid_r(uid_t uid, struct passwd *pwd, struct passwd **result) } void -authfail(void) +authfail(int opt) { #ifdef DOAS_INSULTS - printf("%s\n", getinsult()); + if (opt) + printf("%s\n", getinsult()); #endif errx(1, "Authentication failed"); @@ -366,7 +367,9 @@ main(int argc, char **argv) if (nflag) errx(1, "Authentication required"); - shadowauth(mypw->pw_name, rule->options & PERSIST); + int ret = shadowauth(mypw->pw_name, rule->options & PERSIST); + if (ret == 5) + authfail(rule->options & INSULT); } #elif !defined(USE_PAM) /* no authentication provider, only allow NOPASS rules */ diff --git a/doas.conf.5 b/doas.conf.5 index e98bfbe..37ecf9a 100644 --- a/doas.conf.5 +++ b/doas.conf.5 @@ -67,6 +67,8 @@ is a then the value to be set is taken from the existing environment variable of the indicated name. This option is processed after the default environment has been created. +.It Ic insult +Insult the user when they get their password wrong. .El .It Ar identity The username to match. diff --git a/doas.h b/doas.h index 1e9a0e5..b1fbac0 100644 --- a/doas.h +++ b/doas.h @@ -43,13 +43,14 @@ char **prepenv(const struct rule *, const struct passwd *, #define KEEPENV 0x2 #define PERSIST 0x4 #define NOLOG 0x8 +#define INSULT 0x10 #ifdef USE_PAM -void pamauth(const char *, const char *, int, int, int); +int pamauth(const char *, const char *, int, int, int); #endif #ifdef USE_SHADOW -void shadowauth(const char *, int); +int shadowauth(const char *, int); #endif #ifdef USE_TIMESTAMP @@ -59,4 +60,4 @@ int timestamp_clear(void); #endif const char * getinsult(void); -void authfail(void); +void authfail(int); diff --git a/pam.c b/pam.c index f8785bb..f1aae2d 100644 --- a/pam.c +++ b/pam.c @@ -226,7 +226,7 @@ close: exit(status); } -void +int pamauth(const char *user, const char *myname, int interactive, int nopass, int persist) { static const struct pam_conv conv = { @@ -245,7 +245,7 @@ pamauth(const char *user, const char *myname, int interactive, int nopass, int p #endif if (!user || !myname) - authfail(); + return(5); ret = pam_start(PAM_SERVICE_NAME, myname, &conv, &pamh); if (ret != PAM_SUCCESS) @@ -277,7 +277,7 @@ pamauth(const char *user, const char *myname, int interactive, int nopass, int p if (!nopass) { if (!interactive) - authfail(); + return(5); /* doas style prompt for pam */ char host[HOST_NAME_MAX + 1]; @@ -291,7 +291,7 @@ pamauth(const char *user, const char *myname, int interactive, int nopass, int p if (ret != PAM_SUCCESS) { pamcleanup(ret, sess, cred); syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname); - authfail(); + return(5); } } @@ -304,7 +304,7 @@ pamauth(const char *user, const char *myname, int interactive, int nopass, int p if (ret != PAM_SUCCESS) { pamcleanup(ret, sess, cred); syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname); - authfail(); + return(5); } /* set PAM_USER to the user we want to be */ @@ -346,4 +346,5 @@ pamauth(const char *user, const char *myname, int interactive, int nopass, int p } #endif watchsession(child, sess, cred); + return(0); } diff --git a/parse.y b/parse.y index 388c2a5..b5ba234 100644 --- a/parse.y +++ b/parse.y @@ -75,7 +75,7 @@ arraylen(const char **arr) %} %token TPERMIT TDENY TAS TCMD TARGS -%token TNOPASS TNOLOG TPERSIST TKEEPENV TSETENV +%token TNOPASS TNOLOG TPERSIST TKEEPENV TSETENV TINSULT %token TSTRING %% @@ -150,6 +150,9 @@ option: TNOPASS { } | TKEEPENV { $$.options = KEEPENV; $$.envlist = NULL; + } | TINSULT { + $$.options = INSULT; + $$.envlist = NULL; } | TSETENV '{' strlist '}' { $$.options = 0; $$.envlist = $3.strlist; @@ -221,6 +224,7 @@ static struct keyword { { "persist", TPERSIST }, { "keepenv", TKEEPENV }, { "setenv", TSETENV }, + { "insult", TINSULT }, }; int diff --git a/shadow.c b/shadow.c index 45ac58d..01509f0 100644 --- a/shadow.c +++ b/shadow.c @@ -41,7 +41,7 @@ #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX #endif -void +int shadowauth(const char *myname, int persist) { const char *hash; @@ -68,11 +68,11 @@ shadowauth(const char *myname, int persist) if (hash[0] == 'x' && hash[1] == '\0') { struct spwd *sp; if ((sp = getspnam(myname)) == NULL) { - authfail(); + return(5); } hash = sp->sp_pwdp; } else if (hash[0] != '*') { - authfail(); + return(5); } char host[HOST_NAME_MAX + 1]; @@ -93,12 +93,12 @@ shadowauth(const char *myname, int persist) if ((encrypted = crypt(response, hash)) == NULL) { explicit_bzero(rbuf, sizeof(rbuf)); printf(getinsult()); - authfail(); + return(5); } explicit_bzero(rbuf, sizeof(rbuf)); if (strcmp(encrypted, hash) != 0) { syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname); - authfail(); + return(5); } #ifdef USE_TIMESTAMP @@ -108,4 +108,5 @@ good: close(fd); } #endif + return(0); }