summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2002-03-22 03:43:46 +0000
committerBen Lindstrom <mouring@eviladmin.org>2002-03-22 03:43:46 +0000
commit943481cc774d31f5de75c16efbe8f3394e9470ab (patch)
treec28c4af77849f8945b8aa2743ed36076aae8255f /sshd.c
parentfa1336ff47f406c7f705899993a6003405d92975 (diff)
- markus@cvs.openbsd.org 2002/03/21 21:23:34
[sshd.c] add privsep_preauth() and remove 1 goto; ok provos@
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c98
1 files changed, 55 insertions, 43 deletions
diff --git a/sshd.c b/sshd.c
index 26124b777..c80dfc146 100644
--- a/sshd.c
+++ b/sshd.c
@@ -42,7 +42,7 @@
42 */ 42 */
43 43
44#include "includes.h" 44#include "includes.h"
45RCSID("$OpenBSD: sshd.c,v 1.236 2002/03/20 21:08:08 stevesk Exp $"); 45RCSID("$OpenBSD: sshd.c,v 1.237 2002/03/21 21:23:34 markus Exp $");
46 46
47#include <openssl/dh.h> 47#include <openssl/dh.h>
48#include <openssl/bn.h> 48#include <openssl/bn.h>
@@ -551,14 +551,51 @@ privsep_preauth_child(void)
551 do_setusercontext(pw); 551 do_setusercontext(pw);
552} 552}
553 553
554static void 554static Authctxt*
555privsep_postauth(Authctxt *authctxt, pid_t pid) 555privsep_preauth(void)
556{ 556{
557 extern Authctxt *x_authctxt; 557 Authctxt *authctxt = NULL;
558 int status; 558 int status;
559 pid_t pid;
559 560
560 /* Wait for the child's exit status */ 561 /* Set up unprivileged child process to deal with network data */
561 waitpid(pid, &status, 0); 562 monitor = monitor_init();
563 /* Store a pointer to the kex for later rekeying */
564 monitor->m_pkex = &xxx_kex;
565
566 pid = fork();
567 if (pid == -1) {
568 fatal("fork of unprivileged child failed");
569 } else if (pid != 0) {
570 debug2("Network child is on pid %d", pid);
571
572 close(monitor->m_recvfd);
573 authctxt = monitor_child_preauth(monitor);
574 close(monitor->m_sendfd);
575
576 /* Sync memory */
577 monitor_sync(monitor);
578
579 /* Wait for the child's exit status */
580 waitpid(pid, &status, 0);
581
582 return (authctxt);
583 } else {
584 /* child */
585
586 close(monitor->m_sendfd);
587
588 /* Demote the child */
589 if (getuid() == 0 || geteuid() == 0)
590 privsep_preauth_child();
591 }
592 return (NULL);
593}
594
595static void
596privsep_postauth(Authctxt *authctxt)
597{
598 extern Authctxt *x_authctxt;
562 599
563 /* XXX - Remote port forwarding */ 600 /* XXX - Remote port forwarding */
564 x_authctxt = authctxt; 601 x_authctxt = authctxt;
@@ -584,7 +621,7 @@ privsep_postauth(Authctxt *authctxt, pid_t pid)
584 if (monitor->m_pid == -1) 621 if (monitor->m_pid == -1)
585 fatal("fork of unprivileged child failed"); 622 fatal("fork of unprivileged child failed");
586 else if (monitor->m_pid != 0) { 623 else if (monitor->m_pid != 0) {
587 debug2("User child is on pid %d", pid); 624 debug2("User child is on pid %d", monitor->m_pid);
588 close(monitor->m_recvfd); 625 close(monitor->m_recvfd);
589 monitor_child_postauth(monitor); 626 monitor_child_postauth(monitor);
590 627
@@ -604,7 +641,6 @@ privsep_postauth(Authctxt *authctxt, pid_t pid)
604 monitor_apply_keystate(monitor); 641 monitor_apply_keystate(monitor);
605} 642}
606 643
607
608static char * 644static char *
609list_hostkey_types(void) 645list_hostkey_types(void)
610{ 646{
@@ -1379,36 +1415,9 @@ main(int ac, char **av)
1379 1415
1380 packet_set_nonblocking(); 1416 packet_set_nonblocking();
1381 1417
1382 if (!use_privsep) 1418 if (use_privsep)
1383 goto skip_privilegeseparation; 1419 if ((authctxt = privsep_preauth()) != NULL)
1384 1420 goto authenticated;
1385 /* Set up unprivileged child process to deal with network data */
1386 monitor = monitor_init();
1387 /* Store a pointer to the kex for later rekeying */
1388 monitor->m_pkex = &xxx_kex;
1389
1390 pid = fork();
1391 if (pid == -1)
1392 fatal("fork of unprivileged child failed");
1393 else if (pid != 0) {
1394 debug2("Network child is on pid %d", pid);
1395
1396 close(monitor->m_recvfd);
1397 authctxt = monitor_child_preauth(monitor);
1398 close(monitor->m_sendfd);
1399
1400 /* Sync memory */
1401 monitor_sync(monitor);
1402 goto authenticated;
1403 } else {
1404 close(monitor->m_sendfd);
1405
1406 /* Demote the child */
1407 if (getuid() == 0 || geteuid() == 0)
1408 privsep_preauth_child();
1409 }
1410
1411 skip_privilegeseparation:
1412 1421
1413 /* perform the key exchange */ 1422 /* perform the key exchange */
1414 /* authenticate user and start session */ 1423 /* authenticate user and start session */
@@ -1419,12 +1428,14 @@ main(int ac, char **av)
1419 do_ssh1_kex(); 1428 do_ssh1_kex();
1420 authctxt = do_authentication(); 1429 authctxt = do_authentication();
1421 } 1430 }
1422 if (use_privsep) 1431 /*
1432 * If we use privilege separation, the unprivileged child transfers
1433 * the current keystate and exits
1434 */
1435 if (use_privsep) {
1423 mm_send_keystate(monitor); 1436 mm_send_keystate(monitor);
1424
1425 /* If we use privilege separation, the unprivileged child exits */
1426 if (use_privsep)
1427 exit(0); 1437 exit(0);
1438 }
1428 1439
1429 authenticated: 1440 authenticated:
1430 /* 1441 /*
@@ -1432,7 +1443,8 @@ main(int ac, char **av)
1432 * file descriptor passing. 1443 * file descriptor passing.
1433 */ 1444 */
1434 if (use_privsep) { 1445 if (use_privsep) {
1435 privsep_postauth(authctxt, pid); 1446 privsep_postauth(authctxt);
1447 /* the monitor process [priv] will not return */
1436 if (!compat20) 1448 if (!compat20)
1437 destroy_sensitive_data(); 1449 destroy_sensitive_data();
1438 } 1450 }