summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2008-07-22 19:45:18 +0000
committerColin Watson <cjwatson@debian.org>2008-07-22 19:45:18 +0000
commit137d76ba65883aa8143af1fcad83b57e7badef0c (patch)
treef426e804bb5248ceafedfab7bb78ae6e6752942c /sshd.c
parentdac7d049dad31f5f84d421d4eb628a7e13f977d7 (diff)
parentef94e5613d37bcbf880f21ee6094e4b1c7683a4c (diff)
* New upstream release (closes: #474301). Important changes not previously
backported to 4.7p1: - 4.9/4.9p1 (http://www.openssh.com/txt/release-4.9): + Added chroot(2) support for sshd(8), controlled by a new option "ChrootDirectory" (closes: #139047, LP: #24777). + Linked sftp-server(8) into sshd(8). The internal sftp server is used when the command "internal-sftp" is specified in a Subsystem or ForceCommand declaration. When used with ChrootDirectory, the internal sftp server requires no special configuration of files inside the chroot environment. + Added a protocol extension method "posix-rename@openssh.com" for sftp-server(8) to perform POSIX atomic rename() operations; sftp(1) prefers this if available (closes: #308561). + Removed the fixed limit of 100 file handles in sftp-server(8). + ssh(8) will now skip generation of SSH protocol 1 ephemeral server keys when in inetd mode and protocol 2 connections are negotiated. This speeds up protocol 2 connections to inetd-mode servers that also allow Protocol 1. + Accept the PermitRootLogin directive in a sshd_config(5) Match block. Allows for, e.g. permitting root only from the local network. + Reworked sftp(1) argument splitting and escaping to be more internally consistent (i.e. between sftp commands) and more consistent with sh(1). Please note that this will change the interpretation of some quoted strings, especially those with embedded backslash escape sequences. + Support "Banner=none" in sshd_config(5) to disable sending of a pre-login banner (e.g. in a Match block). + ssh(1) ProxyCommands are now executed with $SHELL rather than /bin/sh. + ssh(1)'s ConnectTimeout option is now applied to both the TCP connection and the SSH banner exchange (previously it just covered the TCP connection). This allows callers of ssh(1) to better detect and deal with stuck servers that accept a TCP connection but don't progress the protocol, and also makes ConnectTimeout useful for connections via a ProxyCommand. + scp(1) incorrectly reported "stalled" on slow copies (closes: #140828). + scp(1) date underflow for timestamps before epoch. + ssh(1) used the obsolete SIG DNS RRtype for host keys in DNS, instead of the current standard RRSIG. + Correctly drain ACKs when a sftp(1) upload write fails midway, avoids a fatal() exit from what should be a recoverable condition. + Fixed ssh-keygen(1) selective host key hashing (i.e. "ssh-keygen -HF hostname") to not include any IP address in the data to be hashed. + Make ssh(1) skip listening on the IPv6 wildcard address when a binding address of 0.0.0.0 is used against an old SSH server that does not support the RFC4254 syntax for wildcard bind addresses. + Enable IPV6_V6ONLY socket option on sshd(8) listen socket, as is already done for X11/TCP forwarding sockets (closes: #439661). + Fix FD leak that could hang a ssh(1) connection multiplexing master. + Make ssh(1) -q option documentation consistent with reality. + Fixed sshd(8) PAM support not calling pam_session_close(), or failing to call it with root privileges (closes: #372680). + Fix activation of OpenSSL engine support when requested in configure (LP: #119295). - 5.1/5.1p1 (http://www.openssh.com/txt/release-5.1): + Introduce experimental SSH Fingerprint ASCII Visualisation to ssh(1) and ssh-keygen(1). Visual fingerprint display is controlled by a new ssh_config(5) option "VisualHostKey". The intent is to render SSH host keys in a visual form that is amenable to easy recall and rejection of changed host keys. + sshd_config(5) now supports CIDR address/masklen matching in "Match address" blocks, with a fallback to classic wildcard matching. + sshd(8) now supports CIDR matching in ~/.ssh/authorized_keys from="..." restrictions, also with a fallback to classic wildcard matching. + Added an extended test mode (-T) to sshd(8) to request that it write its effective configuration to stdout and exit. Extended test mode also supports the specification of connection parameters (username, source address and hostname) to test the application of sshd_config(5) Match rules. + ssh(1) now prints the number of bytes transferred and the overall connection throughput for SSH protocol 2 sessions when in verbose mode (previously these statistics were displayed for protocol 1 connections only). + sftp-server(8) now supports extension methods statvfs@openssh.com and fstatvfs@openssh.com that implement statvfs(2)-like operations. + sftp(1) now has a "df" command to the sftp client that uses the statvfs@openssh.com to produce a df(1)-like display of filesystem space and inode utilisation (requires statvfs@openssh.com support on the server). + Added a MaxSessions option to sshd_config(5) to allow control of the number of multiplexed sessions supported over a single TCP connection. This allows increasing the number of allowed sessions above the previous default of 10, disabling connection multiplexing (MaxSessions=1) or disallowing login/shell/subsystem sessions entirely (MaxSessions=0). + Added a no-more-sessions@openssh.com global request extension that is sent from ssh(1) to sshd(8) when the client knows that it will never request another session (i.e. when session multiplexing is disabled). This allows a server to disallow further session requests and terminate the session in cases where the client has been hijacked. + ssh-keygen(1) now supports the use of the -l option in combination with -F to search for a host in ~/.ssh/known_hosts and display its fingerprint. + ssh-keyscan(1) now defaults to "rsa" (protocol 2) keys, instead of "rsa1". + Added an AllowAgentForwarding option to sshd_config(8) to control whether authentication agent forwarding is permitted. Note that this is a loose control, as a client may install their own unofficial forwarder. + ssh(1) and sshd(8): avoid unnecessary malloc/copy/free when receiving network data, resulting in a ~10% speedup. + ssh(1) and sshd(8) will now try additional addresses when connecting to a port forward destination whose DNS name resolves to more than one address. The previous behaviour was to try the only first address and give up if that failed. + ssh(1) and sshd(8) now support signalling that channels are half-closed for writing, through a channel protocol extension notification "eow@openssh.com". This allows propagation of closed file descriptors, so that commands such as "ssh -2 localhost od /bin/ls | true" do not send unnecessary data over the wire. + sshd(8): increased the default size of ssh protocol 1 ephemeral keys from 768 to 1024 bits. + When ssh(1) has been requested to fork after authentication ("ssh -f") with ExitOnForwardFailure enabled, delay the fork until after replies for any -R forwards have been seen. Allows for robust detection of -R forward failure when using -f. + "Match group" blocks in sshd_config(5) now support negation of groups. E.g. "Match group staff,!guests". + sftp(1) and sftp-server(8) now allow chmod-like operations to set set[ug]id/sticky bits. + The MaxAuthTries option is now permitted in sshd_config(5) match blocks. + Multiplexed ssh(1) sessions now support a subset of the ~ escapes that are available to a primary connection. + ssh(1) connection multiplexing will now fall back to creating a new connection in most error cases (closes: #352830). + Make ssh(1) deal more gracefully with channel requests that fail. Previously it would optimistically assume that requests would always succeed, which could cause hangs if they did not (e.g. when the server runs out of file descriptors). + ssh(1) now reports multiplexing errors via the multiplex slave's stderr where possible (subject to LogLevel in the mux master). + Prevent sshd(8) from erroneously applying public key restrictions leaned from ~/.ssh/authorized_keys to other authentication methods when public key authentication subsequently fails (LP: #161047). + Fixed an UMAC alignment problem that manifested on Itanium platforms.
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c160
1 files changed, 119 insertions, 41 deletions
diff --git a/sshd.c b/sshd.c
index 9097d71ad..9e03cf3ef 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.351 2007/05/22 10:18:52 djm Exp $ */ 1/* $OpenBSD: sshd.c,v 1.364 2008/07/10 18:08:11 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -54,6 +54,7 @@
54# include <sys/time.h> 54# include <sys/time.h>
55#endif 55#endif
56#include "openbsd-compat/sys-tree.h" 56#include "openbsd-compat/sys-tree.h"
57#include "openbsd-compat/sys-queue.h"
57#include <sys/wait.h> 58#include <sys/wait.h>
58 59
59#include <errno.h> 60#include <errno.h>
@@ -75,6 +76,8 @@
75#include <openssl/bn.h> 76#include <openssl/bn.h>
76#include <openssl/md5.h> 77#include <openssl/md5.h>
77#include <openssl/rand.h> 78#include <openssl/rand.h>
79#include "openbsd-compat/openssl-compat.h"
80
78#ifdef HAVE_SECUREWARE 81#ifdef HAVE_SECUREWARE
79#include <sys/security.h> 82#include <sys/security.h>
80#include <prot.h> 83#include <prot.h>
@@ -124,8 +127,8 @@
124#ifdef LIBWRAP 127#ifdef LIBWRAP
125#include <tcpd.h> 128#include <tcpd.h>
126#include <syslog.h> 129#include <syslog.h>
127int allow_severity = LOG_INFO; 130int allow_severity;
128int deny_severity = LOG_WARNING; 131int deny_severity;
129#endif /* LIBWRAP */ 132#endif /* LIBWRAP */
130 133
131#ifndef O_NOCTTY 134#ifndef O_NOCTTY
@@ -375,9 +378,6 @@ grace_alarm_handler(int sig)
375static void 378static void
376generate_ephemeral_server_key(void) 379generate_ephemeral_server_key(void)
377{ 380{
378 u_int32_t rnd = 0;
379 int i;
380
381 verbose("Generating %s%d bit RSA key.", 381 verbose("Generating %s%d bit RSA key.",
382 sensitive_data.server_key ? "new " : "", options.server_key_bits); 382 sensitive_data.server_key ? "new " : "", options.server_key_bits);
383 if (sensitive_data.server_key != NULL) 383 if (sensitive_data.server_key != NULL)
@@ -386,12 +386,7 @@ generate_ephemeral_server_key(void)
386 options.server_key_bits); 386 options.server_key_bits);
387 verbose("RSA key generation complete."); 387 verbose("RSA key generation complete.");
388 388
389 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 389 arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
390 if (i % 4 == 0)
391 rnd = arc4random();
392 sensitive_data.ssh1_cookie[i] = rnd & 0xff;
393 rnd >>= 8;
394 }
395 arc4random_stir(); 390 arc4random_stir();
396} 391}
397 392
@@ -413,7 +408,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
413 int mismatch; 408 int mismatch;
414 int remote_major, remote_minor; 409 int remote_major, remote_minor;
415 int major, minor; 410 int major, minor;
416 char *s; 411 char *s, *newline = "\n";
417 char buf[256]; /* Must not be larger than remote_version. */ 412 char buf[256]; /* Must not be larger than remote_version. */
418 char remote_version[256]; /* Must be at least as big as buf. */ 413 char remote_version[256]; /* Must be at least as big as buf. */
419 414
@@ -424,11 +419,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
424 } else if (options.protocol & SSH_PROTO_2) { 419 } else if (options.protocol & SSH_PROTO_2) {
425 major = PROTOCOL_MAJOR_2; 420 major = PROTOCOL_MAJOR_2;
426 minor = PROTOCOL_MINOR_2; 421 minor = PROTOCOL_MINOR_2;
422 newline = "\r\n";
427 } else { 423 } else {
428 major = PROTOCOL_MAJOR_1; 424 major = PROTOCOL_MAJOR_1;
429 minor = PROTOCOL_MINOR_1; 425 minor = PROTOCOL_MINOR_1;
430 } 426 }
431 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE); 427 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
428 SSH_RELEASE, newline);
432 server_version_string = xstrdup(buf); 429 server_version_string = xstrdup(buf);
433 430
434 /* Send our protocol version identification. */ 431 /* Send our protocol version identification. */
@@ -590,15 +587,14 @@ demote_sensitive_data(void)
590static void 587static void
591privsep_preauth_child(void) 588privsep_preauth_child(void)
592{ 589{
593 u_int32_t rnd[256]; 590 u_int32_t rnd[256];
594 gid_t gidset[1]; 591 gid_t gidset[1];
595 int i;
596 592
597 /* Enable challenge-response authentication for privilege separation */ 593 /* Enable challenge-response authentication for privilege separation */
598 privsep_challenge_enable(); 594 privsep_challenge_enable();
599 595
600 for (i = 0; i < 256; i++) 596 arc4random_stir();
601 rnd[i] = arc4random(); 597 arc4random_buf(rnd, sizeof(rnd));
602 RAND_seed(rnd, sizeof(rnd)); 598 RAND_seed(rnd, sizeof(rnd));
603 599
604 /* Demote the private keys to public keys. */ 600 /* Demote the private keys to public keys. */
@@ -671,6 +667,8 @@ privsep_preauth(Authctxt *authctxt)
671static void 667static void
672privsep_postauth(Authctxt *authctxt) 668privsep_postauth(Authctxt *authctxt)
673{ 669{
670 u_int32_t rnd[256];
671
674#ifdef DISABLE_FD_PASSING 672#ifdef DISABLE_FD_PASSING
675 if (1) { 673 if (1) {
676#else 674#else
@@ -688,7 +686,7 @@ privsep_postauth(Authctxt *authctxt)
688 if (pmonitor->m_pid == -1) 686 if (pmonitor->m_pid == -1)
689 fatal("fork of unprivileged child failed"); 687 fatal("fork of unprivileged child failed");
690 else if (pmonitor->m_pid != 0) { 688 else if (pmonitor->m_pid != 0) {
691 debug2("User child is on pid %ld", (long)pmonitor->m_pid); 689 verbose("User child is on pid %ld", (long)pmonitor->m_pid);
692 close(pmonitor->m_recvfd); 690 close(pmonitor->m_recvfd);
693 buffer_clear(&loginmsg); 691 buffer_clear(&loginmsg);
694 monitor_child_postauth(pmonitor); 692 monitor_child_postauth(pmonitor);
@@ -702,6 +700,10 @@ privsep_postauth(Authctxt *authctxt)
702 /* Demote the private keys to public keys. */ 700 /* Demote the private keys to public keys. */
703 demote_sensitive_data(); 701 demote_sensitive_data();
704 702
703 arc4random_stir();
704 arc4random_buf(rnd, sizeof(rnd));
705 RAND_seed(rnd, sizeof(rnd));
706
705 /* Drop privileges */ 707 /* Drop privileges */
706 do_setusercontext(authctxt->pw); 708 do_setusercontext(authctxt->pw);
707 709
@@ -801,7 +803,7 @@ drop_connection(int startups)
801 p *= startups - options.max_startups_begin; 803 p *= startups - options.max_startups_begin;
802 p /= options.max_startups - options.max_startups_begin; 804 p /= options.max_startups - options.max_startups_begin;
803 p += options.max_startups_rate; 805 p += options.max_startups_rate;
804 r = arc4random() % 100; 806 r = arc4random_uniform(100);
805 807
806 debug("drop_connection: p %d, r %d", p, r); 808 debug("drop_connection: p %d, r %d", p, r);
807 return (r < p) ? 1 : 0; 809 return (r < p) ? 1 : 0;
@@ -813,8 +815,9 @@ usage(void)
813 fprintf(stderr, "%s, %s\n", 815 fprintf(stderr, "%s, %s\n",
814 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); 816 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
815 fprintf(stderr, 817 fprintf(stderr,
816"usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" 818"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]\n"
817" [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n" 819" [-g login_grace_time] [-h host_key_file] [-k key_gen_time]\n"
820" [-o option] [-p port] [-u len]\n"
818 ); 821 );
819 exit(1); 822 exit(1);
820} 823}
@@ -987,8 +990,7 @@ server_listen(void)
987 ntop, sizeof(ntop), strport, sizeof(strport), 990 ntop, sizeof(ntop), strport, sizeof(strport),
988 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 991 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
989 error("getnameinfo failed: %.100s", 992 error("getnameinfo failed: %.100s",
990 (ret != EAI_SYSTEM) ? gai_strerror(ret) : 993 ssh_gai_strerror(ret));
991 strerror(errno));
992 continue; 994 continue;
993 } 995 }
994 /* Create socket for listening. */ 996 /* Create socket for listening. */
@@ -1011,6 +1013,16 @@ server_listen(void)
1011 &on, sizeof(on)) == -1) 1013 &on, sizeof(on)) == -1)
1012 error("setsockopt SO_REUSEADDR: %s", strerror(errno)); 1014 error("setsockopt SO_REUSEADDR: %s", strerror(errno));
1013 1015
1016#ifdef IPV6_V6ONLY
1017 /* Only communicate in IPv6 over AF_INET6 sockets. */
1018 if (ai->ai_family == AF_INET6) {
1019 if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
1020 &on, sizeof(on)) == -1)
1021 error("setsockopt IPV6_V6ONLY: %s",
1022 strerror(errno));
1023 }
1024#endif
1025
1014 debug("Bind to port %s on %s.", strport, ntop); 1026 debug("Bind to port %s on %s.", strport, ntop);
1015 1027
1016 /* Bind the socket to the desired port. */ 1028 /* Bind the socket to the desired port. */
@@ -1118,7 +1130,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1118 *newsock = accept(listen_socks[i], 1130 *newsock = accept(listen_socks[i],
1119 (struct sockaddr *)&from, &fromlen); 1131 (struct sockaddr *)&from, &fromlen);
1120 if (*newsock < 0) { 1132 if (*newsock < 0) {
1121 if (errno != EINTR && errno != EWOULDBLOCK) 1133 if (errno != EINTR && errno != EAGAIN &&
1134 errno != EWOULDBLOCK)
1122 error("accept: %.100s", strerror(errno)); 1135 error("accept: %.100s", strerror(errno));
1123 continue; 1136 continue;
1124 } 1137 }
@@ -1265,9 +1278,12 @@ main(int ac, char **av)
1265 int opt, i, on = 1; 1278 int opt, i, on = 1;
1266 int sock_in = -1, sock_out = -1, newsock = -1; 1279 int sock_in = -1, sock_out = -1, newsock = -1;
1267 const char *remote_ip; 1280 const char *remote_ip;
1281 char *test_user = NULL, *test_host = NULL, *test_addr = NULL;
1268 int remote_port; 1282 int remote_port;
1269 char *line; 1283 char *line, *p, *cp;
1270 int config_s[2] = { -1 , -1 }; 1284 int config_s[2] = { -1 , -1 };
1285 u_int64_t ibytes, obytes;
1286 mode_t new_umask;
1271 Key *key; 1287 Key *key;
1272 Authctxt *authctxt; 1288 Authctxt *authctxt;
1273 1289
@@ -1301,7 +1317,7 @@ main(int ac, char **av)
1301 initialize_server_options(&options); 1317 initialize_server_options(&options);
1302 1318
1303 /* Parse command-line arguments. */ 1319 /* Parse command-line arguments. */
1304 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { 1320 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) {
1305 switch (opt) { 1321 switch (opt) {
1306 case '4': 1322 case '4':
1307 options.address_family = AF_INET; 1323 options.address_family = AF_INET;
@@ -1384,6 +1400,25 @@ main(int ac, char **av)
1384 case 't': 1400 case 't':
1385 test_flag = 1; 1401 test_flag = 1;
1386 break; 1402 break;
1403 case 'T':
1404 test_flag = 2;
1405 break;
1406 case 'C':
1407 cp = optarg;
1408 while ((p = strsep(&cp, ",")) && *p != '\0') {
1409 if (strncmp(p, "addr=", 5) == 0)
1410 test_addr = xstrdup(p + 5);
1411 else if (strncmp(p, "host=", 5) == 0)
1412 test_host = xstrdup(p + 5);
1413 else if (strncmp(p, "user=", 5) == 0)
1414 test_user = xstrdup(p + 5);
1415 else {
1416 fprintf(stderr, "Invalid test "
1417 "mode specification %s\n", p);
1418 exit(1);
1419 }
1420 }
1421 break;
1387 case 'u': 1422 case 'u':
1388 utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); 1423 utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL);
1389 if (utmp_len > MAXHOSTNAMELEN) { 1424 if (utmp_len > MAXHOSTNAMELEN) {
@@ -1406,7 +1441,7 @@ main(int ac, char **av)
1406 } 1441 }
1407 if (rexeced_flag || inetd_flag) 1442 if (rexeced_flag || inetd_flag)
1408 rexec_flag = 0; 1443 rexec_flag = 0;
1409 if (rexec_flag && (av[0] == NULL || *av[0] != '/')) 1444 if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
1410 fatal("sshd re-exec requires execution with an absolute path"); 1445 fatal("sshd re-exec requires execution with an absolute path");
1411 if (rexeced_flag) 1446 if (rexeced_flag)
1412 closefrom(REEXEC_MIN_FREE_FD); 1447 closefrom(REEXEC_MIN_FREE_FD);
@@ -1445,6 +1480,21 @@ main(int ac, char **av)
1445 sensitive_data.have_ssh1_key = 0; 1480 sensitive_data.have_ssh1_key = 0;
1446 sensitive_data.have_ssh2_key = 0; 1481 sensitive_data.have_ssh2_key = 0;
1447 1482
1483 /*
1484 * If we're doing an extended config test, make sure we have all of
1485 * the parameters we need. If we're not doing an extended test,
1486 * do not silently ignore connection test params.
1487 */
1488 if (test_flag >= 2 &&
1489 (test_user != NULL || test_host != NULL || test_addr != NULL)
1490 && (test_user == NULL || test_host == NULL || test_addr == NULL))
1491 fatal("user, host and addr are all required when testing "
1492 "Match configs");
1493 if (test_flag < 2 && (test_user != NULL || test_host != NULL ||
1494 test_addr != NULL))
1495 fatal("Config test connection parameter (-C) provided without "
1496 "test mode (-T)");
1497
1448 /* Fetch our configuration */ 1498 /* Fetch our configuration */
1449 buffer_init(&cfg); 1499 buffer_init(&cfg);
1450 if (rexeced_flag) 1500 if (rexeced_flag)
@@ -1581,6 +1631,13 @@ main(int ac, char **av)
1581 "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); 1631 "world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
1582 } 1632 }
1583 1633
1634 if (test_flag > 1) {
1635 if (test_user != NULL && test_addr != NULL && test_host != NULL)
1636 parse_server_match_config(&options, test_user,
1637 test_host, test_addr);
1638 dump_config(&options);
1639 }
1640
1584 /* Configuration looks good, so exit if in test mode. */ 1641 /* Configuration looks good, so exit if in test mode. */
1585 if (test_flag) 1642 if (test_flag)
1586 exit(0); 1643 exit(0);
@@ -1605,6 +1662,10 @@ main(int ac, char **av)
1605 rexec_argv[rexec_argc + 1] = NULL; 1662 rexec_argv[rexec_argc + 1] = NULL;
1606 } 1663 }
1607 1664
1665 /* Ensure that umask disallows at least group and world write */
1666 new_umask = umask(0077) | 0022;
1667 (void) umask(new_umask);
1668
1608 /* Initialize the log (it is reinitialized below in case we forked). */ 1669 /* Initialize the log (it is reinitialized below in case we forked). */
1609 if (debug_flag && (!inetd_flag || rexeced_flag)) 1670 if (debug_flag && (!inetd_flag || rexeced_flag))
1610 log_stderr = 1; 1671 log_stderr = 1;
@@ -1652,10 +1713,6 @@ main(int ac, char **av)
1652 /* Get a connection, either from inetd or a listening TCP socket */ 1713 /* Get a connection, either from inetd or a listening TCP socket */
1653 if (inetd_flag) { 1714 if (inetd_flag) {
1654 server_accept_inetd(&sock_in, &sock_out); 1715 server_accept_inetd(&sock_in, &sock_out);
1655
1656 if ((options.protocol & SSH_PROTO_1) &&
1657 sensitive_data.server_key == NULL)
1658 generate_ephemeral_server_key();
1659 } else { 1716 } else {
1660 server_listen(); 1717 server_listen();
1661 1718
@@ -1767,7 +1824,7 @@ main(int ac, char **av)
1767 * Register our connection. This turns encryption off because we do 1824 * Register our connection. This turns encryption off because we do
1768 * not have a key. 1825 * not have a key.
1769 */ 1826 */
1770 packet_set_connection(sock_in, sock_out, -1); 1827 packet_set_connection(sock_in, sock_out);
1771 packet_set_server(); 1828 packet_set_server();
1772 1829
1773 /* Set SO_KEEPALIVE if requested. */ 1830 /* Set SO_KEEPALIVE if requested. */
@@ -1796,6 +1853,8 @@ main(int ac, char **av)
1796 audit_connection_from(remote_ip, remote_port); 1853 audit_connection_from(remote_ip, remote_port);
1797#endif 1854#endif
1798#ifdef LIBWRAP 1855#ifdef LIBWRAP
1856 allow_severity = options.log_facility|LOG_INFO;
1857 deny_severity = options.log_facility|LOG_WARNING;
1799 /* Check whether logins are denied from this host. */ 1858 /* Check whether logins are denied from this host. */
1800 if (packet_connection_is_on_socket()) { 1859 if (packet_connection_is_on_socket()) {
1801 struct request_info req; 1860 struct request_info req;
@@ -1883,6 +1942,10 @@ main(int ac, char **av)
1883 1942
1884 sshd_exchange_identification(sock_in, sock_out); 1943 sshd_exchange_identification(sock_in, sock_out);
1885 1944
1945 /* In inetd mode, generate ephemeral key only for proto 1 connections */
1946 if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
1947 generate_ephemeral_server_key();
1948
1886 packet_set_nonblocking(); 1949 packet_set_nonblocking();
1887 1950
1888 /* allocate authentication context */ 1951 /* allocate authentication context */
@@ -1935,6 +1998,20 @@ main(int ac, char **av)
1935 audit_event(SSH_AUTH_SUCCESS); 1998 audit_event(SSH_AUTH_SUCCESS);
1936#endif 1999#endif
1937 2000
2001#ifdef GSSAPI
2002 if (options.gss_authentication) {
2003 temporarily_use_uid(authctxt->pw);
2004 ssh_gssapi_storecreds();
2005 restore_uid();
2006 }
2007#endif
2008#ifdef USE_PAM
2009 if (options.use_pam) {
2010 do_pam_setcred(1);
2011 do_pam_session();
2012 }
2013#endif
2014
1938 /* 2015 /*
1939 * In privilege separation, we fork another child and prepare 2016 * In privilege separation, we fork another child and prepare
1940 * file descriptor passing. 2017 * file descriptor passing.
@@ -1946,11 +2023,18 @@ main(int ac, char **av)
1946 destroy_sensitive_data(); 2023 destroy_sensitive_data();
1947 } 2024 }
1948 2025
2026 packet_set_timeout(options.client_alive_interval,
2027 options.client_alive_count_max);
2028
1949 /* Start session. */ 2029 /* Start session. */
1950 do_authenticated(authctxt); 2030 do_authenticated(authctxt);
1951 2031
1952 /* The connection has been terminated. */ 2032 /* The connection has been terminated. */
1953 verbose("Closing connection to %.100s", remote_ip); 2033 packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
2034 packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
2035 verbose("Transferred: sent %llu, received %llu bytes", obytes, ibytes);
2036
2037 verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
1954 2038
1955#ifdef USE_PAM 2039#ifdef USE_PAM
1956 if (options.use_pam) 2040 if (options.use_pam)
@@ -2030,7 +2114,6 @@ do_ssh1_kex(void)
2030 u_char session_key[SSH_SESSION_KEY_LENGTH]; 2114 u_char session_key[SSH_SESSION_KEY_LENGTH];
2031 u_char cookie[8]; 2115 u_char cookie[8];
2032 u_int cipher_type, auth_mask, protocol_flags; 2116 u_int cipher_type, auth_mask, protocol_flags;
2033 u_int32_t rnd = 0;
2034 2117
2035 /* 2118 /*
2036 * Generate check bytes that the client must send back in the user 2119 * Generate check bytes that the client must send back in the user
@@ -2041,12 +2124,7 @@ do_ssh1_kex(void)
2041 * cookie. This only affects rhosts authentication, and this is one 2124 * cookie. This only affects rhosts authentication, and this is one
2042 * of the reasons why it is inherently insecure. 2125 * of the reasons why it is inherently insecure.
2043 */ 2126 */
2044 for (i = 0; i < 8; i++) { 2127 arc4random_buf(cookie, sizeof(cookie));
2045 if (i % 4 == 0)
2046 rnd = arc4random();
2047 cookie[i] = rnd & 0xff;
2048 rnd >>= 8;
2049 }
2050 2128
2051 /* 2129 /*
2052 * Send our public key. We include in the packet 64 bits of random 2130 * Send our public key. We include in the packet 64 bits of random