]> git.armaanb.net Git - opendoas.git/commitdiff
Add insult option to doas.conf v6.9
authorArmaan Bhojwani <me@armaanb.net>
Sun, 4 Apr 2021 16:27:50 +0000 (12:27 -0400)
committerArmaan Bhojwani <me@armaanb.net>
Sun, 4 Apr 2021 16:27:50 +0000 (12:27 -0400)
README.md
doas.c
doas.conf.5
doas.h
pam.c
parse.y
shadow.c

index c81c46e2b53efba12b7380c281c684b8392612c7..0fc94cfe3271dc1a0c673497e66809bcb05eced7 100644 (file)
--- 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 4c2f07886d49223921dcfdecf5b807feb75c15f2..a99b964105e3465adb2c947bc974a0610cb87f70 100644 (file)
--- 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 */
index e98bfbe70266c80472a5a73276579c499adcae3f..37ecf9af7313f744c3dc6835192c94639d64d4bd 100644 (file)
@@ -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 1e9a0e599475306424f8768c710b40e5b976f43a..b1fbac089eebd7b85ddca551ab6de2d9f7dad2dd 100644 (file)
--- 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 f8785bb1016be59c49c26e0f36378807f70689ca..f1aae2dd6d3070f8a41af7c3ce3d5eda00e1080e 100644 (file)
--- 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 388c2a57f988a3b4e550f8332f08c3228968be13..b5ba234db7e3f6f1f3abf1e90c1eaf74ddd2b53d 100644 (file)
--- 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
index 45ac58d2e5b12ed92cb11266f5c3f9e616752e0c..01509f03df15d25315b0de364fd40341bd2d51bb 100644 (file)
--- 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);
 }