]> git.armaanb.net Git - opendoas.git/commitdiff
add support for the verified auth ioctls using 'persist' rules. ok deraadt henning
authortedu <tedu>
Fri, 2 Sep 2016 18:12:30 +0000 (18:12 +0000)
committerDuncaen <mail@duncano.de>
Mon, 11 Dec 2017 15:28:56 +0000 (16:28 +0100)
doas.1
doas.c
doas.conf.5
doas.h
parse.y

diff --git a/doas.1 b/doas.1
index dd98081cb0c971d56416d106e1e0a4f9a275bebb..16983aa995a5daaeec404e881549f9ec0caaaab9 100644 (file)
--- a/doas.1
+++ b/doas.1
@@ -21,7 +21,7 @@
 .Nd execute commands as another user
 .Sh SYNOPSIS
 .Nm doas
 .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
 .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.
 .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
 .It Fl n
 Non interactive mode, fail if
 .Nm
diff --git a/doas.c b/doas.c
index 3474a7c92b0ad5d028c47aa49e93a2c5141d7fcb..f1a7c34e7b7372d942261a8d2a84175ad9ead38e 100644 (file)
--- a/doas.c
+++ b/doas.c
@@ -17,6 +17,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/ioctl.h>
 
 #include <limits.h>
 #include <string.h>
 
 #include <limits.h>
 #include <string.h>
@@ -46,7 +47,7 @@ version(void)
 static void __dead
 usage(void)
 {
 static void __dead
 usage(void)
 {
-       fprintf(stderr, "usage: doas [-nsv] "
+       fprintf(stderr, "usage: doas [-Lnsv] "
 #ifdef HAVE_BSD_AUTH_H
            "[-a style] "
 #endif
 #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
 
 #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;
 {
        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)))
 
        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));
                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
 }
 #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;
 {
        const char *hash;
        char *encrypted;
@@ -326,17 +341,14 @@ main(int argc, char **argv)
 
        setprogname("doas");
 
 
        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
        closefrom(STDERR_FILENO + 1);
 
        uid = getuid();
 
 #ifdef HAVE_BSD_AUTH_H
-# define OPTSTRING "a:C:nsu:v"
+# define OPTSTRING "a:C:Lnsu:v"
 #else
 #else
-# define OPTSTRING "+C:nsu:v"
+# define OPTSTRING "+C:Lnsu:v"
 #endif
 
        while ((ch = getopt(argc, argv, OPTSTRING)) != -1) {
 #endif
 
        while ((ch = getopt(argc, argv, OPTSTRING)) != -1) {
@@ -349,6 +361,13 @@ main(int argc, char **argv)
                case 'C':
                        confpath = optarg;
                        break;
                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");
                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");
 
                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);
        }
 #elif HAVE_PAM_APPL_H
        pw = getpwuid(target);
index e6c115b3890a012ffcfd438ac8fec7f40593e157..cfe1cf3ad2eddd66ea174c1c0b4bf3346ae53e14 100644 (file)
@@ -45,6 +45,9 @@ Options are:
 .Bl -tag -width keepenv
 .It Ic nopass
 The user is not required to enter a password.
 .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
 .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 2f95310d6e5e30a8a1d5fe1501458dce6bc0733e..062c38725583446a49db2668af229f443a103fc6 100644 (file)
--- a/doas.h
+++ b/doas.h
@@ -22,3 +22,4 @@ char **prepenv(struct rule *);
 
 #define NOPASS         0x1
 #define KEEPENV                0x2
 
 #define NOPASS         0x1
 #define KEEPENV                0x2
+#define PERSIST                0x4
diff --git a/parse.y b/parse.y
index 506eb686bf2fcffc284755185ac548a09db9113d..43732a6291144726e88e82d3925620394ddd9ea1 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -60,7 +60,7 @@ int yyparse(void);
 %}
 
 %token TPERMIT TDENY TAS TCMD TARGS
 %}
 
 %token TPERMIT TDENY TAS TCMD TARGS
-%token TNOPASS TKEEPENV TSETENV
+%token TNOPASS TPERSIST TKEEPENV TSETENV
 %token TSTRING
 
 %%
 %token TSTRING
 
 %%
@@ -122,6 +122,9 @@ options:    /* none */ {
 option:                TNOPASS {
                        $$.options = NOPASS;
                        $$.envlist = NULL;
 option:                TNOPASS {
                        $$.options = NOPASS;
                        $$.envlist = NULL;
+               } | TPERSIST {
+                       $$.options = PERSIST;
+                       $$.envlist = NULL;
                } | TKEEPENV {
                        $$.options = KEEPENV;
                        $$.envlist = NULL;
                } | TKEEPENV {
                        $$.options = KEEPENV;
                        $$.envlist = NULL;
@@ -208,6 +211,7 @@ struct keyword {
        { "cmd", TCMD },
        { "args", TARGS },
        { "nopass", TNOPASS },
        { "cmd", TCMD },
        { "args", TARGS },
        { "nopass", TNOPASS },
+       { "persist", TPERSIST },
        { "keepenv", TKEEPENV },
        { "setenv", TSETENV },
 };
        { "keepenv", TKEEPENV },
        { "setenv", TSETENV },
 };