17
17
18
18
#include <sys/types.h>
19
19
#include <sys/stat.h>
20
+ #include <sys/ioctl.h>
20
21
21
22
#if defined(HAVE_INTTYPES_H )
22
23
#include <inttypes.h>
39
40
#include <grp.h>
40
41
#include <syslog.h>
41
42
#include <errno.h>
43
+ #include <fcntl.h>
42
44
43
45
#if defined(HAVE_LOGIN_CAP_H )
44
46
#include <login_cap.h>
@@ -83,18 +85,6 @@ errc(int eval, int code, const char *format)
83
85
}
84
86
#endif
85
87
86
- size_t
87
- arraylen (const char * * arr )
88
- {
89
- size_t cnt = 0 ;
90
-
91
- while (* arr ) {
92
- cnt ++ ;
93
- arr ++ ;
94
- }
95
- return cnt ;
96
- }
97
-
98
88
static int
99
89
parseuid (const char * s , uid_t * uid )
100
90
{
@@ -254,6 +244,54 @@ checkconfig(const char *confpath, int argc, char **argv,
254
244
}
255
245
}
256
246
247
+ #if defined(USE_BSD_AUTH )
248
+ static void
249
+ authuser (char * myname , char * login_style , int persist )
250
+ {
251
+ char * challenge = NULL , * response , rbuf [1024 ], cbuf [128 ];
252
+ auth_session_t * as ;
253
+ int fd = -1 ;
254
+
255
+ if (persist )
256
+ fd = open ("/dev/tty" , O_RDWR );
257
+ if (fd != -1 ) {
258
+ if (ioctl (fd , TIOCCHKVERAUTH ) == 0 )
259
+ goto good ;
260
+ }
261
+
262
+ if (!(as = auth_userchallenge (myname , login_style , "auth-doas" ,
263
+ & challenge )))
264
+ errx (1 , "Authorization failed" );
265
+ if (!challenge ) {
266
+ char host [HOST_NAME_MAX + 1 ];
267
+ if (gethostname (host , sizeof (host )))
268
+ snprintf (host , sizeof (host ), "?" );
269
+ snprintf (cbuf , sizeof (cbuf ),
270
+ "\rdoas (%.32s@%.32s) password: " , myname , host );
271
+ challenge = cbuf ;
272
+ }
273
+ response = readpassphrase (challenge , rbuf , sizeof (rbuf ),
274
+ RPP_REQUIRE_TTY );
275
+ if (response == NULL && errno == ENOTTY ) {
276
+ syslog (LOG_AUTHPRIV | LOG_NOTICE ,
277
+ "tty required for %s" , myname );
278
+ errx (1 , "a tty is required" );
279
+ }
280
+ if (!auth_userresponse (as , response , 0 )) {
281
+ syslog (LOG_AUTHPRIV | LOG_NOTICE ,
282
+ "failed auth for %s" , myname );
283
+ errc (1 , EPERM , NULL );
284
+ }
285
+ explicit_bzero (rbuf , sizeof (rbuf ));
286
+ good :
287
+ if (fd != -1 ) {
288
+ int secs = 5 * 60 ;
289
+ ioctl (fd , TIOCSETVERAUTH , & secs );
290
+ close (fd );
291
+ }
292
+ }
293
+ #endif
294
+
257
295
int
258
296
main (int argc , char * * argv )
259
297
{
@@ -283,25 +321,27 @@ main(int argc, char **argv)
283
321
setprogname ("doas" );
284
322
#endif
285
323
286
- /*
287
- if (pledge("stdio rpath getpw tty proc exec id", NULL) == -1)
288
- err(1, "pledge");
289
- */
290
-
291
324
#ifndef linux
292
325
closefrom (STDERR_FILENO + 1 );
293
326
#endif
294
327
295
328
uid = getuid ();
296
329
297
330
while ((ch = getopt (argc , argv , "a:C:nsu:" )) != -1 ) {
331
+ /* while ((ch = getopt(argc, argv, "a:C:Lnsu:")) != -1) { */
298
332
switch (ch ) {
299
333
case 'a' :
300
334
login_style = optarg ;
301
335
break ;
302
336
case 'C' :
303
337
confpath = optarg ;
304
338
break ;
339
+ /* case 'L':
340
+ i = open("/dev/tty", O_RDWR);
341
+ if (i != -1)
342
+ ioctl(i, TIOCCLRVERAUTH);
343
+ exit(i != -1);
344
+ */
305
345
case 'u' :
306
346
if (parseuid (optarg , & target ) != 0 )
307
347
errx (1 , "unknown user" );
@@ -343,9 +383,11 @@ main(int argc, char **argv)
343
383
344
384
if (sflag ) {
345
385
sh = getenv ("SHELL" );
346
- if (sh == NULL || * sh == '\0' )
347
- shargv [0 ] = pw -> pw_shell ;
348
- else
386
+ if (sh == NULL || * sh == '\0' ) {
387
+ shargv [0 ] = strdup (pw -> pw_shell );
388
+ if (shargv [0 ] == NULL )
389
+ err (1 , NULL );
390
+ } else
349
391
shargv [0 ] = sh ;
350
392
argv = shargv ;
351
393
argc = 1 ;
@@ -357,11 +399,14 @@ main(int argc, char **argv)
357
399
exit (1 ); /* fail safe */
358
400
}
359
401
402
+ if (geteuid ())
403
+ errx (1 , "not installed setuid" );
404
+
360
405
parseconfig (DOAS_CONF , 1 );
361
406
362
407
/* cmdline is used only for logging, no need to abort on truncate */
363
408
#ifndef linux
364
- (void ) strlcpy (cmdline , argv [0 ], sizeof (cmdline ));
409
+ (void )strlcpy (cmdline , argv [0 ], sizeof (cmdline ));
365
410
for (i = 1 ; i < argc ; i ++ ) {
366
411
if (strlcat (cmdline , " " , sizeof (cmdline )) >= sizeof (cmdline ))
367
412
break ;
@@ -379,44 +424,18 @@ main(int argc, char **argv)
379
424
380
425
cmd = argv [0 ];
381
426
if (!permit (uid , groups , ngroups , & rule , target , cmd ,
382
- (const char * * )argv + 1 )) {
427
+ (const char * * )argv + 1 )) {
383
428
syslog (LOG_AUTHPRIV | LOG_NOTICE ,
384
429
"failed command for %s: %s" , myname , cmdline );
385
430
errc (1 , EPERM , NULL );
386
431
}
387
432
388
433
if (!(rule -> options & NOPASS )) {
389
434
#if defined(USE_BSD_AUTH )
390
- char * challenge = NULL , * response , rbuf [1024 ], cbuf [128 ];
391
- auth_session_t * as ;
392
-
393
435
if (nflag )
394
436
errx (1 , "Authorization required" );
395
437
396
- if (!(as = auth_userchallenge (myname , login_style , "auth-doas" ,
397
- & challenge )))
398
- errx (1 , "Authorization failed" );
399
- if (!challenge ) {
400
- char host [MAXHOSTNAME + 1 ];
401
- if (gethostname (host , sizeof (host )))
402
- snprintf (host , sizeof (host ), "?" );
403
- snprintf (cbuf , sizeof (cbuf ),
404
- "\rdoas (%.32s@%.32s) password: " , myname , host );
405
- challenge = cbuf ;
406
- }
407
- response = readpassphrase (challenge , rbuf , sizeof (rbuf ),
408
- RPP_REQUIRE_TTY );
409
- if (response == NULL && errno == ENOTTY ) {
410
- syslog (LOG_AUTHPRIV | LOG_NOTICE ,
411
- "tty required for %s" , myname );
412
- errx (1 , "a tty is required" );
413
- }
414
- if (!auth_userresponse (as , response , 0 )) {
415
- syslog (LOG_AUTHPRIV | LOG_NOTICE ,
416
- "failed auth for %s" , myname );
417
- errc (1 , EPERM , NULL );
418
- }
419
- explicit_bzero (rbuf , sizeof (rbuf ));
438
+ authuser (myname , login_style , rule -> options & PERSIST );
420
439
#elif defined(USE_PAM )
421
440
#define PAM_END (msg ) do { \
422
441
syslog(LOG_ERR, "%s: %s", msg, pam_strerror(pamh, pam_err)); \
@@ -518,7 +537,6 @@ main(int argc, char **argv)
518
537
#else
519
538
#error No auth module!
520
539
#endif
521
-
522
540
}
523
541
524
542
/*
0 commit comments