summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2002-03-13 12:47:54 +1100
committerDamien Miller <djm@mindrot.org>2002-03-13 12:47:54 +1100
commit646e7cf3d7e7d4231c2d97d27c09fe5fe1d749e2 (patch)
treea693368c47d2d044514878fbb1516f87b487f78b /sshd.c
parent29bdd2c9bca2737e7a246ed50fd827a6ccba0c61 (diff)
Import of Niels Provos' 20020312 ssh-complete.diff
PAM, Cygwin and OSF SIA will not work for sure
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c173
1 files changed, 167 insertions, 6 deletions
diff --git a/sshd.c b/sshd.c
index ea9293251..cbe316087 100644
--- a/sshd.c
+++ b/sshd.c
@@ -72,6 +72,11 @@ 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"
75 80
76#ifdef LIBWRAP 81#ifdef LIBWRAP
77#include <tcpd.h> 82#include <tcpd.h>
@@ -189,8 +194,20 @@ u_int utmp_len = MAXHOSTNAMELEN;
189int *startup_pipes = NULL; 194int *startup_pipes = NULL;
190int startup_pipe; /* in child */ 195int startup_pipe; /* in child */
191 196
197/* variables used for privilege separation */
198#define MM_MEMSIZE 65536
199struct mm_master *mm_zback;
200struct mm_master *mm_zlib;
201
202extern int use_privsep;
203/* Socket for the child to receive a fd */
204extern int mm_recvfd;
205/* Socket for the parent to send a fd */
206int mm_sendfd;
207
192/* Prototypes for various functions defined later in this file. */ 208/* Prototypes for various functions defined later in this file. */
193void destroy_sensitive_data(void); 209void destroy_sensitive_data(void);
210void demote_sensitive_data(void);
194 211
195static void do_ssh1_kex(void); 212static void do_ssh1_kex(void);
196static void do_ssh2_kex(void); 213static void do_ssh2_kex(void);
@@ -477,6 +494,69 @@ destroy_sensitive_data(void)
477 memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); 494 memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH);
478} 495}
479 496
497/* Demote private to public keys for network child */
498void
499demote_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
520void
521privsep_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
480static char * 560static char *
481list_hostkey_types(void) 561list_hostkey_types(void)
482{ 562{
@@ -518,6 +598,25 @@ get_hostkey_by_type(int type)
518 return NULL; 598 return NULL;
519} 599}
520 600
601Key *
602get_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
609int
610get_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
521/* 620/*
522 * returns 1 if connection should be dropped, 0 otherwise. 621 * returns 1 if connection should be dropped, 0 otherwise.
523 * dropping starts at connection #max_startups_begin with a probability 622 * dropping starts at connection #max_startups_begin with a probability
@@ -594,6 +693,8 @@ main(int ac, char **av)
594 int listen_sock, maxfd; 693 int listen_sock, maxfd;
595 int startup_p[2]; 694 int startup_p[2];
596 int startups = 0; 695 int startups = 0;
696 Authctxt *authctxt;
697 int sp[2];
597 Key *key; 698 Key *key;
598 int ret, key_used = 0; 699 int ret, key_used = 0;
599 700
@@ -1231,23 +1332,84 @@ main(int ac, char **av)
1231 1332
1232 packet_set_nonblocking(); 1333 packet_set_nonblocking();
1233 1334
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
1234 /* perform the key exchange */ 1377 /* perform the key exchange */
1235 /* authenticate user and start session */ 1378 /* authenticate user and start session */
1236 if (compat20) { 1379 if (compat20) {
1237 do_ssh2_kex(); 1380 do_ssh2_kex();
1238 do_authentication2(); 1381 authctxt = do_authentication2();
1382 if (use_privsep)
1383 mm_send_keystate(mm_recvfd);
1239 } else { 1384 } else {
1240 do_ssh1_kex(); 1385 do_ssh1_kex();
1241 do_authentication(); 1386 authctxt = do_authentication();
1242 } 1387 }
1243 /* The connection has been terminated. */ 1388
1244 verbose("Closing connection to %.100s", remote_ip); 1389 /* If we use privilege separation, the unprivileged child exits */
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);
1245 1403
1246#ifdef USE_PAM 1404#ifdef USE_PAM
1247 finish_pam(); 1405 finish_pam();
1248#endif /* USE_PAM */ 1406#endif /* USE_PAM */
1249 1407
1250 packet_close(); 1408 packet_close();
1409
1410 if (use_privsep)
1411 mm_terminate(mm_recvfd);
1412
1251 exit(0); 1413 exit(0);
1252} 1414}
1253 1415
@@ -1453,8 +1615,6 @@ do_ssh1_kex(void)
1453 for (i = 0; i < 16; i++) 1615 for (i = 0; i < 16; i++)
1454 session_id[i] = session_key[i] ^ session_key[i + 16]; 1616 session_id[i] = session_key[i] ^ session_key[i + 16];
1455 } 1617 }
1456 /* Destroy the private and public keys. They will no longer be needed. */
1457 destroy_sensitive_data();
1458 1618
1459 /* Destroy the decrypted integer. It is no longer needed. */ 1619 /* Destroy the decrypted integer. It is no longer needed. */
1460 BN_clear_free(session_key_int); 1620 BN_clear_free(session_key_int);
@@ -1502,6 +1662,7 @@ do_ssh2_kex(void)
1502 kex->client_version_string=client_version_string; 1662 kex->client_version_string=client_version_string;
1503 kex->server_version_string=server_version_string; 1663 kex->server_version_string=server_version_string;
1504 kex->load_host_key=&get_hostkey_by_type; 1664 kex->load_host_key=&get_hostkey_by_type;
1665 kex->host_key_index=&get_hostkey_index;
1505 1666
1506 xxx_kex = kex; 1667 xxx_kex = kex;
1507 1668