diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2002-03-21 21:23:35 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2002-03-21 21:23:35 +0000 |
commit | 605e71c7e2211dbbeb3e5ae5fc81cd4eb0edf9d8 (patch) | |
tree | 73a37db8fc65d5cb195076cebeba3397fece97ea | |
parent | c0967d536eae53b780d9c6d9061f19eb623a32f7 (diff) |
add privsep_preauth() and remove 1 goto; ok provos@
-rw-r--r-- | usr.bin/ssh/sshd.c | 98 |
1 files changed, 55 insertions, 43 deletions
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c index e3374f8c4b0..0ef16630674 100644 --- a/usr.bin/ssh/sshd.c +++ b/usr.bin/ssh/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.236 2002/03/20 21:08:08 stevesk Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.237 2002/03/21 21:23:34 markus Exp $"); #include <openssl/dh.h> #include <openssl/bn.h> @@ -542,14 +542,51 @@ privsep_preauth_child(void) do_setusercontext(pw); } -static void -privsep_postauth(Authctxt *authctxt, pid_t pid) +static Authctxt* +privsep_preauth(void) { - extern Authctxt *x_authctxt; + Authctxt *authctxt = NULL; int status; + pid_t pid; - /* Wait for the child's exit status */ - waitpid(pid, &status, 0); + /* Set up unprivileged child process to deal with network data */ + monitor = monitor_init(); + /* Store a pointer to the kex for later rekeying */ + monitor->m_pkex = &xxx_kex; + + pid = fork(); + if (pid == -1) { + fatal("fork of unprivileged child failed"); + } else if (pid != 0) { + debug2("Network child is on pid %d", pid); + + close(monitor->m_recvfd); + authctxt = monitor_child_preauth(monitor); + close(monitor->m_sendfd); + + /* Sync memory */ + monitor_sync(monitor); + + /* Wait for the child's exit status */ + waitpid(pid, &status, 0); + + return (authctxt); + } else { + /* child */ + + close(monitor->m_sendfd); + + /* Demote the child */ + if (getuid() == 0 || geteuid() == 0) + privsep_preauth_child(); + } + return (NULL); +} + +static void +privsep_postauth(Authctxt *authctxt) +{ + extern Authctxt *x_authctxt; /* XXX - Remote port forwarding */ x_authctxt = authctxt; @@ -575,7 +612,7 @@ privsep_postauth(Authctxt *authctxt, pid_t pid) if (monitor->m_pid == -1) fatal("fork of unprivileged child failed"); else if (monitor->m_pid != 0) { - debug2("User child is on pid %d", pid); + debug2("User child is on pid %d", monitor->m_pid); close(monitor->m_recvfd); monitor_child_postauth(monitor); @@ -595,7 +632,6 @@ privsep_postauth(Authctxt *authctxt, pid_t pid) monitor_apply_keystate(monitor); } - static char * list_hostkey_types(void) { @@ -1351,36 +1387,9 @@ main(int ac, char **av) packet_set_nonblocking(); - if (!use_privsep) - goto skip_privilegeseparation; - - /* Set up unprivileged child process to deal with network data */ - monitor = monitor_init(); - /* Store a pointer to the kex for later rekeying */ - monitor->m_pkex = &xxx_kex; - - pid = fork(); - if (pid == -1) - fatal("fork of unprivileged child failed"); - else if (pid != 0) { - debug2("Network child is on pid %d", pid); - - close(monitor->m_recvfd); - authctxt = monitor_child_preauth(monitor); - close(monitor->m_sendfd); - - /* Sync memory */ - monitor_sync(monitor); - goto authenticated; - } else { - close(monitor->m_sendfd); - - /* Demote the child */ - if (getuid() == 0 || geteuid() == 0) - privsep_preauth_child(); - } - - skip_privilegeseparation: + if (use_privsep) + if ((authctxt = privsep_preauth()) != NULL) + goto authenticated; /* perform the key exchange */ /* authenticate user and start session */ @@ -1391,12 +1400,14 @@ main(int ac, char **av) do_ssh1_kex(); authctxt = do_authentication(); } - if (use_privsep) + /* + * If we use privilege separation, the unprivileged child transfers + * the current keystate and exits + */ + if (use_privsep) { mm_send_keystate(monitor); - - /* If we use privilege separation, the unprivileged child exits */ - if (use_privsep) exit(0); + } authenticated: /* @@ -1404,7 +1415,8 @@ main(int ac, char **av) * file descriptor passing. */ if (use_privsep) { - privsep_postauth(authctxt, pid); + privsep_postauth(authctxt); + /* the monitor process [priv] will not return */ if (!compat20) destroy_sensitive_data(); } |