diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sshd.c | 98 |
2 files changed, 59 insertions, 44 deletions
@@ -133,6 +133,9 @@ | |||
133 | - markus@cvs.openbsd.org 2002/03/21 20:51:12 | 133 | - markus@cvs.openbsd.org 2002/03/21 20:51:12 |
134 | [sshd_config] | 134 | [sshd_config] |
135 | add privsep (off) | 135 | add privsep (off) |
136 | - markus@cvs.openbsd.org 2002/03/21 21:23:34 | ||
137 | [sshd.c] | ||
138 | add privsep_preauth() and remove 1 goto; ok provos@ | ||
136 | 139 | ||
137 | 20020317 | 140 | 20020317 |
138 | - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted, | 141 | - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted, |
@@ -7979,4 +7982,4 @@ | |||
7979 | - Wrote replacements for strlcpy and mkdtemp | 7982 | - Wrote replacements for strlcpy and mkdtemp |
7980 | - Released 1.0pre1 | 7983 | - Released 1.0pre1 |
7981 | 7984 | ||
7982 | $Id: ChangeLog,v 1.1962 2002/03/22 03:40:58 mouring Exp $ | 7985 | $Id: ChangeLog,v 1.1963 2002/03/22 03:43:46 mouring Exp $ |
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include "includes.h" | 44 | #include "includes.h" |
45 | RCSID("$OpenBSD: sshd.c,v 1.236 2002/03/20 21:08:08 stevesk Exp $"); | 45 | RCSID("$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 | ||
554 | static void | 554 | static Authctxt* |
555 | privsep_postauth(Authctxt *authctxt, pid_t pid) | 555 | privsep_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 | |||
595 | static void | ||
596 | privsep_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 | |||
608 | static char * | 644 | static char * |
609 | list_hostkey_types(void) | 645 | list_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 | } |