@@ -111,7 +111,6 @@ static const char default_user_keyword[] = "DEFAULT:";
111
111
#define default_user_keyword_len_without_colon (sizeof(default_user_keyword)-2)
112
112
113
113
static int opt_quiet = 0 ;
114
- static int opt_direct = 0 ;
115
114
116
115
static const char * policy_program = QREXEC_POLICY_PROGRAM ;
117
116
@@ -262,7 +261,7 @@ static int handle_agent_hello(libvchan_t *ctrl, const char *domain_name)
262
261
static void signal_handler (int sig );
263
262
264
263
/* do the preparatory tasks, needed before entering the main event loop */
265
- static void init (int xid )
264
+ static void init (int xid , bool opt_direct )
266
265
{
267
266
char qrexec_error_log_name [256 ];
268
267
int logfd ;
@@ -283,19 +282,21 @@ static void init(int xid)
283
282
startup_timeout = MAX_STARTUP_TIME_DEFAULT ;
284
283
}
285
284
286
- int pipes [2 ];
285
+ int pipes [2 ] = { -1 , -1 };
286
+ bool have_timeout = getenv ("QREXEC_STARTUP_NOWAIT" ) == NULL ;
287
287
if (!opt_direct ) {
288
- if (pipe2 (pipes , O_CLOEXEC ))
288
+ if (have_timeout && pipe2 (pipes , O_CLOEXEC ))
289
289
err (1 , "pipe2()" );
290
290
switch (pid = fork ()) {
291
291
case -1 :
292
292
PERROR ("fork" );
293
293
exit (1 );
294
294
case 0 :
295
- close (pipes [0 ]);
295
+ if (have_timeout )
296
+ close (pipes [0 ]);
296
297
break ;
297
298
default :
298
- if (getenv ( "QREXEC_STARTUP_NOWAIT" ) )
299
+ if (! have_timeout )
299
300
exit (0 );
300
301
close (pipes [1 ]);
301
302
if (!opt_quiet )
@@ -353,8 +354,10 @@ static void init(int xid)
353
354
exit (1 );
354
355
}
355
356
356
- dup2 (logfd , 1 );
357
- dup2 (logfd , 2 );
357
+ if (dup2 (logfd , 1 ) != 1 || dup2 (logfd , 2 ) != 2 )
358
+ err (1 , "dup2()" );
359
+ if (logfd > 2 )
360
+ close (logfd );
358
361
359
362
if (setsid () < 0 ) {
360
363
PERROR ("setsid()" );
@@ -363,18 +366,22 @@ static void init(int xid)
363
366
}
364
367
365
368
int wait_fd ;
366
- vchan = libvchan_client_init_async (xid , VCHAN_BASE_PORT , & wait_fd );
369
+ if (have_timeout ) {
370
+ vchan = libvchan_client_init_async (xid , VCHAN_BASE_PORT , & wait_fd );
371
+ if (vchan != NULL && qubes_wait_for_vchan_connection_with_timeout (
372
+ vchan , wait_fd , false, startup_timeout ) < 0 ) {
373
+ if (!opt_direct && write (pipes [1 ], "\1" , 1 )) {}
374
+ LOG (ERROR , "qrexec connection timeout" );
375
+ exit (3 );
376
+ }
377
+ } else {
378
+ /* No timeout in this case */
379
+ vchan = libvchan_client_init (xid , VCHAN_BASE_PORT );
380
+ }
367
381
if (!vchan ) {
368
382
LOG (ERROR , "Cannot create data vchan connection" );
369
383
exit (3 );
370
384
}
371
- if (qubes_wait_for_vchan_connection_with_timeout (
372
- vchan , wait_fd , false, startup_timeout ) < 0 ) {
373
- if (write (pipes [1 ], "\1" , 1 )) {}
374
- LOG (ERROR , "qrexec connection timeout" );
375
- exit (3 );
376
- }
377
-
378
385
protocol_version = handle_agent_hello (vchan , remote_domain_name );
379
386
if (protocol_version < 0 ) {
380
387
exit (1 );
@@ -417,7 +424,7 @@ static void init(int xid)
417
424
err (1 , "sigaction" );
418
425
if (sigaction (SIGTERM , & sigterm_action , NULL ))
419
426
err (1 , "sigaction" );
420
- if (!opt_direct ) {
427
+ if (have_timeout && !opt_direct ) {
421
428
if (write (pipes [1 ], "" , 1 ) != 1 )
422
429
err (1 , "write(pipe)" );
423
430
close (pipes [1 ]);
@@ -1528,6 +1535,7 @@ int main(int argc, char **argv)
1528
1535
{
1529
1536
int i , opt ;
1530
1537
sigset_t selectmask ;
1538
+ bool opt_direct = false;
1531
1539
1532
1540
{
1533
1541
int null_fd = open ("/dev/null" , O_RDONLY |O_NOCTTY );
@@ -1571,7 +1579,7 @@ int main(int argc, char **argv)
1571
1579
remote_domain_name = argv [optind + 1 ];
1572
1580
if (argc - optind >= 3 )
1573
1581
default_user = argv [optind + 2 ];
1574
- init (remote_domain_id );
1582
+ init (remote_domain_id , opt_direct );
1575
1583
1576
1584
sigemptyset (& selectmask );
1577
1585
sigaddset (& selectmask , SIGCHLD );
0 commit comments