diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 44 |
1 files changed, 33 insertions, 11 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.381 2011/01/11 06:13:10 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.385 2011/06/23 09:34:13 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -118,6 +118,7 @@ | |||
118 | #endif | 118 | #endif |
119 | #include "monitor_wrap.h" | 119 | #include "monitor_wrap.h" |
120 | #include "roaming.h" | 120 | #include "roaming.h" |
121 | #include "ssh-sandbox.h" | ||
121 | #include "version.h" | 122 | #include "version.h" |
122 | 123 | ||
123 | #ifdef USE_SECURITY_SESSION_API | 124 | #ifdef USE_SECURITY_SESSION_API |
@@ -628,42 +629,62 @@ privsep_preauth(Authctxt *authctxt) | |||
628 | { | 629 | { |
629 | int status; | 630 | int status; |
630 | pid_t pid; | 631 | pid_t pid; |
632 | struct ssh_sandbox *box = NULL; | ||
631 | 633 | ||
632 | /* Set up unprivileged child process to deal with network data */ | 634 | /* Set up unprivileged child process to deal with network data */ |
633 | pmonitor = monitor_init(); | 635 | pmonitor = monitor_init(); |
634 | /* Store a pointer to the kex for later rekeying */ | 636 | /* Store a pointer to the kex for later rekeying */ |
635 | pmonitor->m_pkex = &xxx_kex; | 637 | pmonitor->m_pkex = &xxx_kex; |
636 | 638 | ||
639 | if (use_privsep == PRIVSEP_SANDBOX) | ||
640 | box = ssh_sandbox_init(); | ||
637 | pid = fork(); | 641 | pid = fork(); |
638 | if (pid == -1) { | 642 | if (pid == -1) { |
639 | fatal("fork of unprivileged child failed"); | 643 | fatal("fork of unprivileged child failed"); |
640 | } else if (pid != 0) { | 644 | } else if (pid != 0) { |
641 | debug2("Network child is on pid %ld", (long)pid); | 645 | debug2("Network child is on pid %ld", (long)pid); |
642 | 646 | ||
643 | close(pmonitor->m_recvfd); | 647 | if (box != NULL) |
648 | ssh_sandbox_parent_preauth(box, pid); | ||
644 | pmonitor->m_pid = pid; | 649 | pmonitor->m_pid = pid; |
645 | monitor_child_preauth(authctxt, pmonitor); | 650 | monitor_child_preauth(authctxt, pmonitor); |
646 | close(pmonitor->m_sendfd); | ||
647 | 651 | ||
648 | /* Sync memory */ | 652 | /* Sync memory */ |
649 | monitor_sync(pmonitor); | 653 | monitor_sync(pmonitor); |
650 | 654 | ||
651 | /* Wait for the child's exit status */ | 655 | /* Wait for the child's exit status */ |
652 | while (waitpid(pid, &status, 0) < 0) | 656 | while (waitpid(pid, &status, 0) < 0) { |
653 | if (errno != EINTR) | 657 | if (errno != EINTR) |
654 | break; | 658 | fatal("%s: waitpid: %s", __func__, |
655 | return (1); | 659 | strerror(errno)); |
660 | } | ||
661 | if (WIFEXITED(status)) { | ||
662 | if (WEXITSTATUS(status) != 0) | ||
663 | fatal("%s: preauth child exited with status %d", | ||
664 | __func__, WEXITSTATUS(status)); | ||
665 | } else if (WIFSIGNALED(status)) | ||
666 | fatal("%s: preauth child terminated by signal %d", | ||
667 | __func__, WTERMSIG(status)); | ||
668 | if (box != NULL) | ||
669 | ssh_sandbox_parent_finish(box); | ||
670 | return 1; | ||
656 | } else { | 671 | } else { |
657 | /* child */ | 672 | /* child */ |
658 | |||
659 | close(pmonitor->m_sendfd); | 673 | close(pmonitor->m_sendfd); |
674 | close(pmonitor->m_log_recvfd); | ||
675 | |||
676 | /* Arrange for logging to be sent to the monitor */ | ||
677 | set_log_handler(mm_log_handler, pmonitor); | ||
660 | 678 | ||
661 | /* Demote the child */ | 679 | /* Demote the child */ |
662 | if (getuid() == 0 || geteuid() == 0) | 680 | if (getuid() == 0 || geteuid() == 0) |
663 | privsep_preauth_child(); | 681 | privsep_preauth_child(); |
664 | setproctitle("%s", "[net]"); | 682 | setproctitle("%s", "[net]"); |
683 | if (box != NULL) | ||
684 | ssh_sandbox_child(box); | ||
685 | |||
686 | return 0; | ||
665 | } | 687 | } |
666 | return (0); | ||
667 | } | 688 | } |
668 | 689 | ||
669 | static void | 690 | static void |
@@ -689,7 +710,6 @@ privsep_postauth(Authctxt *authctxt) | |||
689 | fatal("fork of unprivileged child failed"); | 710 | fatal("fork of unprivileged child failed"); |
690 | else if (pmonitor->m_pid != 0) { | 711 | else if (pmonitor->m_pid != 0) { |
691 | verbose("User child is on pid %ld", (long)pmonitor->m_pid); | 712 | verbose("User child is on pid %ld", (long)pmonitor->m_pid); |
692 | close(pmonitor->m_recvfd); | ||
693 | buffer_clear(&loginmsg); | 713 | buffer_clear(&loginmsg); |
694 | monitor_child_postauth(pmonitor); | 714 | monitor_child_postauth(pmonitor); |
695 | 715 | ||
@@ -697,7 +717,10 @@ privsep_postauth(Authctxt *authctxt) | |||
697 | exit(0); | 717 | exit(0); |
698 | } | 718 | } |
699 | 719 | ||
720 | /* child */ | ||
721 | |||
700 | close(pmonitor->m_sendfd); | 722 | close(pmonitor->m_sendfd); |
723 | pmonitor->m_sendfd = -1; | ||
701 | 724 | ||
702 | /* Demote the private keys to public keys. */ | 725 | /* Demote the private keys to public keys. */ |
703 | demote_sensitive_data(); | 726 | demote_sensitive_data(); |
@@ -1119,7 +1142,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1119 | (int) received_sigterm); | 1142 | (int) received_sigterm); |
1120 | close_listen_socks(); | 1143 | close_listen_socks(); |
1121 | unlink(options.pid_file); | 1144 | unlink(options.pid_file); |
1122 | exit(255); | 1145 | exit(received_sigterm == SIGTERM ? 0 : 255); |
1123 | } | 1146 | } |
1124 | if (key_used && key_do_regen) { | 1147 | if (key_used && key_do_regen) { |
1125 | generate_ephemeral_server_key(); | 1148 | generate_ephemeral_server_key(); |
@@ -1310,7 +1333,6 @@ main(int ac, char **av) | |||
1310 | (void)set_auth_parameters(ac, av); | 1333 | (void)set_auth_parameters(ac, av); |
1311 | #endif | 1334 | #endif |
1312 | __progname = ssh_get_progname(av[0]); | 1335 | __progname = ssh_get_progname(av[0]); |
1313 | init_rng(); | ||
1314 | 1336 | ||
1315 | /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ | 1337 | /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ |
1316 | saved_argc = ac; | 1338 | saved_argc = ac; |