]> 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.
 
 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
 
 
 ## 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
 }
 
 void
-authfail(void)
+authfail(int opt)
 {
 
 #ifdef DOAS_INSULTS
 {
 
 #ifdef DOAS_INSULTS
-       printf("%s\n", getinsult());
+       if (opt)
+               printf("%s\n", getinsult());
 #endif
 
        errx(1, "Authentication failed");
 #endif
 
        errx(1, "Authentication failed");
@@ -366,7 +367,9 @@ main(int argc, char **argv)
                if (nflag)
                        errx(1, "Authentication required");
 
                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 */
        }
 #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.
 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.
 .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 KEEPENV                0x2
 #define PERSIST                0x4
 #define NOLOG          0x8
+#define INSULT         0x10
 
 #ifdef USE_PAM
 
 #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
 #endif
 
 #ifdef USE_SHADOW
-void shadowauth(const char *, int);
+int shadowauth(const char *, int);
 #endif
 
 #ifdef USE_TIMESTAMP
 #endif
 
 #ifdef USE_TIMESTAMP
@@ -59,4 +60,4 @@ int timestamp_clear(void);
 #endif
 
 const char * getinsult(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);
 }
 
        exit(status);
 }
 
-void
+int
 pamauth(const char *user, const char *myname, int interactive, int nopass, int persist)
 {
        static const struct pam_conv conv = {
 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)
 #endif
 
        if (!user || !myname)
-               authfail();
+               return(5);
 
        ret = pam_start(PAM_SERVICE_NAME, myname, &conv, &pamh);
        if (ret != PAM_SUCCESS)
 
        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)
 
        if (!nopass) {
                if (!interactive)
-                       authfail();
+                       return(5);
 
                /* doas style prompt for pam */
                char host[HOST_NAME_MAX + 1];
 
                /* 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);
                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);
        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 */
        }
 
        /* 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);
        }
 #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 TPERMIT TDENY TAS TCMD TARGS
-%token TNOPASS TNOLOG TPERSIST TKEEPENV TSETENV
+%token TNOPASS TNOLOG TPERSIST TKEEPENV TSETENV TINSULT
 %token TSTRING
 
 %%
 %token TSTRING
 
 %%
@@ -150,6 +150,9 @@ option:             TNOPASS {
                } | TKEEPENV {
                        $$.options = KEEPENV;
                        $$.envlist = NULL;
                } | TKEEPENV {
                        $$.options = KEEPENV;
                        $$.envlist = NULL;
+               } | TINSULT {
+                       $$.options = INSULT;
+                       $$.envlist = NULL;
                } | TSETENV '{' strlist '}' {
                        $$.options = 0;
                        $$.envlist = $3.strlist;
                } | TSETENV '{' strlist '}' {
                        $$.options = 0;
                        $$.envlist = $3.strlist;
@@ -221,6 +224,7 @@ static struct keyword {
        { "persist", TPERSIST },
        { "keepenv", TKEEPENV },
        { "setenv", TSETENV },
        { "persist", TPERSIST },
        { "keepenv", TKEEPENV },
        { "setenv", TSETENV },
+       { "insult", TINSULT },
 };
 
 int
 };
 
 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
 
 #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
 #endif
 
-void
+int
 shadowauth(const char *myname, int persist)
 {
        const char *hash;
 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) {
        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] != '*') {
                }
                hash = sp->sp_pwdp;
        } else if (hash[0] != '*') {
-               authfail();
+               return(5);
        }
 
        char host[HOST_NAME_MAX + 1];
        }
 
        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());
        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);
        }
        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
        }
 
 #ifdef USE_TIMESTAMP
@@ -108,4 +108,5 @@ good:
                close(fd);
        }
 #endif
                close(fd);
        }
 #endif
+       return(0);
 }
 }