From 27235dd398ab05cf7f992efe2027efc70fa0da0c Mon Sep 17 00:00:00 2001 From: tedu Date: Fri, 2 Sep 2016 18:12:30 +0000 Subject: [PATCH] add support for the verified auth ioctls using 'persist' rules. ok deraadt henning --- doas.1 | 6 ++++-- doas.c | 37 ++++++++++++++++++++++++++++--------- doas.conf.5 | 3 +++ doas.h | 1 + parse.y | 6 +++++- 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/doas.1 b/doas.1 index dd98081..16983aa 100644 --- a/doas.1 +++ b/doas.1 @@ -21,7 +21,7 @@ .Nd execute commands as another user .Sh SYNOPSIS .Nm doas -.Op Fl ns +.Op Fl Lns .Op Fl C Ar config .Op Fl u Ar user .Ar command @@ -57,7 +57,9 @@ or .Sq deny will be printed on standard output, depending on command matching results. -In either case, no command is executed. +No command is executed. +.It Fl L +Clear any persisted authorizations from previous invocations. .It Fl n Non interactive mode, fail if .Nm diff --git a/doas.c b/doas.c index 3474a7c..f1a7c34 100644 --- a/doas.c +++ b/doas.c @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -46,7 +47,7 @@ version(void) static void __dead usage(void) { - fprintf(stderr, "usage: doas [-nsv] " + fprintf(stderr, "usage: doas [-Lnsv] " #ifdef HAVE_BSD_AUTH_H "[-a style] " #endif @@ -221,10 +222,18 @@ checkconfig(const char *confpath, int argc, char **argv, #ifdef HAVE_BSD_AUTH_H static void -authuser(char *myname, char *login_style) +authuser(char *myname, char *login_style, int persist) { char *challenge = NULL, *response, rbuf[1024], cbuf[128]; auth_session_t *as; + int fd = -1; + + if (persist) + fd = open("/dev/tty", O_RDWR); + if (fd != -1) { + if (ioctl(fd, TIOCCHKVERAUTH) == 0) + goto good; + } if (!(as = auth_userchallenge(myname, login_style, "auth-doas", &challenge))) @@ -250,10 +259,16 @@ authuser(char *myname, char *login_style) errc(1, EPERM, NULL); } explicit_bzero(rbuf, sizeof(rbuf)); +good: + if (fd != -1) { + int secs = 10 * 60; + ioctl(fd, TIOCSETVERAUTH, &secs); + close(fd); + } } #elif HAVE_SHADOW_H static void -authuser(const char *myname, const char *login_style) +authuser(const char *myname, const char *login_style, int persist) { const char *hash; char *encrypted; @@ -326,17 +341,14 @@ main(int argc, char **argv) setprogname("doas"); - if (pledge("stdio rpath getpw tty recvfd proc exec id", NULL) == -1) - err(1, "pledge"); - closefrom(STDERR_FILENO + 1); uid = getuid(); #ifdef HAVE_BSD_AUTH_H -# define OPTSTRING "a:C:nsu:v" +# define OPTSTRING "a:C:Lnsu:v" #else -# define OPTSTRING "+C:nsu:v" +# define OPTSTRING "+C:Lnsu:v" #endif while ((ch = getopt(argc, argv, OPTSTRING)) != -1) { @@ -349,6 +361,13 @@ main(int argc, char **argv) case 'C': confpath = optarg; break; + case 'L': +#ifdef TIOCCLRVERAUTH + i = open("/dev/tty", O_RDWR); + if (i != -1) + ioctl(i, TIOCCLRVERAUTH); + exit(i == -1); +#endif case 'u': if (parseuid(optarg, &target) != 0) errx(1, "unknown user"); @@ -431,7 +450,7 @@ main(int argc, char **argv) if (nflag) errx(1, "Authorization required"); - authuser(myname, login_style); + authuser(myname, login_style, rule->options & PERSIST); } #elif HAVE_PAM_APPL_H pw = getpwuid(target); diff --git a/doas.conf.5 b/doas.conf.5 index e6c115b..cfe1cf3 100644 --- a/doas.conf.5 +++ b/doas.conf.5 @@ -45,6 +45,9 @@ Options are: .Bl -tag -width keepenv .It Ic nopass The user is not required to enter a password. +.It Ic persist +After the user successfully authenticates, do not ask for a password +again for some time. .It Ic keepenv The user's environment is maintained. The default is to reset the environment, except for the variables diff --git a/doas.h b/doas.h index 2f95310..062c387 100644 --- a/doas.h +++ b/doas.h @@ -22,3 +22,4 @@ char **prepenv(struct rule *); #define NOPASS 0x1 #define KEEPENV 0x2 +#define PERSIST 0x4 diff --git a/parse.y b/parse.y index 506eb68..43732a6 100644 --- a/parse.y +++ b/parse.y @@ -60,7 +60,7 @@ int yyparse(void); %} %token TPERMIT TDENY TAS TCMD TARGS -%token TNOPASS TKEEPENV TSETENV +%token TNOPASS TPERSIST TKEEPENV TSETENV %token TSTRING %% @@ -122,6 +122,9 @@ options: /* none */ { option: TNOPASS { $$.options = NOPASS; $$.envlist = NULL; + } | TPERSIST { + $$.options = PERSIST; + $$.envlist = NULL; } | TKEEPENV { $$.options = KEEPENV; $$.envlist = NULL; @@ -208,6 +211,7 @@ struct keyword { { "cmd", TCMD }, { "args", TARGS }, { "nopass", TNOPASS }, + { "persist", TPERSIST }, { "keepenv", TKEEPENV }, { "setenv", TSETENV }, }; -- 2.39.2