summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2004-03-01 02:25:32 +0000
committerColin Watson <cjwatson@debian.org>2004-03-01 02:25:32 +0000
commitea8116a11e3de70036dbc665ccb0d486cf89cac9 (patch)
treed73ccdff78d8608e156465af42e6a1b3527fb2d6 /sshd.c
parente39b311381a5609cc05acf298c42fba196dc524b (diff)
parentf5bda272678ec6dccaa5f29379cf60cb855018e8 (diff)
Merge 3.8p1 to the trunk. This builds and runs, but I haven't tested it
extensively yet. ProtocolKeepAlives is now just a compatibility alias for ServerAliveInterval.
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c108
1 files changed, 64 insertions, 44 deletions
diff --git a/sshd.c b/sshd.c
index 92fab6ccd..1f0d7747a 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.276 2003/08/28 12:54:34 markus Exp $"); 45RCSID("$OpenBSD: sshd.c,v 1.286 2004/02/23 12:02:33 markus Exp $");
46 46
47#include <openssl/dh.h> 47#include <openssl/dh.h>
48#include <openssl/bn.h> 48#include <openssl/bn.h>
@@ -101,6 +101,7 @@ extern char *__progname;
101#else 101#else
102char *__progname; 102char *__progname;
103#endif 103#endif
104extern char **environ;
104 105
105/* Server configuration options. */ 106/* Server configuration options. */
106ServerOptions options; 107ServerOptions options;
@@ -199,11 +200,14 @@ int startup_pipe; /* in child */
199 200
200/* variables used for privilege separation */ 201/* variables used for privilege separation */
201int use_privsep; 202int use_privsep;
202struct monitor *pmonitor; 203struct monitor *pmonitor = NULL;
203 204
204/* message to be displayed after login */ 205/* message to be displayed after login */
205Buffer loginmsg; 206Buffer loginmsg;
206 207
208/* global authentication context */
209Authctxt *the_authctxt = NULL;
210
207/* Prototypes for various functions defined later in this file. */ 211/* Prototypes for various functions defined later in this file. */
208void destroy_sensitive_data(void); 212void destroy_sensitive_data(void);
209void demote_sensitive_data(void); 213void demote_sensitive_data(void);
@@ -302,6 +306,9 @@ grace_alarm_handler(int sig)
302{ 306{
303 /* XXX no idea how fix this signal handler */ 307 /* XXX no idea how fix this signal handler */
304 308
309 if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
310 kill(pmonitor->m_pid, SIGALRM);
311
305 /* Log error and exit. */ 312 /* Log error and exit. */
306 fatal("Timeout before authentication for %s", get_remote_ipaddr()); 313 fatal("Timeout before authentication for %s", get_remote_ipaddr());
307} 314}
@@ -375,7 +382,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
375 strlen(server_version_string)) 382 strlen(server_version_string))
376 != strlen(server_version_string)) { 383 != strlen(server_version_string)) {
377 logit("Could not write ident string to %s", get_remote_ipaddr()); 384 logit("Could not write ident string to %s", get_remote_ipaddr());
378 fatal_cleanup(); 385 cleanup_exit(255);
379 } 386 }
380 387
381 /* Read other sides version identification. */ 388 /* Read other sides version identification. */
@@ -384,7 +391,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
384 if (atomicio(read, sock_in, &buf[i], 1) != 1) { 391 if (atomicio(read, sock_in, &buf[i], 1) != 1) {
385 logit("Did not receive identification string from %s", 392 logit("Did not receive identification string from %s",
386 get_remote_ipaddr()); 393 get_remote_ipaddr());
387 fatal_cleanup(); 394 cleanup_exit(255);
388 } 395 }
389 if (buf[i] == '\r') { 396 if (buf[i] == '\r') {
390 buf[i] = 0; 397 buf[i] = 0;
@@ -414,7 +421,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
414 close(sock_out); 421 close(sock_out);
415 logit("Bad protocol version identification '%.100s' from %s", 422 logit("Bad protocol version identification '%.100s' from %s",
416 client_version_string, get_remote_ipaddr()); 423 client_version_string, get_remote_ipaddr());
417 fatal_cleanup(); 424 cleanup_exit(255);
418 } 425 }
419 debug("Client protocol version %d.%d; client software version %.100s", 426 debug("Client protocol version %d.%d; client software version %.100s",
420 remote_major, remote_minor, remote_version); 427 remote_major, remote_minor, remote_version);
@@ -424,13 +431,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
424 if (datafellows & SSH_BUG_PROBE) { 431 if (datafellows & SSH_BUG_PROBE) {
425 logit("probed from %s with %s. Don't panic.", 432 logit("probed from %s with %s. Don't panic.",
426 get_remote_ipaddr(), client_version_string); 433 get_remote_ipaddr(), client_version_string);
427 fatal_cleanup(); 434 cleanup_exit(255);
428 } 435 }
429 436
430 if (datafellows & SSH_BUG_SCANNER) { 437 if (datafellows & SSH_BUG_SCANNER) {
431 logit("scanned from %s with %s. Don't panic.", 438 logit("scanned from %s with %s. Don't panic.",
432 get_remote_ipaddr(), client_version_string); 439 get_remote_ipaddr(), client_version_string);
433 fatal_cleanup(); 440 cleanup_exit(255);
434 } 441 }
435 442
436 mismatch = 0; 443 mismatch = 0;
@@ -476,7 +483,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
476 logit("Protocol major versions differ for %s: %.200s vs. %.200s", 483 logit("Protocol major versions differ for %s: %.200s vs. %.200s",
477 get_remote_ipaddr(), 484 get_remote_ipaddr(),
478 server_version_string, client_version_string); 485 server_version_string, client_version_string);
479 fatal_cleanup(); 486 cleanup_exit(255);
480 } 487 }
481} 488}
482 489
@@ -571,10 +578,9 @@ privsep_preauth_child(void)
571#endif 578#endif
572} 579}
573 580
574static Authctxt * 581static int
575privsep_preauth(void) 582privsep_preauth(Authctxt *authctxt)
576{ 583{
577 Authctxt *authctxt = NULL;
578 int status; 584 int status;
579 pid_t pid; 585 pid_t pid;
580 586
@@ -587,12 +593,11 @@ privsep_preauth(void)
587 if (pid == -1) { 593 if (pid == -1) {
588 fatal("fork of unprivileged child failed"); 594 fatal("fork of unprivileged child failed");
589 } else if (pid != 0) { 595 } else if (pid != 0) {
590 fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
591
592 debug2("Network child is on pid %ld", (long)pid); 596 debug2("Network child is on pid %ld", (long)pid);
593 597
594 close(pmonitor->m_recvfd); 598 close(pmonitor->m_recvfd);
595 authctxt = monitor_child_preauth(pmonitor); 599 pmonitor->m_pid = pid;
600 monitor_child_preauth(authctxt, pmonitor);
596 close(pmonitor->m_sendfd); 601 close(pmonitor->m_sendfd);
597 602
598 /* Sync memory */ 603 /* Sync memory */
@@ -602,11 +607,7 @@ privsep_preauth(void)
602 while (waitpid(pid, &status, 0) < 0) 607 while (waitpid(pid, &status, 0) < 0)
603 if (errno != EINTR) 608 if (errno != EINTR)
604 break; 609 break;
605 610 return (1);
606 /* Reinstall, since the child has finished */
607 fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
608
609 return (authctxt);
610 } else { 611 } else {
611 /* child */ 612 /* child */
612 613
@@ -617,17 +618,12 @@ privsep_preauth(void)
617 privsep_preauth_child(); 618 privsep_preauth_child();
618 setproctitle("%s", "[net]"); 619 setproctitle("%s", "[net]");
619 } 620 }
620 return (NULL); 621 return (0);
621} 622}
622 623
623static void 624static void
624privsep_postauth(Authctxt *authctxt) 625privsep_postauth(Authctxt *authctxt)
625{ 626{
626 extern Authctxt *x_authctxt;
627
628 /* XXX - Remote port forwarding */
629 x_authctxt = authctxt;
630
631#ifdef DISABLE_FD_PASSING 627#ifdef DISABLE_FD_PASSING
632 if (1) { 628 if (1) {
633#else 629#else
@@ -653,8 +649,6 @@ privsep_postauth(Authctxt *authctxt)
653 if (pmonitor->m_pid == -1) 649 if (pmonitor->m_pid == -1)
654 fatal("fork of unprivileged child failed"); 650 fatal("fork of unprivileged child failed");
655 else if (pmonitor->m_pid != 0) { 651 else if (pmonitor->m_pid != 0) {
656 fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
657
658 debug2("User child is on pid %ld", (long)pmonitor->m_pid); 652 debug2("User child is on pid %ld", (long)pmonitor->m_pid);
659 close(pmonitor->m_recvfd); 653 close(pmonitor->m_recvfd);
660 monitor_child_postauth(pmonitor); 654 monitor_child_postauth(pmonitor);
@@ -679,7 +673,8 @@ static char *
679list_hostkey_types(void) 673list_hostkey_types(void)
680{ 674{
681 Buffer b; 675 Buffer b;
682 char *p; 676 const char *p;
677 char *ret;
683 int i; 678 int i;
684 679
685 buffer_init(&b); 680 buffer_init(&b);
@@ -698,10 +693,10 @@ list_hostkey_types(void)
698 } 693 }
699 } 694 }
700 buffer_append(&b, "\0", 1); 695 buffer_append(&b, "\0", 1);
701 p = xstrdup(buffer_ptr(&b)); 696 ret = xstrdup(buffer_ptr(&b));
702 buffer_free(&b); 697 buffer_free(&b);
703 debug("list_hostkey_types: %s", p); 698 debug("list_hostkey_types: %s", ret);
704 return p; 699 return ret;
705} 700}
706 701
707Key * 702Key *
@@ -769,7 +764,8 @@ drop_connection(int startups)
769static void 764static void
770usage(void) 765usage(void)
771{ 766{
772 fprintf(stderr, "sshd version %s\n", SSH_VERSION); 767 fprintf(stderr, "sshd version %s, %s\n",
768 SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
773 fprintf(stderr, "Usage: %s [options]\n", __progname); 769 fprintf(stderr, "Usage: %s [options]\n", __progname);
774 fprintf(stderr, "Options:\n"); 770 fprintf(stderr, "Options:\n");
775 fprintf(stderr, " -f file Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE); 771 fprintf(stderr, " -f file Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE);
@@ -809,11 +805,12 @@ main(int ac, char **av)
809 FILE *f; 805 FILE *f;
810 struct addrinfo *ai; 806 struct addrinfo *ai;
811 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 807 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
808 char *line;
812 int listen_sock, maxfd; 809 int listen_sock, maxfd;
813 int startup_p[2]; 810 int startup_p[2];
814 int startups = 0; 811 int startups = 0;
815 Authctxt *authctxt;
816 Key *key; 812 Key *key;
813 Authctxt *authctxt;
817 int ret, key_used = 0; 814 int ret, key_used = 0;
818 815
819#ifdef HAVE_SECUREWARE 816#ifdef HAVE_SECUREWARE
@@ -922,9 +919,11 @@ main(int ac, char **av)
922 } 919 }
923 break; 920 break;
924 case 'o': 921 case 'o':
925 if (process_server_config_line(&options, optarg, 922 line = xstrdup(optarg);
923 if (process_server_config_line(&options, line,
926 "command-line", 0) != 0) 924 "command-line", 0) != 0)
927 exit(1); 925 exit(1);
926 xfree(line);
928 break; 927 break;
929 case '?': 928 case '?':
930 default: 929 default:
@@ -1069,8 +1068,8 @@ main(int ac, char **av)
1069 /* 1068 /*
1070 * Clear out any supplemental groups we may have inherited. This 1069 * Clear out any supplemental groups we may have inherited. This
1071 * prevents inadvertent creation of files with bad modes (in the 1070 * prevents inadvertent creation of files with bad modes (in the
1072 * portable version at least, it's certainly possible for PAM 1071 * portable version at least, it's certainly possible for PAM
1073 * to create a file, and we can't control the code in every 1072 * to create a file, and we can't control the code in every
1074 * module which might be used). 1073 * module which might be used).
1075 */ 1074 */
1076 if (setgroups(0, NULL) < 0) 1075 if (setgroups(0, NULL) < 0)
@@ -1112,6 +1111,11 @@ main(int ac, char **av)
1112 unmounted if desired. */ 1111 unmounted if desired. */
1113 chdir("/"); 1112 chdir("/");
1114 1113
1114#ifndef HAVE_CYGWIN
1115 /* Clear environment */
1116 environ[0] = NULL;
1117#endif
1118
1115 /* ignore SIGPIPE */ 1119 /* ignore SIGPIPE */
1116 signal(SIGPIPE, SIG_IGN); 1120 signal(SIGPIPE, SIG_IGN);
1117 1121
@@ -1180,7 +1184,7 @@ main(int ac, char **av)
1180 1184
1181 /* Start listening on the port. */ 1185 /* Start listening on the port. */
1182 logit("Server listening on %s port %s.", ntop, strport); 1186 logit("Server listening on %s port %s.", ntop, strport);
1183 if (listen(listen_sock, 5) < 0) 1187 if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
1184 fatal("listen: %.100s", strerror(errno)); 1188 fatal("listen: %.100s", strerror(errno));
1185 1189
1186 } 1190 }
@@ -1419,8 +1423,8 @@ main(int ac, char **av)
1419 signal(SIGCHLD, SIG_DFL); 1423 signal(SIGCHLD, SIG_DFL);
1420 signal(SIGINT, SIG_DFL); 1424 signal(SIGINT, SIG_DFL);
1421 1425
1422 /* Set keepalives if requested. */ 1426 /* Set SO_KEEPALIVE if requested. */
1423 if (options.keepalives && 1427 if (options.tcp_keep_alive &&
1424 setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, 1428 setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on,
1425 sizeof(on)) < 0) 1429 sizeof(on)) < 0)
1426 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 1430 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
@@ -1470,21 +1474,28 @@ main(int ac, char **av)
1470 1474
1471 packet_set_nonblocking(); 1475 packet_set_nonblocking();
1472 1476
1473 /* prepare buffers to collect authentication messages */ 1477 /* prepare buffers to collect authentication messages */
1474 buffer_init(&loginmsg); 1478 buffer_init(&loginmsg);
1475 1479
1480 /* allocate authentication context */
1481 authctxt = xmalloc(sizeof(*authctxt));
1482 memset(authctxt, 0, sizeof(*authctxt));
1483
1484 /* XXX global for cleanup, access from other modules */
1485 the_authctxt = authctxt;
1486
1476 if (use_privsep) 1487 if (use_privsep)
1477 if ((authctxt = privsep_preauth()) != NULL) 1488 if (privsep_preauth(authctxt) == 1)
1478 goto authenticated; 1489 goto authenticated;
1479 1490
1480 /* perform the key exchange */ 1491 /* perform the key exchange */
1481 /* authenticate user and start session */ 1492 /* authenticate user and start session */
1482 if (compat20) { 1493 if (compat20) {
1483 do_ssh2_kex(); 1494 do_ssh2_kex();
1484 authctxt = do_authentication2(); 1495 do_authentication2(authctxt);
1485 } else { 1496 } else {
1486 do_ssh1_kex(); 1497 do_ssh1_kex();
1487 authctxt = do_authentication(); 1498 do_authentication(authctxt);
1488 } 1499 }
1489 /* 1500 /*
1490 * If we use privilege separation, the unprivileged child transfers 1501 * If we use privilege separation, the unprivileged child transfers
@@ -1507,7 +1518,7 @@ main(int ac, char **av)
1507 destroy_sensitive_data(); 1518 destroy_sensitive_data();
1508 } 1519 }
1509 1520
1510 /* Perform session preparation. */ 1521 /* Start session. */
1511 do_authenticated(authctxt); 1522 do_authenticated(authctxt);
1512 1523
1513 /* The connection has been terminated. */ 1524 /* The connection has been terminated. */
@@ -1800,3 +1811,12 @@ do_ssh2_kex(void)
1800#endif 1811#endif
1801 debug("KEX done"); 1812 debug("KEX done");
1802} 1813}
1814
1815/* server specific fatal cleanup */
1816void
1817cleanup_exit(int i)
1818{
1819 if (the_authctxt)
1820 do_cleanup(the_authctxt);
1821 _exit(i);
1822}