hi,
here's an updated diff using /var/doas directory root:wheel owned with a strict 700 permissions. checks and batteries included.

Index: doas.c
===================================================================
RCS file: /cvs/src/usr.bin/doas/doas.c,v
retrieving revision 1.27
diff -u -p -u -p -r1.27 doas.c
--- doas.c    26 Jul 2015 22:44:33 -0000    1.27
+++ doas.c    27 Jul 2015 15:32:27 -0000
@@ -18,12 +18,14 @@
 #include <sys/types.h>
 #include <sys/stat.h>

+#include <fcntl.h>
 #include <limits.h>
 #include <login_cap.h>
 #include <bsd_auth.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 #include <err.h>
 #include <unistd.h>
 #include <pwd.h>
@@ -52,6 +54,39 @@ arraylen(const char **arr)
     return cnt;
 }

+int
+checktimeout (const char *username)
+{
+    char path[PATH_MAX];
+    struct stat stinfo;
+    time_t tv;
+    int fh;
+
+    if (!stat("/var/doas", (struct stat *)&stinfo)) {
+        if(stinfo.st_mode != (S_IFDIR|S_IRWXU))
+ errx(1,"/var/doas must be a directory, owned by root:wheel, and not writable nor readable by world or group");
+        if(stinfo.st_uid != 0 && stinfo.st_gid != 0)
+            errx(1,"/var/doas must belong to root:wheel");
+    } else {
+        perror ("doas");
+        exit(-1);
+    }
+
+ snprintf((char *)&path,PATH_MAX-1,"/var/doas/doas.timestamp.%s",username);
+    tv = time((time_t *)NULL);
+
+ if (!stat(path,(struct stat *)&stinfo) && (tv-stinfo.st_mtim.tv_sec)<pw_timeout)
+            return 1;
+    else {
+        fh = creat(path,S_IRUSR|S_IWUSR);
+        close(fh);
+        return 0;
+    }
+    return 0;
+}
+
+
+
 static int
 parseuid(const char *s, uid_t *uid)
 {
@@ -399,7 +434,7 @@ main(int argc, char **argv, char **envp)
             "failed command for %s: %s", myname, cmdline);
         fail();
     }
-
+ if (pw_timeout && !checktimeout(pw->pw_name)) {
     if (!(rule->options & NOPASS)) {
         if (nflag)
             errx(1, "Authorization required");
@@ -409,6 +444,7 @@ main(int argc, char **argv, char **envp)
             fail();
         }
     }
+}
     envp = copyenv((const char **)envp, rule);

     pw = getpwuid(target);
Index: doas.conf.5
===================================================================
RCS file: /cvs/src/usr.bin/doas/doas.conf.5,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 doas.conf.5
--- doas.conf.5    23 Jul 2015 15:26:37 -0000    1.11
+++ doas.conf.5    27 Jul 2015 15:32:27 -0000
@@ -22,10 +22,21 @@
 .Sh DESCRIPTION
 The
 .Xr doas 1
-utility executes commands as other users according to the rules
+utility executes commands as other users according to the rules and options
 in the
 .Nm
 configuration file.
+.Sh OPTIONS
+.Pp
+The configuration file currently accepts one option:
+.Bd -ragged -offset indent
+.Ic timeout
+tsec
+.Pp
+By default
+.Ic doas
+prompts for password on every execution. This option sets timeout for password reprompt to the tsec seconds value.
+.Sh RULES
 .Pp
 The rules have the following format:
 .Bd -ragged -offset indent
@@ -113,6 +124,9 @@ and additionally permits tedu to run pro
 .Bd -literal -offset indent
 # Non-exhaustive list of variables needed to
 # build release(8) and ports(7)
+# timeout is optional
+timeout 300 # sets the password reprompt time out to 5 minutes
+
 permit nopass keepenv { \e
         FTPMODE PKG_CACHE PKG_PATH SM_PATH SSH_AUTH_SOCK \e
         DESTDIR DISTDIR FETCH_CMD FLAVOR GROUP MAKE MAKECONF \e
Index: doas.h
===================================================================
RCS file: /cvs/src/usr.bin/doas/doas.h,v
retrieving revision 1.4
diff -u -p -u -p -r1.4 doas.h
--- doas.h    24 Jul 2015 06:36:42 -0000    1.4
+++ doas.h    27 Jul 2015 15:32:27 -0000
@@ -10,6 +10,7 @@ struct rule {
     const char **envlist;
 };

+extern time_t pw_timeout;
 extern struct rule **rules;
 extern int nrules, maxrules;
 extern int parse_errors;
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.bin/doas/parse.y,v
retrieving revision 1.10
diff -u -p -u -p -r1.10 parse.y
--- parse.y    24 Jul 2015 06:36:42 -0000    1.10
+++ parse.y    27 Jul 2015 15:32:27 -0000
@@ -17,6 +17,7 @@

 %{
 #include <sys/types.h>
+#include <sys/limits.h>
 #include <ctype.h>
 #include <unistd.h>
 #include <stdint.h>
@@ -24,6 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <err.h>
+#include <errno.h>

 #include "doas.h"

@@ -45,6 +47,7 @@ typedef struct {

 FILE *yyfp;

+time_t pw_timeout;
 struct rule **rules;
 int nrules, maxrules;
 int parse_errors = 0;
@@ -56,7 +59,7 @@ int yyparse(void);
 %}

 %token TPERMIT TDENY TAS TCMD TARGS
-%token TNOPASS TKEEPENV
+%token TNOPASS TKEEPENV TTIMEOUT
 %token TSTRING

 %%
@@ -64,9 +67,21 @@ int yyparse(void);
 grammar:    /* empty */
         | grammar '\n'
         | grammar rule '\n'
+        | grammar timeout '\n'
         | error '\n'
         ;

+timeout:    TTIMEOUT TSTRING {
+            errno = 0;
+            char *ep;
+            pw_timeout = strtol($2.str,&ep,10);
+            if ($2.str[0] == '\0' || *ep != '\0')
+                errx (1, "timeout must be a number of seconds");
+            if (errno == ERANGE && pw_timeout == ULONG_MAX)
+                errx (1, "timeout is out of range");
+            //printf ("Timeout is: %d\n",timeout);
+        };
+
 rule:        action ident target cmd {
             struct rule *r;
             r = calloc(1, sizeof(*r));
@@ -193,6 +208,7 @@ struct keyword {
     { "args", TARGS },
     { "nopass", TNOPASS },
     { "keepenv", TKEEPENV },
+    { "timeout", TTIMEOUT },
 };

 int


Reply via email to