summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2002-03-13 13:19:42 +1100
committerDamien Miller <djm@mindrot.org>2002-03-13 13:19:42 +1100
commit3a5b0233306a3db3a5db5b9ddc187c55e9b251f4 (patch)
tree86478addb63771a9a1be0e13cfbdea9f964f963a
parent3225fb454d0e79cf6f824dd00ff478749620277b (diff)
Stupid djm commits experimental code to head instead of branch
revert
-rw-r--r--Makefile.in6
-rw-r--r--auth.h4
-rw-r--r--auth1.c30
-rw-r--r--auth2.c119
-rw-r--r--bufaux.c2
-rw-r--r--cipher.c40
-rw-r--r--cipher.h2
-rw-r--r--compress.c4
-rw-r--r--kex.c4
-rw-r--r--kex.h1
-rw-r--r--kexdh.c13
-rw-r--r--kexgex.c19
-rw-r--r--key.c43
-rw-r--r--key.h1
-rw-r--r--packet.c106
-rw-r--r--packet.h7
-rw-r--r--servconf.c15
-rw-r--r--session.c53
-rw-r--r--session.h28
-rw-r--r--sshd.c173
20 files changed, 109 insertions, 561 deletions
diff --git a/Makefile.in b/Makefile.in
index 38c1d381c..31aa8e583 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.198 2002/03/13 01:47:54 djm Exp $ 1# $Id: Makefile.in,v 1.199 2002/03/13 02:19:42 djm Exp $
2 2
3prefix=@prefix@ 3prefix=@prefix@
4exec_prefix=@exec_prefix@ 4exec_prefix=@exec_prefix@
@@ -50,11 +50,11 @@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
50 50
51TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} $(SFTP_PROGS) 51TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} $(SFTP_PROGS)
52 52
53LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dh.o dispatch.o fatal.o mac.o hostfile.o key.o kex.o kexdh.o kexgex.o log.o match.o misc.o monitor_fdpass.c monitor_wrap.c mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o scard.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o 53LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dh.o dispatch.o fatal.o mac.o hostfile.o key.o kex.o kexdh.o kexgex.o log.o match.o misc.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o scard.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o
54 54
55SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o 55SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o
56 56
57SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o monitor.c monitor_mm.c sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o 57SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o
58 58
59MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out 59MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out
60MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 60MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1
diff --git a/auth.h b/auth.h
index 9b5b19f6c..c7175405d 100644
--- a/auth.h
+++ b/auth.h
@@ -121,8 +121,8 @@ void krb5_cleanup_proc(void *authctxt);
121#include "auth-pam.h" 121#include "auth-pam.h"
122#include "auth2-pam.h" 122#include "auth2-pam.h"
123 123
124Authctxt *do_authentication(void); 124void do_authentication(void);
125Authctxt *do_authentication2(void); 125void do_authentication2(void);
126 126
127Authctxt *authctxt_new(void); 127Authctxt *authctxt_new(void);
128void auth_log(Authctxt *, int, char *, char *); 128void auth_log(Authctxt *, int, char *, char *);
diff --git a/auth1.c b/auth1.c
index c52f63897..c2d99895f 100644
--- a/auth1.c
+++ b/auth1.c
@@ -26,13 +26,8 @@ RCSID("$OpenBSD: auth1.c,v 1.35 2002/02/03 17:53:25 markus Exp $");
26#include "session.h" 26#include "session.h"
27#include "misc.h" 27#include "misc.h"
28#include "uidswap.h" 28#include "uidswap.h"
29#include "monitor.h"
30#include "monitor_wrap.h"
31 29
32/* import */ 30/* import */
33extern int use_privsep;
34extern int mm_recvfd;
35
36extern ServerOptions options; 31extern ServerOptions options;
37 32
38/* 33/*
@@ -360,13 +355,12 @@ do_authloop(Authctxt *authctxt)
360 * Performs authentication of an incoming connection. Session key has already 355 * Performs authentication of an incoming connection. Session key has already
361 * been exchanged and encryption is enabled. 356 * been exchanged and encryption is enabled.
362 */ 357 */
363Authctxt * 358void
364do_authentication(void) 359do_authentication(void)
365{ 360{
366 Authctxt *authctxt; 361 Authctxt *authctxt;
367 struct passwd *pw = NULL, *pwent; 362 struct passwd *pw;
368 u_int ulen; 363 u_int ulen;
369 int allowed;
370 char *p, *user, *style = NULL; 364 char *p, *user, *style = NULL;
371 365
372 /* Get the name of the user that we wish to log in as. */ 366 /* Get the name of the user that we wish to log in as. */
@@ -388,26 +382,17 @@ do_authentication(void)
388 authctxt->style = style; 382 authctxt->style = style;
389 383
390 /* Verify that the user is a valid user. */ 384 /* Verify that the user is a valid user. */
391 if (!use_privsep) { 385 pw = getpwnam(user);
392 pwent = getpwnam(user); 386 if (pw && allowed_user(pw)) {
393 allowed = pwent ? allowed_user(pwent) : 0;
394 } else
395 pwent = mm_getpwnamallow(mm_recvfd, user, &allowed);
396 if (pwent && allowed) {
397 authctxt->valid = 1; 387 authctxt->valid = 1;
398 pw = pwcopy(pwent); 388 pw = pwcopy(pw);
399 } else { 389 } else {
400 debug("do_authentication: illegal user %s", user); 390 debug("do_authentication: illegal user %s", user);
401 pw = NULL; 391 pw = NULL;
402 } 392 }
403 /* Free memory */
404 if (use_privsep)
405 pwfree(pwent);
406
407 authctxt->pw = pw; 393 authctxt->pw = pw;
408 394
409 setproctitle("%s%s", use_privsep ? " [net]" : "", 395 setproctitle("%s", pw ? user : "unknown");
410 pw ? user : "unknown");
411 396
412#ifdef USE_PAM 397#ifdef USE_PAM
413 start_pam(pw == NULL ? "NOUSER" : user); 398 start_pam(pw == NULL ? "NOUSER" : user);
@@ -433,5 +418,6 @@ do_authentication(void)
433 packet_send(); 418 packet_send();
434 packet_write_wait(); 419 packet_write_wait();
435 420
436 return (authctxt); 421 /* Perform session preparation. */
422 do_authenticated(authctxt);
437} 423}
diff --git a/auth2.c b/auth2.c
index f661f8d7c..f2a801ecc 100644
--- a/auth2.c
+++ b/auth2.c
@@ -51,13 +51,8 @@ RCSID("$OpenBSD: auth2.c,v 1.85 2002/02/24 19:14:59 markus Exp $");
51#include "hostfile.h" 51#include "hostfile.h"
52#include "canohost.h" 52#include "canohost.h"
53#include "match.h" 53#include "match.h"
54#include "monitor.h"
55#include "monitor_wrap.h"
56 54
57/* import */ 55/* import */
58extern int use_privsep;
59extern int mm_recvfd;
60
61extern ServerOptions options; 56extern ServerOptions options;
62extern u_char *session_id2; 57extern u_char *session_id2;
63extern int session_id2_len; 58extern int session_id2_len;
@@ -80,8 +75,8 @@ static void input_userauth_request(int, u_int32_t, void *);
80/* helper */ 75/* helper */
81static Authmethod *authmethod_lookup(const char *); 76static Authmethod *authmethod_lookup(const char *);
82static char *authmethods_get(void); 77static char *authmethods_get(void);
83int user_key_allowed(struct passwd *, Key *); 78static int user_key_allowed(struct passwd *, Key *);
84int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); 79static int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
85 80
86/* auth */ 81/* auth */
87static void userauth_banner(void); 82static void userauth_banner(void);
@@ -114,7 +109,7 @@ Authmethod authmethods[] = {
114 * loop until authctxt->success == TRUE 109 * loop until authctxt->success == TRUE
115 */ 110 */
116 111
117Authctxt * 112void
118do_authentication2(void) 113do_authentication2(void)
119{ 114{
120 Authctxt *authctxt = authctxt_new(); 115 Authctxt *authctxt = authctxt_new();
@@ -130,8 +125,7 @@ do_authentication2(void)
130 dispatch_init(&dispatch_protocol_error); 125 dispatch_init(&dispatch_protocol_error);
131 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); 126 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
132 dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); 127 dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
133 128 do_authenticated(authctxt);
134 return(authctxt);
135} 129}
136 130
137static void 131static void
@@ -188,15 +182,10 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
188 *style++ = 0; 182 *style++ = 0;
189 183
190 if (authctxt->attempt++ == 0) { 184 if (authctxt->attempt++ == 0) {
191 /* setup auth context */ 185 /* setup auth context */
192 int allowed;
193 struct passwd *pw = NULL; 186 struct passwd *pw = NULL;
194 if (!use_privsep) { 187 pw = getpwnam(user);
195 pw = getpwnam(user); 188 if (pw && allowed_user(pw) && strcmp(service, "ssh-connection")==0) {
196 allowed = pw ? allowed_user(pw) : 0;
197 } else
198 pw = mm_getpwnamallow(mm_recvfd, user, &allowed);
199 if (pw && allowed && strcmp(service, "ssh-connection")==0) {
200 authctxt->pw = pwcopy(pw); 189 authctxt->pw = pwcopy(pw);
201 authctxt->valid = 1; 190 authctxt->valid = 1;
202 debug2("input_userauth_request: setting up authctxt for %s", user); 191 debug2("input_userauth_request: setting up authctxt for %s", user);
@@ -209,18 +198,10 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
209 start_pam("NOUSER"); 198 start_pam("NOUSER");
210#endif 199#endif
211 } 200 }
212 /* Free memory */ 201 setproctitle("%s", pw ? user : "unknown");
213 if (use_privsep)
214 pwfree(pw);
215
216 setproctitle("%s%s", use_privsep ? " [net]" : "",
217 pw ? user : "unknown");
218 authctxt->user = xstrdup(user); 202 authctxt->user = xstrdup(user);
219 authctxt->service = xstrdup(service); 203 authctxt->service = xstrdup(service);
220 authctxt->style = style ? xstrdup(style) : NULL; 204 authctxt->style = style ? xstrdup(style) : NULL;
221
222 if (use_privsep)
223 mm_inform_authserv(mm_recvfd, service, style);
224 } else if (strcmp(user, authctxt->user) != 0 || 205 } else if (strcmp(user, authctxt->user) != 0 ||
225 strcmp(service, authctxt->service) != 0) { 206 strcmp(service, authctxt->service) != 0) {
226 packet_disconnect("Change of username or service not allowed: " 207 packet_disconnect("Change of username or service not allowed: "
@@ -332,8 +313,6 @@ done:
332static int 313static int
333userauth_none(Authctxt *authctxt) 314userauth_none(Authctxt *authctxt)
334{ 315{
335 int res = 0;
336
337 /* disable method "none", only allowed one time */ 316 /* disable method "none", only allowed one time */
338 Authmethod *m = authmethod_lookup("none"); 317 Authmethod *m = authmethod_lookup("none");
339 if (m != NULL) 318 if (m != NULL)
@@ -343,16 +322,18 @@ userauth_none(Authctxt *authctxt)
343 322
344 if (authctxt->valid == 0) 323 if (authctxt->valid == 0)
345 return(0); 324 return(0);
346 if (!authctxt->valid) 325
347 return (0); 326#ifdef HAVE_CYGWIN
348 if (use_privsep) 327 if (check_nt_auth(1, authctxt->pw) == 0)
349#if defined(USE_PAM) || defined(HAVE_OSF_SIA) 328 return(0);
350#error NOT IMPLEMENTED FOR PRIVSEP
351#endif 329#endif
352 res = mm_auth_password(mm_recvfd, ""); 330#ifdef USE_PAM
353 else 331 return auth_pam_password(authctxt->pw, "");
354 res = auth_password(authctxt, ""); 332#elif defined(HAVE_OSF_SIA)
355 return (res); 333 return 0;
334#else /* !HAVE_OSF_SIA && !USE_PAM */
335 return auth_password(authctxt, "");
336#endif /* USE_PAM */
356} 337}
357 338
358static int 339static int
@@ -367,16 +348,18 @@ userauth_passwd(Authctxt *authctxt)
367 log("password change not supported"); 348 log("password change not supported");
368 password = packet_get_string(&len); 349 password = packet_get_string(&len);
369 packet_check_eom(); 350 packet_check_eom();
370 351 if (authctxt->valid &&
371#if defined(HAVE_CYGWIN) || defined(USE_PAM) || defined(HAVE_OSF_SIA) 352#ifdef HAVE_CYGWIN
372#error NOT IMPLEMENTED FOR PRIVSEP 353 check_nt_auth(1, authctxt->pw) &&
373#endif 354#endif
374 if (authctxt->valid) { 355#ifdef USE_PAM
375 if (use_privsep) 356 auth_pam_password(authctxt->pw, password) == 1)
376 authenticated = mm_auth_password(mm_recvfd, password); 357#elif defined(HAVE_OSF_SIA)
377 else 358 auth_sia_password(authctxt->user, password) == 1)
378 authenticated = auth_password(authctxt, password); 359#else /* !USE_PAM && !HAVE_OSF_SIA */
379 } 360 auth_password(authctxt, password) == 1)
361#endif /* USE_PAM */
362 authenticated = 1;
380 memset(password, 0, len); 363 memset(password, 0, len);
381 xfree(password); 364 xfree(password);
382 return authenticated; 365 return authenticated;
@@ -484,23 +467,12 @@ userauth_pubkey(Authctxt *authctxt)
484 buffer_dump(&b); 467 buffer_dump(&b);
485#endif 468#endif
486 /* test for correct signature */ 469 /* test for correct signature */
487 authenticated = 0; 470 if (user_key_allowed(authctxt->pw, key) &&
488 if (use_privsep) { 471 key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
489 if (mm_user_key_allowed(mm_recvfd, key) && 472 authenticated = 1;
490 mm_key_verify(mm_recvfd,
491 MM_USERKEY, NULL, NULL, key, sig, slen,
492 buffer_ptr(&b), buffer_len(&b)) == 1)
493 authenticated = 1;
494 } else {
495 if (user_key_allowed(authctxt->pw, key) &&
496 key_verify(key, sig, slen, buffer_ptr(&b),
497 buffer_len(&b)) == 1)
498 authenticated = 1;
499 }
500 buffer_clear(&b); 473 buffer_clear(&b);
501 xfree(sig); 474 xfree(sig);
502 } else { 475 } else {
503 int res = 0;
504 debug("test whether pkalg/pkblob are acceptable"); 476 debug("test whether pkalg/pkblob are acceptable");
505 packet_check_eom(); 477 packet_check_eom();
506 478
@@ -512,11 +484,7 @@ userauth_pubkey(Authctxt *authctxt)
512 * if a user is not allowed to login. is this an 484 * if a user is not allowed to login. is this an
513 * issue? -markus 485 * issue? -markus
514 */ 486 */
515 if (use_privsep) 487 if (user_key_allowed(authctxt->pw, key)) {
516 res = mm_user_key_allowed(mm_recvfd, key);
517 else
518 res = user_key_allowed(authctxt->pw, key);
519 if (res) {
520 packet_start(SSH2_MSG_USERAUTH_PK_OK); 488 packet_start(SSH2_MSG_USERAUTH_PK_OK);
521 packet_put_string(pkalg, alen); 489 packet_put_string(pkalg, alen);
522 packet_put_string(pkblob, blen); 490 packet_put_string(pkblob, blen);
@@ -604,18 +572,9 @@ userauth_hostbased(Authctxt *authctxt)
604 buffer_dump(&b); 572 buffer_dump(&b);
605#endif 573#endif
606 /* test for allowed key and correct signature */ 574 /* test for allowed key and correct signature */
607 authenticated = 0; 575 if (hostbased_key_allowed(authctxt->pw, cuser, chost, key) &&
608 if (use_privsep) { 576 key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
609 if (mm_hostbased_key_allowed(mm_recvfd, cuser, chost, key) && 577 authenticated = 1;
610 mm_key_verify(mm_recvfd, MM_HOSTKEY, cuser, chost, key,
611 sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
612 authenticated = 1;
613 } else {
614 if (hostbased_key_allowed(authctxt->pw, cuser, chost, key) &&
615 key_verify(key, sig, slen, buffer_ptr(&b),
616 buffer_len(&b)) == 1)
617 authenticated = 1;
618 }
619 578
620 buffer_clear(&b); 579 buffer_clear(&b);
621done: 580done:
@@ -771,7 +730,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
771} 730}
772 731
773/* check whether given key is in .ssh/authorized_keys* */ 732/* check whether given key is in .ssh/authorized_keys* */
774int 733static int
775user_key_allowed(struct passwd *pw, Key *key) 734user_key_allowed(struct passwd *pw, Key *key)
776{ 735{
777 int success; 736 int success;
@@ -791,7 +750,7 @@ user_key_allowed(struct passwd *pw, Key *key)
791} 750}
792 751
793/* return 1 if given hostkey is allowed */ 752/* return 1 if given hostkey is allowed */
794int 753static int
795hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, 754hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
796 Key *key) 755 Key *key)
797{ 756{
diff --git a/bufaux.c b/bufaux.c
index 64b9a26e9..23bc0c814 100644
--- a/bufaux.c
+++ b/bufaux.c
@@ -221,8 +221,6 @@ buffer_put_string(Buffer *buffer, const void *buf, u_int len)
221void 221void
222buffer_put_cstring(Buffer *buffer, const char *s) 222buffer_put_cstring(Buffer *buffer, const char *s)
223{ 223{
224 if (s == NULL)
225 fatal("buffer_put_cstring: s == NULL");
226 buffer_put_string(buffer, s, strlen(s)); 224 buffer_put_string(buffer, s, strlen(s));
227} 225}
228 226
diff --git a/cipher.c b/cipher.c
index 5ddf819c4..9e8f42f5e 100644
--- a/cipher.c
+++ b/cipher.c
@@ -541,43 +541,3 @@ evp_rijndael(void)
541#endif 541#endif
542 return (&rijndal_cbc); 542 return (&rijndal_cbc);
543} 543}
544
545/*
546 * Exports an IV from the CipherContext required to export the key
547 * state back from the unprivileged child to the privileged parent
548 * process.
549 */
550
551void
552cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
553{
554 Cipher *c = cc->cipher;
555 u_char *civ = NULL;
556 int evplen;
557
558 switch (c->number) {
559 case SSH_CIPHER_SSH2:
560 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
561 if (evplen == 0)
562 return;
563 if (evplen != len)
564 fatal("%s: wrong iv length %d != %d", __FUNCTION__,
565 evplen, len);
566
567 if (strncmp(c->name, "aes", 3) == 0) {
568 struct ssh_rijndael_ctx *aesc;
569
570 aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
571 if (aesc == NULL)
572 fatal("ssh_rijndael_cbc: no context");
573 civ = aesc->r_iv;
574 } else {
575 civ = cc->evp.iv;
576 }
577 break;
578 default:
579 fatal("%s: bad cipher %d", __FUNCTION__, c->number);
580 }
581 memcpy(iv, civ, len);
582}
583
diff --git a/cipher.h b/cipher.h
index c7724469b..b3b0303c7 100644
--- a/cipher.h
+++ b/cipher.h
@@ -81,6 +81,4 @@ void cipher_cleanup(CipherContext *);
81void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); 81void cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
82u_int cipher_blocksize(Cipher *); 82u_int cipher_blocksize(Cipher *);
83u_int cipher_keylen(Cipher *); 83u_int cipher_keylen(Cipher *);
84
85void cipher_get_keyiv(CipherContext *, u_char *, u_int);
86#endif /* CIPHER_H */ 84#endif /* CIPHER_H */
diff --git a/compress.c b/compress.c
index dec96ba55..3badbf452 100644
--- a/compress.c
+++ b/compress.c
@@ -19,8 +19,8 @@ RCSID("$OpenBSD: compress.c,v 1.17 2001/12/29 21:56:01 stevesk Exp $");
19#include "zlib.h" 19#include "zlib.h"
20#include "compress.h" 20#include "compress.h"
21 21
22z_stream incoming_stream; 22static z_stream incoming_stream;
23z_stream outgoing_stream; 23static z_stream outgoing_stream;
24static int compress_init_send_called = 0; 24static int compress_init_send_called = 0;
25static int compress_init_recv_called = 0; 25static int compress_init_recv_called = 0;
26 26
diff --git a/kex.c b/kex.c
index e5c0b0d00..bf8fd95b4 100644
--- a/kex.c
+++ b/kex.c
@@ -43,10 +43,6 @@ RCSID("$OpenBSD: kex.c,v 1.47 2002/02/28 15:46:33 markus Exp $");
43 43
44#define KEX_COOKIE_LEN 16 44#define KEX_COOKIE_LEN 16
45 45
46/* Use privilege separation for sshd */
47int use_privsep;
48int mm_recvfd;
49
50/* prototype */ 46/* prototype */
51static void kex_kexinit_finish(Kex *); 47static void kex_kexinit_finish(Kex *);
52static void kex_choose_conf(Kex *); 48static void kex_choose_conf(Kex *);
diff --git a/kex.h b/kex.h
index c99afaec0..755bf332a 100644
--- a/kex.h
+++ b/kex.h
@@ -111,7 +111,6 @@ struct Kex {
111 char *server_version_string; 111 char *server_version_string;
112 int (*verify_host_key)(Key *); 112 int (*verify_host_key)(Key *);
113 Key *(*load_host_key)(int); 113 Key *(*load_host_key)(int);
114 int (*host_key_index)(Key *);
115}; 114};
116 115
117Kex *kex_setup(char *[PROPOSAL_MAX]); 116Kex *kex_setup(char *[PROPOSAL_MAX]);
diff --git a/kexdh.c b/kexdh.c
index 6256722ff..eaf497ca7 100644
--- a/kexdh.c
+++ b/kexdh.c
@@ -37,12 +37,6 @@ RCSID("$OpenBSD: kexdh.c,v 1.17 2002/02/28 15:46:33 markus Exp $");
37#include "packet.h" 37#include "packet.h"
38#include "dh.h" 38#include "dh.h"
39#include "ssh2.h" 39#include "ssh2.h"
40#include "monitor.h"
41#include "monitor_wrap.h"
42
43/* Imports */
44extern int use_privsep;
45extern int mm_recvfd;
46 40
47static u_char * 41static u_char *
48kex_dh_hash( 42kex_dh_hash(
@@ -281,12 +275,7 @@ kexdh_server(Kex *kex)
281 275
282 /* sign H */ 276 /* sign H */
283 /* XXX hashlen depends on KEX */ 277 /* XXX hashlen depends on KEX */
284 if (use_privsep) 278 key_sign(server_host_key, &signature, &slen, hash, 20);
285 mm_key_sign(mm_recvfd,
286 kex->host_key_index(server_host_key),
287 &signature, &slen, hash, 20);
288 else
289 key_sign(server_host_key, &signature, &slen, hash, 20);
290 279
291 /* destroy_sensitive_data(); */ 280 /* destroy_sensitive_data(); */
292 281
diff --git a/kexgex.c b/kexgex.c
index 3c811f337..61896e6ed 100644
--- a/kexgex.c
+++ b/kexgex.c
@@ -38,12 +38,6 @@ RCSID("$OpenBSD: kexgex.c,v 1.20 2002/02/28 15:46:33 markus Exp $");
38#include "dh.h" 38#include "dh.h"
39#include "ssh2.h" 39#include "ssh2.h"
40#include "compat.h" 40#include "compat.h"
41#include "monitor.h"
42#include "monitor_wrap.h"
43
44/* Imports */
45extern int use_privsep;
46extern int mm_recvfd;
47 41
48static u_char * 42static u_char *
49kexgex_hash( 43kexgex_hash(
@@ -302,11 +296,7 @@ kexgex_server(Kex *kex)
302 fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", 296 fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
303 min, nbits, max); 297 min, nbits, max);
304 298
305 /* Contact privileged parent */ 299 dh = choose_dh(min, nbits, max);
306 if (use_privsep)
307 dh = mm_choose_dh(mm_recvfd, min, nbits, max);
308 else
309 dh = choose_dh(min, nbits, max);
310 if (dh == NULL) 300 if (dh == NULL)
311 packet_disconnect("Protocol error: no matching DH grp found"); 301 packet_disconnect("Protocol error: no matching DH grp found");
312 302
@@ -389,11 +379,7 @@ kexgex_server(Kex *kex)
389 379
390 /* sign H */ 380 /* sign H */
391 /* XXX hashlen depends on KEX */ 381 /* XXX hashlen depends on KEX */
392 if (use_privsep) 382 key_sign(server_host_key, &signature, &slen, hash, 20);
393 mm_key_sign(mm_recvfd, kex->host_key_index(server_host_key),
394 &signature, &slen, hash, 20);
395 else
396 key_sign(server_host_key, &signature, &slen, hash, 20);
397 383
398 /* destroy_sensitive_data(); */ 384 /* destroy_sensitive_data(); */
399 385
@@ -404,7 +390,6 @@ kexgex_server(Kex *kex)
404 packet_put_bignum2(dh->pub_key); /* f */ 390 packet_put_bignum2(dh->pub_key); /* f */
405 packet_put_string(signature, slen); 391 packet_put_string(signature, slen);
406 packet_send(); 392 packet_send();
407
408 xfree(signature); 393 xfree(signature);
409 xfree(server_host_key_blob); 394 xfree(server_host_key_blob);
410 /* have keys, free DH */ 395 /* have keys, free DH */
diff --git a/key.c b/key.c
index fb6bff95b..cda91571a 100644
--- a/key.c
+++ b/key.c
@@ -801,46 +801,3 @@ key_verify(
801 break; 801 break;
802 } 802 }
803} 803}
804
805/* Converts a private to a public key */
806
807Key *
808key_demote(Key *k)
809{
810 Key *pk;
811
812 pk = xmalloc(sizeof(*pk));
813 pk->type = k->type;
814 pk->flags = k->flags;
815 pk->dsa = NULL;
816 pk->rsa = NULL;
817
818 switch (k->type) {
819 case KEY_RSA1:
820 case KEY_RSA:
821 if ((pk->rsa = RSA_new()) == NULL)
822 fatal("key_demote: RSA_new failed");
823 if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL)
824 fatal("key_demote: BN_dup failed");
825 if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
826 fatal("key_demote: BN_dup failed");
827 break;
828 case KEY_DSA:
829 if ((pk->dsa = DSA_new()) == NULL)
830 fatal("key_demote: DSA_new failed");
831 if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL)
832 fatal("key_demote: BN_dup failed");
833 if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL)
834 fatal("key_demote: BN_dup failed");
835 if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL)
836 fatal("key_demote: BN_dup failed");
837 if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
838 fatal("key_demote: BN_dup failed");
839 break;
840 default:
841 fatal("key_free: bad key type %d", k->type);
842 break;
843 }
844
845 return (pk);
846}
diff --git a/key.h b/key.h
index bc8b3d06b..a2257731a 100644
--- a/key.h
+++ b/key.h
@@ -58,7 +58,6 @@ struct Key {
58Key *key_new(int); 58Key *key_new(int);
59Key *key_new_private(int); 59Key *key_new_private(int);
60void key_free(Key *); 60void key_free(Key *);
61Key *key_demote(Key *);
62int key_equal(Key *, Key *); 61int key_equal(Key *, Key *);
63char *key_fingerprint(Key *, enum fp_type, enum fp_rep); 62char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
64char *key_type(Key *); 63char *key_type(Key *);
diff --git a/packet.c b/packet.c
index 1c80af128..045d5a105 100644
--- a/packet.c
+++ b/packet.c
@@ -115,8 +115,6 @@ static int interactive_mode = 0;
115 115
116/* Session key information for Encryption and MAC */ 116/* Session key information for Encryption and MAC */
117Newkeys *newkeys[MODE_MAX]; 117Newkeys *newkeys[MODE_MAX];
118static u_int32_t read_seqnr = 0;
119static u_int32_t send_seqnr = 0;
120 118
121/* roundup current message to extra_pad bytes */ 119/* roundup current message to extra_pad bytes */
122static u_char extra_pad = 0; 120static u_char extra_pad = 0;
@@ -173,87 +171,6 @@ packet_connection_is_on_socket(void)
173 return 1; 171 return 1;
174} 172}
175 173
176/*
177 * Exports an IV from the CipherContext required to export the key
178 * state back from the unprivileged child to the privileged parent
179 * process.
180 */
181
182void
183packet_get_keyiv(int mode, u_char *iv, u_int len)
184{
185 CipherContext *cc;
186
187 if (mode == MODE_OUT)
188 cc = &send_context;
189 else
190 cc = &receive_context;
191
192 cipher_get_keyiv(cc, iv, len);
193}
194
195int
196packet_get_keycontext(int mode, u_char *dat)
197{
198 int plen;
199 CipherContext *cc;
200
201 if (mode == MODE_OUT)
202 cc = &send_context;
203 else
204 cc = &receive_context;
205
206#if OPENSSL_VERSION_NUMBER < 0x00907000L
207 plen = sizeof(cc->evp.c);
208#else
209 plen = cc->evp.cipher->ctx_size;
210#endif
211
212 if (dat == NULL)
213 return (plen);
214
215#if OPENSSL_VERSION_NUMBER < 0x00907000L
216 memcpy(dat, &cc->evp.c, sizeof(cc->evp.c));
217#else
218 memcpy(dat, &cc->evp.cipher_data, plen);
219#endif
220 return (plen);
221}
222
223void
224packet_set_keycontext(int mode, u_char *dat)
225{
226 CipherContext *cc;
227
228 if (mode == MODE_OUT)
229 cc = &send_context;
230 else
231 cc = &receive_context;
232
233#if OPENSSL_VERSION_NUMBER < 0x00907000L
234 memcpy(&cc->evp.c, dat, sizeof(cc->evp.c));
235#else
236 memcpy(&cc->evp.cipher_data, dat, cc->evp.cipher->ctx_size);
237#endif
238}
239
240u_int32_t
241packet_get_seqnr(int mode)
242{
243 return (mode == MODE_IN ? read_seqnr : send_seqnr);
244}
245
246void
247packet_set_seqnr(int mode, u_int32_t seqnr)
248{
249 if (mode == MODE_IN)
250 read_seqnr = seqnr;
251 else if (mode == MODE_OUT)
252 send_seqnr = seqnr;
253 else
254 fatal("%s: bad mode %d", __FUNCTION__, mode);
255}
256
257/* returns 1 if connection is via ipv4 */ 174/* returns 1 if connection is via ipv4 */
258 175
259int 176int
@@ -516,7 +433,7 @@ packet_send1(void)
516 */ 433 */
517} 434}
518 435
519void 436static void
520set_newkeys(int mode) 437set_newkeys(int mode)
521{ 438{
522 Enc *enc; 439 Enc *enc;
@@ -560,9 +477,8 @@ set_newkeys(int mode)
560 DBG(debug("cipher_init_context: %d", mode)); 477 DBG(debug("cipher_init_context: %d", mode));
561 cipher_init(cc, enc->cipher, enc->key, enc->key_len, 478 cipher_init(cc, enc->cipher, enc->key, enc->key_len,
562 enc->iv, enc->block_size, encrypt); 479 enc->iv, enc->block_size, encrypt);
563 /* Deleting the keys does not gain extra security */ 480 memset(enc->iv, 0, enc->block_size);
564 /* memset(enc->iv, 0, enc->block_size); 481 memset(enc->key, 0, enc->key_len);
565 memset(enc->key, 0, enc->key_len); */
566 if (comp->type != 0 && comp->enabled == 0) { 482 if (comp->type != 0 && comp->enabled == 0) {
567 packet_init_compression(); 483 packet_init_compression();
568 if (mode == MODE_OUT) 484 if (mode == MODE_OUT)
@@ -579,6 +495,7 @@ set_newkeys(int mode)
579static void 495static void
580packet_send2(void) 496packet_send2(void)
581{ 497{
498 static u_int32_t seqnr = 0;
582 u_char type, *cp, *macbuf = NULL; 499 u_char type, *cp, *macbuf = NULL;
583 u_char padlen, pad; 500 u_char padlen, pad;
584 u_int packet_length = 0; 501 u_int packet_length = 0;
@@ -659,10 +576,10 @@ packet_send2(void)
659 576
660 /* compute MAC over seqnr and packet(length fields, payload, padding) */ 577 /* compute MAC over seqnr and packet(length fields, payload, padding) */
661 if (mac && mac->enabled) { 578 if (mac && mac->enabled) {
662 macbuf = mac_compute(mac, send_seqnr, 579 macbuf = mac_compute(mac, seqnr,
663 buffer_ptr(&outgoing_packet), 580 buffer_ptr(&outgoing_packet),
664 buffer_len(&outgoing_packet)); 581 buffer_len(&outgoing_packet));
665 DBG(debug("done calc MAC out #%d", send_seqnr)); 582 DBG(debug("done calc MAC out #%d", seqnr));
666 } 583 }
667 /* encrypt packet and append to output buffer. */ 584 /* encrypt packet and append to output buffer. */
668 cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); 585 cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
@@ -676,7 +593,7 @@ packet_send2(void)
676 buffer_dump(&output); 593 buffer_dump(&output);
677#endif 594#endif
678 /* increment sequence number for outgoing packets */ 595 /* increment sequence number for outgoing packets */
679 if (++send_seqnr == 0) 596 if (++seqnr == 0)
680 log("outgoing seqnr wraps around"); 597 log("outgoing seqnr wraps around");
681 buffer_clear(&outgoing_packet); 598 buffer_clear(&outgoing_packet);
682 599
@@ -866,6 +783,7 @@ packet_read_poll1(void)
866static int 783static int
867packet_read_poll2(u_int32_t *seqnr_p) 784packet_read_poll2(u_int32_t *seqnr_p)
868{ 785{
786 static u_int32_t seqnr = 0;
869 static u_int packet_length = 0; 787 static u_int packet_length = 0;
870 u_int padlen, need; 788 u_int padlen, need;
871 u_char *macbuf, *cp, type; 789 u_char *macbuf, *cp, type;
@@ -927,17 +845,17 @@ packet_read_poll2(u_int32_t *seqnr_p)
927 * increment sequence number for incoming packet 845 * increment sequence number for incoming packet
928 */ 846 */
929 if (mac && mac->enabled) { 847 if (mac && mac->enabled) {
930 macbuf = mac_compute(mac, read_seqnr, 848 macbuf = mac_compute(mac, seqnr,
931 buffer_ptr(&incoming_packet), 849 buffer_ptr(&incoming_packet),
932 buffer_len(&incoming_packet)); 850 buffer_len(&incoming_packet));
933 if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) 851 if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
934 packet_disconnect("Corrupted MAC on input."); 852 packet_disconnect("Corrupted MAC on input.");
935 DBG(debug("MAC #%d ok", read_seqnr)); 853 DBG(debug("MAC #%d ok", seqnr));
936 buffer_consume(&input, mac->mac_len); 854 buffer_consume(&input, mac->mac_len);
937 } 855 }
938 if (seqnr_p != NULL) 856 if (seqnr_p != NULL)
939 *seqnr_p = read_seqnr; 857 *seqnr_p = seqnr;
940 if (++read_seqnr == 0) 858 if (++seqnr == 0)
941 log("incoming seqnr wraps around"); 859 log("incoming seqnr wraps around");
942 860
943 /* get padlen */ 861 /* get padlen */
diff --git a/packet.h b/packet.h
index b87a03cf8..d6bf2aab4 100644
--- a/packet.h
+++ b/packet.h
@@ -56,13 +56,6 @@ void *packet_get_string(u_int *length_ptr);
56void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); 56void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2)));
57void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); 57void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
58 58
59void set_newkeys(int mode);
60void packet_get_keyiv(int, u_char *, u_int);
61int packet_get_keycontext(int, u_char *);
62void packet_set_keycontext(int, u_char *);
63u_int32_t packet_get_seqnr(int);
64void packet_set_seqnr(int, u_int32_t);
65
66void packet_write_poll(void); 59void packet_write_poll(void);
67void packet_write_wait(void); 60void packet_write_wait(void);
68int packet_have_data_to_write(void); 61int packet_have_data_to_write(void);
diff --git a/servconf.c b/servconf.c
index c3f1253e8..9bbd994ca 100644
--- a/servconf.c
+++ b/servconf.c
@@ -36,8 +36,6 @@ static void add_one_listen_addr(ServerOptions *, char *, u_short);
36 36
37/* AF_UNSPEC or AF_INET or AF_INET6 */ 37/* AF_UNSPEC or AF_INET or AF_INET6 */
38extern int IPv4or6; 38extern int IPv4or6;
39/* Use of privilege separation or not */
40extern int use_privsep;
41 39
42/* Initializes the server options to their default values. */ 40/* Initializes the server options to their default values. */
43 41
@@ -112,9 +110,6 @@ initialize_server_options(ServerOptions *options)
112 options->client_alive_count_max = -1; 110 options->client_alive_count_max = -1;
113 options->authorized_keys_file = NULL; 111 options->authorized_keys_file = NULL;
114 options->authorized_keys_file2 = NULL; 112 options->authorized_keys_file2 = NULL;
115
116 /* Needs to be accessable in many places */
117 use_privsep = -1;
118} 113}
119 114
120void 115void
@@ -240,10 +235,6 @@ fill_default_server_options(ServerOptions *options)
240 } 235 }
241 if (options->authorized_keys_file == NULL) 236 if (options->authorized_keys_file == NULL)
242 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; 237 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
243
244 /* Turn privilege separation on by default */
245 if (use_privsep == -1)
246 use_privsep = 1;
247} 238}
248 239
249/* Keyword tokens. */ 240/* Keyword tokens. */
@@ -276,7 +267,6 @@ typedef enum {
276 sBanner, sVerifyReverseMapping, sHostbasedAuthentication, 267 sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
277 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 268 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
278 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 269 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
279 sUsePrivilegeSeparation,
280 sDeprecated 270 sDeprecated
281} ServerOpCodes; 271} ServerOpCodes;
282 272
@@ -352,7 +342,6 @@ static struct {
352 { "clientalivecountmax", sClientAliveCountMax }, 342 { "clientalivecountmax", sClientAliveCountMax },
353 { "authorizedkeysfile", sAuthorizedKeysFile }, 343 { "authorizedkeysfile", sAuthorizedKeysFile },
354 { "authorizedkeysfile2", sAuthorizedKeysFile2 }, 344 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
355 { "useprivilegeseparation", sUsePrivilegeSeparation},
356 { NULL, sBadOption } 345 { NULL, sBadOption }
357}; 346};
358 347
@@ -729,10 +718,6 @@ parse_flag:
729 intptr = &options->allow_tcp_forwarding; 718 intptr = &options->allow_tcp_forwarding;
730 goto parse_flag; 719 goto parse_flag;
731 720
732 case sUsePrivilegeSeparation:
733 intptr = &use_privsep;
734 goto parse_flag;
735
736 case sAllowUsers: 721 case sAllowUsers:
737 while ((arg = strdelim(&cp)) && *arg != '\0') { 722 while ((arg = strdelim(&cp)) && *arg != '\0') {
738 if (options->num_allow_users >= MAX_ALLOW_USERS) 723 if (options->num_allow_users >= MAX_ALLOW_USERS)
diff --git a/session.c b/session.c
index 17227c9ff..a31ff85d8 100644
--- a/session.c
+++ b/session.c
@@ -56,8 +56,6 @@ RCSID("$OpenBSD: session.c,v 1.128 2002/02/16 00:51:44 markus Exp $");
56#include "serverloop.h" 56#include "serverloop.h"
57#include "canohost.h" 57#include "canohost.h"
58#include "session.h" 58#include "session.h"
59#include "monitor.h"
60#include "monitor_wrap.h"
61 59
62#ifdef HAVE_CYGWIN 60#ifdef HAVE_CYGWIN
63#include <windows.h> 61#include <windows.h>
@@ -65,15 +63,39 @@ RCSID("$OpenBSD: session.c,v 1.128 2002/02/16 00:51:44 markus Exp $");
65#define is_winnt (GetVersion() < 0x80000000) 63#define is_winnt (GetVersion() < 0x80000000)
66#endif 64#endif
67 65
68/* Imports */ 66/* types */
69extern int use_privsep; 67
70extern int mm_recvfd; 68#define TTYSZ 64
69typedef struct Session Session;
70struct Session {
71 int used;
72 int self;
73 struct passwd *pw;
74 Authctxt *authctxt;
75 pid_t pid;
76 /* tty */
77 char *term;
78 int ptyfd, ttyfd, ptymaster;
79 int row, col, xpixel, ypixel;
80 char tty[TTYSZ];
81 /* X11 */
82 int display_number;
83 char *display;
84 int screen;
85 char *auth_display;
86 char *auth_proto;
87 char *auth_data;
88 int single_connection;
89 /* proto 2 */
90 int chanid;
91 int is_subsystem;
92};
71 93
72/* func */ 94/* func */
73 95
74Session *session_new(void); 96Session *session_new(void);
75void session_set_fds(Session *, int, int, int); 97void session_set_fds(Session *, int, int, int);
76void session_pty_cleanup(void *); 98static void session_pty_cleanup(void *);
77void session_proctitle(Session *); 99void session_proctitle(Session *);
78int session_setup_x11fwd(Session *); 100int session_setup_x11fwd(Session *);
79void do_exec_pty(Session *, const char *); 101void do_exec_pty(Session *, const char *);
@@ -90,6 +112,7 @@ int check_quietlogin(Session *, const char *);
90static void do_authenticated1(Authctxt *); 112static void do_authenticated1(Authctxt *);
91static void do_authenticated2(Authctxt *); 113static void do_authenticated2(Authctxt *);
92 114
115static void session_close(Session *);
93static int session_pty_req(Session *); 116static int session_pty_req(Session *);
94 117
95/* import */ 118/* import */
@@ -1425,8 +1448,7 @@ session_pty_req(Session *s)
1425{ 1448{
1426 u_int len; 1449 u_int len;
1427 int n_bytes; 1450 int n_bytes;
1428 int res; 1451
1429
1430 if (no_pty_flag) { 1452 if (no_pty_flag) {
1431 debug("Allocating a pty not permitted for this authentication."); 1453 debug("Allocating a pty not permitted for this authentication.");
1432 return 0; 1454 return 0;
@@ -1455,15 +1477,7 @@ session_pty_req(Session *s)
1455 1477
1456 /* Allocate a pty and open it. */ 1478 /* Allocate a pty and open it. */
1457 debug("Allocating pty."); 1479 debug("Allocating pty.");
1458 if (!use_privsep) { 1480 if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) {
1459 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
1460 sizeof(s->tty));
1461 if (res)
1462 pty_setowner(s->pw, s->tty);
1463 } else
1464 res = mm_pty_allocown(mm_recvfd,
1465 &s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1466 if (!res) {
1467 if (s->term) 1481 if (s->term)
1468 xfree(s->term); 1482 xfree(s->term);
1469 s->term = NULL; 1483 s->term = NULL;
@@ -1484,6 +1498,7 @@ session_pty_req(Session *s)
1484 * time in case we call fatal() (e.g., the connection gets closed). 1498 * time in case we call fatal() (e.g., the connection gets closed).
1485 */ 1499 */
1486 fatal_add_cleanup(session_pty_cleanup, (void *)s); 1500 fatal_add_cleanup(session_pty_cleanup, (void *)s);
1501 pty_setowner(s->pw, s->tty);
1487 1502
1488 /* Set window size from the packet. */ 1503 /* Set window size from the packet. */
1489 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1504 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
@@ -1646,7 +1661,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr)
1646 * Function to perform pty cleanup. Also called if we get aborted abnormally 1661 * Function to perform pty cleanup. Also called if we get aborted abnormally
1647 * (e.g., due to a dropped connection). 1662 * (e.g., due to a dropped connection).
1648 */ 1663 */
1649void 1664static void
1650session_pty_cleanup(void *session) 1665session_pty_cleanup(void *session)
1651{ 1666{
1652 Session *s = session; 1667 Session *s = session;
@@ -1724,7 +1739,7 @@ session_exit_message(Session *s, int status)
1724 s->chanid = -1; 1739 s->chanid = -1;
1725} 1740}
1726 1741
1727void 1742static void
1728session_close(Session *s) 1743session_close(Session *s)
1729{ 1744{
1730 debug("session_close: session %d pid %d", s->self, s->pid); 1745 debug("session_close: session %d pid %d", s->self, s->pid);
diff --git a/session.h b/session.h
index e3123beed..ec8284a5f 100644
--- a/session.h
+++ b/session.h
@@ -26,32 +26,6 @@
26#ifndef SESSION_H 26#ifndef SESSION_H
27#define SESSION_H 27#define SESSION_H
28 28
29#define TTYSZ 64
30typedef struct Session Session;
31struct Session {
32 int used;
33 int self;
34 struct passwd *pw;
35 Authctxt *authctxt;
36 pid_t pid;
37 /* tty */
38 char *term;
39 int ptyfd, ttyfd, ptymaster;
40 int row, col, xpixel, ypixel;
41 char tty[TTYSZ];
42 /* X11 */
43 int display_number;
44 char *display;
45 int screen;
46 char *auth_display;
47 char *auth_proto;
48 char *auth_data;
49 int single_connection;
50 /* proto 2 */
51 int chanid;
52 int is_subsystem;
53};
54
55void do_authenticated(Authctxt *); 29void do_authenticated(Authctxt *);
56 30
57int session_open(Authctxt*, int); 31int session_open(Authctxt*, int);
@@ -60,6 +34,4 @@ void session_close_by_pid(pid_t, int);
60void session_close_by_channel(int, void *); 34void session_close_by_channel(int, void *);
61void session_destroy_all(void); 35void session_destroy_all(void);
62 36
63Session *session_new(void);
64void session_close(Session *);
65#endif 37#endif
diff --git a/sshd.c b/sshd.c
index cbe316087..ea9293251 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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;
194int *startup_pipes = NULL; 189int *startup_pipes = NULL;
195int startup_pipe; /* in child */ 190int startup_pipe; /* in child */
196 191
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
208/* Prototypes for various functions defined later in this file. */ 192/* Prototypes for various functions defined later in this file. */
209void destroy_sensitive_data(void); 193void destroy_sensitive_data(void);
210void demote_sensitive_data(void);
211 194
212static void do_ssh1_kex(void); 195static void do_ssh1_kex(void);
213static void do_ssh2_kex(void); 196static 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 */
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
560static char * 480static char *
561list_hostkey_types(void) 481list_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
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
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