diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 173 |
1 files changed, 6 insertions, 167 deletions
@@ -72,11 +72,6 @@ RCSID("$OpenBSD: sshd.c,v 1.228 2002/02/27 21:23:13 stevesk Exp $"); | |||
72 | #include "misc.h" | 72 | #include "misc.h" |
73 | #include "dispatch.h" | 73 | #include "dispatch.h" |
74 | #include "channels.h" | 74 | #include "channels.h" |
75 | #include "session.h" | ||
76 | #include "monitor_mm.h" | ||
77 | #include "monitor.h" | ||
78 | #include "monitor_wrap.h" | ||
79 | #include "monitor_fdpass.h" | ||
80 | 75 | ||
81 | #ifdef LIBWRAP | 76 | #ifdef LIBWRAP |
82 | #include <tcpd.h> | 77 | #include <tcpd.h> |
@@ -194,20 +189,8 @@ u_int utmp_len = MAXHOSTNAMELEN; | |||
194 | int *startup_pipes = NULL; | 189 | int *startup_pipes = NULL; |
195 | int startup_pipe; /* in child */ | 190 | int startup_pipe; /* in child */ |
196 | 191 | ||
197 | /* variables used for privilege separation */ | ||
198 | #define MM_MEMSIZE 65536 | ||
199 | struct mm_master *mm_zback; | ||
200 | struct mm_master *mm_zlib; | ||
201 | |||
202 | extern int use_privsep; | ||
203 | /* Socket for the child to receive a fd */ | ||
204 | extern int mm_recvfd; | ||
205 | /* Socket for the parent to send a fd */ | ||
206 | int mm_sendfd; | ||
207 | |||
208 | /* Prototypes for various functions defined later in this file. */ | 192 | /* Prototypes for various functions defined later in this file. */ |
209 | void destroy_sensitive_data(void); | 193 | void destroy_sensitive_data(void); |
210 | void demote_sensitive_data(void); | ||
211 | 194 | ||
212 | static void do_ssh1_kex(void); | 195 | static void do_ssh1_kex(void); |
213 | static void do_ssh2_kex(void); | 196 | static void do_ssh2_kex(void); |
@@ -494,69 +477,6 @@ destroy_sensitive_data(void) | |||
494 | memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); | 477 | memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); |
495 | } | 478 | } |
496 | 479 | ||
497 | /* Demote private to public keys for network child */ | ||
498 | void | ||
499 | demote_sensitive_data(void) | ||
500 | { | ||
501 | Key *tmp; | ||
502 | int i; | ||
503 | |||
504 | if (sensitive_data.server_key) { | ||
505 | tmp = key_demote(sensitive_data.server_key); | ||
506 | key_free(sensitive_data.server_key); | ||
507 | sensitive_data.server_key = tmp; | ||
508 | } | ||
509 | for (i = 0; i < options.num_host_key_files; i++) { | ||
510 | if (sensitive_data.host_keys[i]) { | ||
511 | tmp = key_demote(sensitive_data.host_keys[i]); | ||
512 | key_free(sensitive_data.host_keys[i]); | ||
513 | sensitive_data.host_keys[i] = tmp; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ | ||
518 | } | ||
519 | |||
520 | void | ||
521 | privsep_postauth(Authctxt *authctxt) | ||
522 | { | ||
523 | pid_t pid; | ||
524 | |||
525 | if (0) { | ||
526 | /* File descriptor passing is broken */ | ||
527 | mm_apply_keystate(mm_zlib); | ||
528 | use_privsep = 0; | ||
529 | return; | ||
530 | } | ||
531 | |||
532 | pid = fork(); | ||
533 | if (pid == -1) | ||
534 | fatal("fork of unprivileged child failed"); | ||
535 | else if (pid != 0) { | ||
536 | debug2("User child is on pid %d", pid); | ||
537 | close(mm_recvfd); | ||
538 | monitor_child_postauth(mm_sendfd); | ||
539 | |||
540 | /* Teardown? */ | ||
541 | exit(0); | ||
542 | } | ||
543 | |||
544 | close(mm_sendfd); | ||
545 | |||
546 | /* Demote the private keys to public keys. */ | ||
547 | demote_sensitive_data(); | ||
548 | |||
549 | /* Drop privileges */ | ||
550 | if (seteuid(authctxt->pw->pw_uid) == -1) | ||
551 | fatal("%s: seteuid", __FUNCTION__); | ||
552 | if (setuid(authctxt->pw->pw_uid) == -1) | ||
553 | fatal("%s: setuid", __FUNCTION__); | ||
554 | |||
555 | /* It is safe now to apply the key state */ | ||
556 | mm_apply_keystate(mm_zlib); | ||
557 | } | ||
558 | |||
559 | |||
560 | static char * | 480 | static char * |
561 | list_hostkey_types(void) | 481 | list_hostkey_types(void) |
562 | { | 482 | { |
@@ -598,25 +518,6 @@ get_hostkey_by_type(int type) | |||
598 | return NULL; | 518 | return NULL; |
599 | } | 519 | } |
600 | 520 | ||
601 | Key * | ||
602 | get_hostkey_by_index(int ind) | ||
603 | { | ||
604 | if (ind < 0 || ind >= options.num_host_key_files) | ||
605 | return (NULL); | ||
606 | return (sensitive_data.host_keys[ind]); | ||
607 | } | ||
608 | |||
609 | int | ||
610 | get_hostkey_index(Key *key) | ||
611 | { | ||
612 | int i; | ||
613 | for (i = 0; i < options.num_host_key_files; i++) { | ||
614 | if (key == sensitive_data.host_keys[i]) | ||
615 | return (i); | ||
616 | } | ||
617 | return (-1); | ||
618 | } | ||
619 | |||
620 | /* | 521 | /* |
621 | * returns 1 if connection should be dropped, 0 otherwise. | 522 | * returns 1 if connection should be dropped, 0 otherwise. |
622 | * dropping starts at connection #max_startups_begin with a probability | 523 | * dropping starts at connection #max_startups_begin with a probability |
@@ -693,8 +594,6 @@ main(int ac, char **av) | |||
693 | int listen_sock, maxfd; | 594 | int listen_sock, maxfd; |
694 | int startup_p[2]; | 595 | int startup_p[2]; |
695 | int startups = 0; | 596 | int startups = 0; |
696 | Authctxt *authctxt; | ||
697 | int sp[2]; | ||
698 | Key *key; | 597 | Key *key; |
699 | int ret, key_used = 0; | 598 | int ret, key_used = 0; |
700 | 599 | ||
@@ -1332,84 +1231,23 @@ main(int ac, char **av) | |||
1332 | 1231 | ||
1333 | packet_set_nonblocking(); | 1232 | packet_set_nonblocking(); |
1334 | 1233 | ||
1335 | if (!use_privsep) | ||
1336 | goto skip_privilegeseparation; | ||
1337 | |||
1338 | /* Set up unprivileged child process to deal with network data */ | ||
1339 | monitor_socketpair(sp); | ||
1340 | mm_recvfd = sp[0]; | ||
1341 | mm_sendfd = sp[1]; | ||
1342 | |||
1343 | /* Used to share zlib space across processes */ | ||
1344 | mm_zback = mm_create(NULL, MM_MEMSIZE); | ||
1345 | mm_zlib = mm_create(mm_zback, 20 * MM_MEMSIZE); | ||
1346 | |||
1347 | /* Compression needs to share state across borders */ | ||
1348 | mm_init_compression(mm_zlib); | ||
1349 | |||
1350 | pid = fork(); | ||
1351 | if (pid == -1) | ||
1352 | fatal("fork of unprivileged child failed"); | ||
1353 | else if (pid != 0) { | ||
1354 | debug2("Network child is on pid %d", pid); | ||
1355 | authctxt = monitor_child_preauth(mm_sendfd); | ||
1356 | |||
1357 | /* The member allocation is not visible, so sync it */ | ||
1358 | mm_share_sync(&mm_zlib, &mm_zback); | ||
1359 | goto authenticated; | ||
1360 | } else { | ||
1361 | /* Demote the private keys to public keys. */ | ||
1362 | demote_sensitive_data(); | ||
1363 | |||
1364 | /* Change our root directory - /var/empty is standard*/ | ||
1365 | if (chroot("/var/empty") == -1) | ||
1366 | fatal("chroot(/var/empty)"); | ||
1367 | if (chdir("/") == -1) | ||
1368 | fatal("chdir(/)"); | ||
1369 | |||
1370 | /* Drop our privileges */ | ||
1371 | seteuid(32767); /* XXX - Niels */ | ||
1372 | setuid(32767); | ||
1373 | } | ||
1374 | |||
1375 | skip_privilegeseparation: | ||
1376 | |||
1377 | /* perform the key exchange */ | 1234 | /* perform the key exchange */ |
1378 | /* authenticate user and start session */ | 1235 | /* authenticate user and start session */ |
1379 | if (compat20) { | 1236 | if (compat20) { |
1380 | do_ssh2_kex(); | 1237 | do_ssh2_kex(); |
1381 | authctxt = do_authentication2(); | 1238 | do_authentication2(); |
1382 | if (use_privsep) | ||
1383 | mm_send_keystate(mm_recvfd); | ||
1384 | } else { | 1239 | } else { |
1385 | do_ssh1_kex(); | 1240 | do_ssh1_kex(); |
1386 | authctxt = do_authentication(); | 1241 | do_authentication(); |
1387 | } | 1242 | } |
1388 | 1243 | /* The connection has been terminated. */ | |
1389 | /* If we use privilege separation, the unprivileged child exits */ | 1244 | verbose("Closing connection to %.100s", remote_ip); |
1390 | if (use_privsep) | ||
1391 | exit(0); | ||
1392 | |||
1393 | authenticated: | ||
1394 | /* | ||
1395 | * In privilege separation, we fork another child and prepare | ||
1396 | * file descriptor passing. | ||
1397 | */ | ||
1398 | if (use_privsep) | ||
1399 | privsep_postauth(authctxt); | ||
1400 | |||
1401 | /* Perform session preparation. */ | ||
1402 | do_authenticated(authctxt); | ||
1403 | 1245 | ||
1404 | #ifdef USE_PAM | 1246 | #ifdef USE_PAM |
1405 | finish_pam(); | 1247 | finish_pam(); |
1406 | #endif /* USE_PAM */ | 1248 | #endif /* USE_PAM */ |
1407 | 1249 | ||
1408 | packet_close(); | 1250 | packet_close(); |
1409 | |||
1410 | if (use_privsep) | ||
1411 | mm_terminate(mm_recvfd); | ||
1412 | |||
1413 | exit(0); | 1251 | exit(0); |
1414 | } | 1252 | } |
1415 | 1253 | ||
@@ -1615,6 +1453,8 @@ do_ssh1_kex(void) | |||
1615 | for (i = 0; i < 16; i++) | 1453 | for (i = 0; i < 16; i++) |
1616 | session_id[i] = session_key[i] ^ session_key[i + 16]; | 1454 | session_id[i] = session_key[i] ^ session_key[i + 16]; |
1617 | } | 1455 | } |
1456 | /* Destroy the private and public keys. They will no longer be needed. */ | ||
1457 | destroy_sensitive_data(); | ||
1618 | 1458 | ||
1619 | /* Destroy the decrypted integer. It is no longer needed. */ | 1459 | /* Destroy the decrypted integer. It is no longer needed. */ |
1620 | BN_clear_free(session_key_int); | 1460 | BN_clear_free(session_key_int); |
@@ -1662,7 +1502,6 @@ do_ssh2_kex(void) | |||
1662 | kex->client_version_string=client_version_string; | 1502 | kex->client_version_string=client_version_string; |
1663 | kex->server_version_string=server_version_string; | 1503 | kex->server_version_string=server_version_string; |
1664 | kex->load_host_key=&get_hostkey_by_type; | 1504 | kex->load_host_key=&get_hostkey_by_type; |
1665 | kex->host_key_index=&get_hostkey_index; | ||
1666 | 1505 | ||
1667 | xxx_kex = kex; | 1506 | xxx_kex = kex; |
1668 | 1507 | ||