View | Details | Raw Unified | Return to bug 2615
Collapse All | Expand All

(-)a/sshd.c (-2 / +96 lines)
Lines 241-250 Buffer loginmsg; Link Here
241
/* Unprivileged user */
241
/* Unprivileged user */
242
struct passwd *privsep_pw = NULL;
242
struct passwd *privsep_pw = NULL;
243
243
244
/* Pid of process backing up login_grace_time alarm. */
245
pid_t grace_watchdog_pid = -1;
246
#define	GRACE_WATCHDOG_TRESHOLD 10
247
244
/* Prototypes for various functions defined later in this file. */
248
/* Prototypes for various functions defined later in this file. */
245
void destroy_sensitive_data(void);
249
void destroy_sensitive_data(void);
246
void demote_sensitive_data(void);
250
void demote_sensitive_data(void);
247
static void do_ssh2_kex(void);
251
static void do_ssh2_kex(void);
252
static void stop_grace_watchdog();
248
253
249
/*
254
/*
250
 * Close all listening sockets
255
 * Close all listening sockets
Lines 354-365 grace_alarm_handler(int sig) Link Here
354
		signal(SIGTERM, SIG_IGN);
359
		signal(SIGTERM, SIG_IGN);
355
		kill(0, SIGTERM);
360
		kill(0, SIGTERM);
356
	}
361
	}
362
	stop_grace_watchdog();
357
363
358
	/* Log error and exit. */
364
	/* Log error and exit. */
359
	sigdie("Timeout before authentication for %s port %d",
365
	sigdie("Timeout before authentication for %s port %d",
360
	    ssh_remote_ipaddr(active_state), ssh_remote_port(active_state));
366
	    ssh_remote_ipaddr(active_state), ssh_remote_port(active_state));
361
}
367
}
362
368
369
static inline void
370
sleep_reliably(unsigned int seconds)
371
{
372
	while (seconds > 0)
373
		seconds = sleep(seconds);
374
}
375
376
/*
377
 * Implements watchdog process, which backs up login_grace_time alarm.
378
 *
379
 * If the main process is hung in a syscall, SIGALRM is queued but not
380
 * delivered and the connection stays unauthenticated for too long.
381
 *
382
 * This function forks of a watchdog process, that sends the main process
383
 * a SIGTERM, if it does neither authenticate nor exit before
384
 * (login_grace_time + GRACE_WATCHDOG_TRESHOLD).
385
 * If the main process does not react to SIGTERM, SIGKILL is sent after
386
 * additional GRACE_WATCHDOG_TRESHOLD seconds.
387
 */
388
static void
389
start_grace_watchdog(int login_grace_time)
390
{
391
	pid_t ppid;
392
393
	if (login_grace_time == 0)
394
		return;
395
396
	if (grace_watchdog_pid != -1) {
397
		error("login_grace_time watchdog process already running");
398
		return;
399
	}
400
401
	grace_watchdog_pid = fork();
402
	if (grace_watchdog_pid == -1)
403
		fatal("fork of login_grace_time watchdog process failed");
404
	else if (grace_watchdog_pid > 0)
405
		return;
406
407
	/* child */
408
	ppid = getppid();
409
410
	/* close open fds, including client socket and startup_pipe */
411
	closefrom(3);
412
413
	/* kill the monitor with SIGTERM after timeout + treshold */
414
	sleep_reliably(login_grace_time + GRACE_WATCHDOG_TRESHOLD);
415
	if (getppid() != ppid) {
416
		debug("login_grace_time watchdog still active, "
417
		    "but watched process %d already exited.", (int)ppid);
418
		exit(0);
419
	}
420
	error("Timeout before authentication for %s. Killing process %d "
421
	    "with SIGTERM.", ssh_remote_ipaddr(active_state), (int)ppid);
422
	kill(ppid, SIGTERM);
423
424
	/* if neccessary, kill it with SIGKILL */
425
	sleep_reliably(GRACE_WATCHDOG_TRESHOLD);
426
	if (getppid() != ppid)
427
		exit(0);
428
	error("Watched process %d did not respond to SIGTERM. "
429
	    "Killing it with SIGKILL.", (int)ppid);
430
	kill(ppid, SIGKILL);
431
432
	/* give up */
433
	sleep_reliably(GRACE_WATCHDOG_TRESHOLD);
434
	if (getppid() == ppid) {
435
		error("login_grace_time watchdog failed to kill %d", (int)ppid);
436
		exit(255);
437
	}
438
	exit(0);
439
}
440
441
/* kill grace watchdog process */
442
static void
443
stop_grace_watchdog()
444
{
445
	if (grace_watchdog_pid == -1) {
446
		debug3("login_grace_time watchdog process not running");
447
		return;
448
	}
449
450
	kill(grace_watchdog_pid, SIGTERM);
451
	grace_watchdog_pid = -1;
452
}
453
363
static void
454
static void
364
sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
455
sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
365
{
456
{
Lines 608-613 privsep_preauth(Authctxt *authctxt) Link Here
608
		/* child */
699
		/* child */
609
		close(pmonitor->m_sendfd);
700
		close(pmonitor->m_sendfd);
610
		close(pmonitor->m_log_recvfd);
701
		close(pmonitor->m_log_recvfd);
702
		grace_watchdog_pid = -1;
611
703
612
		/* Arrange for logging to be sent to the monitor */
704
		/* Arrange for logging to be sent to the monitor */
613
		set_log_handler(mm_log_handler, pmonitor);
705
		set_log_handler(mm_log_handler, pmonitor);
Lines 1989-1996 main(int ac, char **av) Link Here
1989
	 * are about to discover the bug.
2081
	 * are about to discover the bug.
1990
	 */
2082
	 */
1991
	signal(SIGALRM, grace_alarm_handler);
2083
	signal(SIGALRM, grace_alarm_handler);
1992
	if (!debug_flag)
2084
	if (!debug_flag) {
1993
		alarm(options.login_grace_time);
2085
		alarm(options.login_grace_time);
2086
		start_grace_watchdog(options.login_grace_time);
2087
	}
1994
2088
1995
	sshd_exchange_identification(ssh, sock_in, sock_out);
2089
	sshd_exchange_identification(ssh, sock_in, sock_out);
1996
	packet_set_nonblocking();
2090
	packet_set_nonblocking();
Lines 2038-2043 main(int ac, char **av) Link Here
2038
	 */
2132
	 */
2039
	alarm(0);
2133
	alarm(0);
2040
	signal(SIGALRM, SIG_DFL);
2134
	signal(SIGALRM, SIG_DFL);
2135
	stop_grace_watchdog();
2041
	authctxt->authenticated = 1;
2136
	authctxt->authenticated = 1;
2042
	if (startup_pipe != -1) {
2137
	if (startup_pipe != -1) {
2043
		close(startup_pipe);
2138
		close(startup_pipe);
2044
- 

Return to bug 2615