summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmaan Bhojwani <me@armaanb.net>2021-04-04 12:27:50 -0400
committerArmaan Bhojwani <me@armaanb.net>2021-04-04 12:27:50 -0400
commitb5d211d5d75b031f70e12565e704e7a9c817df83 (patch)
tree959ea1a31c76115ac1442d0f55ecb61196499c4c
parent71b759e2542878de5c75a7101f2400cf35ec6299 (diff)
downloadopendoas-b5d211d5d75b031f70e12565e704e7a9c817df83.tar.gz
Add insult option to doas.confv6.9
-rw-r--r--README.md3
-rw-r--r--doas.c9
-rw-r--r--doas.conf.52
-rw-r--r--doas.h7
-rw-r--r--pam.c11
-rw-r--r--parse.y6
-rw-r--r--shadow.c11
7 files changed, 31 insertions, 18 deletions
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);
}