summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2013-09-14 23:42:11 +0100
committerColin Watson <cjwatson@debian.org>2013-09-14 23:42:11 +0100
commit327155e6824b3ee13837bdde04e4eb47e147ff46 (patch)
tree8f8743122403c7a2e6ed919156711fb1520c657f /sshd.c
parent0334ce32304e9ba2a10ee5ca49ca6e8ff3ba6cf4 (diff)
parent74e339b8f8936bc0d985e053a076d0c9b5e9ea51 (diff)
* New upstream release (http://www.openssh.com/txt/release-6.3).
- sftp(1): add support for resuming partial downloads using the "reget" command and on the sftp commandline or on the "get" commandline using the "-a" (append) option (closes: #158590). - ssh(1): add an "IgnoreUnknown" configuration option to selectively suppress errors arising from unknown configuration directives (closes: #436052). - sftp(1): update progressmeter when data is acknowledged, not when it's sent (partially addresses #708372). - ssh(1): do not fatally exit when attempting to cleanup multiplexing- created channels that are incompletely opened (closes: #651357).
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c129
1 files changed, 106 insertions, 23 deletions
diff --git a/sshd.c b/sshd.c
index 0c260a50d..72e9eaf47 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.397 2013/02/11 21:21:58 dtucker Exp $ */ 1/* $OpenBSD: sshd.c,v 1.404 2013/07/19 07:37:48 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
@@ -106,6 +106,7 @@
106#include "canohost.h" 106#include "canohost.h"
107#include "hostfile.h" 107#include "hostfile.h"
108#include "auth.h" 108#include "auth.h"
109#include "authfd.h"
109#include "misc.h" 110#include "misc.h"
110#include "msg.h" 111#include "msg.h"
111#include "dispatch.h" 112#include "dispatch.h"
@@ -198,6 +199,10 @@ char *server_version_string = NULL;
198/* for rekeying XXX fixme */ 199/* for rekeying XXX fixme */
199Kex *xxx_kex; 200Kex *xxx_kex;
200 201
202/* Daemon's agent connection */
203AuthenticationConnection *auth_conn = NULL;
204int have_agent = 0;
205
201/* 206/*
202 * Any really sensitive data in the application is contained in this 207 * Any really sensitive data in the application is contained in this
203 * structure. The idea is that this structure could be locked into memory so 208 * structure. The idea is that this structure could be locked into memory so
@@ -210,6 +215,7 @@ struct {
210 Key *server_key; /* ephemeral server key */ 215 Key *server_key; /* ephemeral server key */
211 Key *ssh1_host_key; /* ssh1 host key */ 216 Key *ssh1_host_key; /* ssh1 host key */
212 Key **host_keys; /* all private host keys */ 217 Key **host_keys; /* all private host keys */
218 Key **host_pubkeys; /* all public host keys */
213 Key **host_certificates; /* all public host certificates */ 219 Key **host_certificates; /* all public host certificates */
214 int have_ssh1_key; 220 int have_ssh1_key;
215 int have_ssh2_key; 221 int have_ssh2_key;
@@ -658,6 +664,8 @@ privsep_preauth(Authctxt *authctxt)
658 debug2("Network child is on pid %ld", (long)pid); 664 debug2("Network child is on pid %ld", (long)pid);
659 665
660 pmonitor->m_pid = pid; 666 pmonitor->m_pid = pid;
667 if (have_agent)
668 auth_conn = ssh_get_authentication_connection();
661 if (box != NULL) 669 if (box != NULL)
662 ssh_sandbox_parent_preauth(box, pid); 670 ssh_sandbox_parent_preauth(box, pid);
663 monitor_child_preauth(authctxt, pmonitor); 671 monitor_child_preauth(authctxt, pmonitor);
@@ -772,6 +780,8 @@ list_hostkey_types(void)
772 for (i = 0; i < options.num_host_key_files; i++) { 780 for (i = 0; i < options.num_host_key_files; i++) {
773 key = sensitive_data.host_keys[i]; 781 key = sensitive_data.host_keys[i];
774 if (key == NULL) 782 if (key == NULL)
783 key = sensitive_data.host_pubkeys[i];
784 if (key == NULL)
775 continue; 785 continue;
776 switch (key->type) { 786 switch (key->type) {
777 case KEY_RSA: 787 case KEY_RSA:
@@ -824,6 +834,8 @@ get_hostkey_by_type(int type, int need_private)
824 break; 834 break;
825 default: 835 default:
826 key = sensitive_data.host_keys[i]; 836 key = sensitive_data.host_keys[i];
837 if (key == NULL && !need_private)
838 key = sensitive_data.host_pubkeys[i];
827 break; 839 break;
828 } 840 }
829 if (key != NULL && key->type == type) 841 if (key != NULL && key->type == type)
@@ -853,6 +865,14 @@ get_hostkey_by_index(int ind)
853 return (sensitive_data.host_keys[ind]); 865 return (sensitive_data.host_keys[ind]);
854} 866}
855 867
868Key *
869get_hostkey_public_by_index(int ind)
870{
871 if (ind < 0 || ind >= options.num_host_key_files)
872 return (NULL);
873 return (sensitive_data.host_pubkeys[ind]);
874}
875
856int 876int
857get_hostkey_index(Key *key) 877get_hostkey_index(Key *key)
858{ 878{
@@ -865,6 +885,8 @@ get_hostkey_index(Key *key)
865 } else { 885 } else {
866 if (key == sensitive_data.host_keys[i]) 886 if (key == sensitive_data.host_keys[i])
867 return (i); 887 return (i);
888 if (key == sensitive_data.host_pubkeys[i])
889 return (i);
868 } 890 }
869 } 891 }
870 return (-1); 892 return (-1);
@@ -905,8 +927,9 @@ usage(void)
905 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); 927 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
906 fprintf(stderr, 928 fprintf(stderr,
907"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" 929"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n"
908" [-f config_file] [-g login_grace_time] [-h host_key_file]\n" 930" [-E log_file] [-f config_file] [-g login_grace_time]\n"
909" [-k key_gen_time] [-o option] [-p port] [-u len]\n" 931" [-h host_key_file] [-k key_gen_time] [-o option] [-p port]\n"
932" [-u len]\n"
910 ); 933 );
911 exit(1); 934 exit(1);
912} 935}
@@ -977,7 +1000,7 @@ recv_rexec_state(int fd, Buffer *conf)
977 cp = buffer_get_string(&m, &len); 1000 cp = buffer_get_string(&m, &len);
978 if (conf != NULL) 1001 if (conf != NULL)
979 buffer_append(conf, cp, len + 1); 1002 buffer_append(conf, cp, len + 1);
980 xfree(cp); 1003 free(cp);
981 1004
982 if (buffer_get_int(&m)) { 1005 if (buffer_get_int(&m)) {
983 if (sensitive_data.server_key != NULL) 1006 if (sensitive_data.server_key != NULL)
@@ -1028,7 +1051,9 @@ server_accept_inetd(int *sock_in, int *sock_out)
1028 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 1051 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
1029 dup2(fd, STDIN_FILENO); 1052 dup2(fd, STDIN_FILENO);
1030 dup2(fd, STDOUT_FILENO); 1053 dup2(fd, STDOUT_FILENO);
1031 if (fd > STDOUT_FILENO) 1054 if (!log_stderr)
1055 dup2(fd, STDERR_FILENO);
1056 if (fd > (log_stderr ? STDERR_FILENO : STDOUT_FILENO))
1032 close(fd); 1057 close(fd);
1033 } 1058 }
1034 debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out); 1059 debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out);
@@ -1139,7 +1164,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1139 if (received_sighup) 1164 if (received_sighup)
1140 sighup_restart(); 1165 sighup_restart();
1141 if (fdset != NULL) 1166 if (fdset != NULL)
1142 xfree(fdset); 1167 free(fdset);
1143 fdset = (fd_set *)xcalloc(howmany(maxfd + 1, NFDBITS), 1168 fdset = (fd_set *)xcalloc(howmany(maxfd + 1, NFDBITS),
1144 sizeof(fd_mask)); 1169 sizeof(fd_mask));
1145 1170
@@ -1188,8 +1213,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1188 *newsock = accept(listen_socks[i], 1213 *newsock = accept(listen_socks[i],
1189 (struct sockaddr *)&from, &fromlen); 1214 (struct sockaddr *)&from, &fromlen);
1190 if (*newsock < 0) { 1215 if (*newsock < 0) {
1191 if (errno != EINTR && errno != EAGAIN && 1216 if (errno != EINTR && errno != EWOULDBLOCK &&
1192 errno != EWOULDBLOCK) 1217 errno != ECONNABORTED && errno != EAGAIN)
1193 error("accept: %.100s", 1218 error("accept: %.100s",
1194 strerror(errno)); 1219 strerror(errno));
1195 if (errno == EMFILE || errno == ENFILE) 1220 if (errno == EMFILE || errno == ENFILE)
@@ -1340,12 +1365,14 @@ main(int ac, char **av)
1340 int sock_in = -1, sock_out = -1, newsock = -1; 1365 int sock_in = -1, sock_out = -1, newsock = -1;
1341 const char *remote_ip; 1366 const char *remote_ip;
1342 int remote_port; 1367 int remote_port;
1343 char *line; 1368 char *line, *logfile = NULL;
1344 int config_s[2] = { -1 , -1 }; 1369 int config_s[2] = { -1 , -1 };
1345 u_int n; 1370 u_int n;
1346 u_int64_t ibytes, obytes; 1371 u_int64_t ibytes, obytes;
1347 mode_t new_umask; 1372 mode_t new_umask;
1348 Key *key; 1373 Key *key;
1374 Key *pubkey;
1375 int keytype;
1349 Authctxt *authctxt; 1376 Authctxt *authctxt;
1350 struct connection_info *connection_info = get_connection_info(0, 0); 1377 struct connection_info *connection_info = get_connection_info(0, 0);
1351 1378
@@ -1378,7 +1405,7 @@ main(int ac, char **av)
1378 initialize_server_options(&options); 1405 initialize_server_options(&options);
1379 1406
1380 /* Parse command-line arguments. */ 1407 /* Parse command-line arguments. */
1381 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) { 1408 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeE:iqrtQRT46")) != -1) {
1382 switch (opt) { 1409 switch (opt) {
1383 case '4': 1410 case '4':
1384 options.address_family = AF_INET; 1411 options.address_family = AF_INET;
@@ -1407,6 +1434,9 @@ main(int ac, char **av)
1407 case 'D': 1434 case 'D':
1408 no_daemon_flag = 1; 1435 no_daemon_flag = 1;
1409 break; 1436 break;
1437 case 'E':
1438 logfile = xstrdup(optarg);
1439 /* FALLTHROUGH */
1410 case 'e': 1440 case 'e':
1411 log_stderr = 1; 1441 log_stderr = 1;
1412 break; 1442 break;
@@ -1485,7 +1515,7 @@ main(int ac, char **av)
1485 if (process_server_config_line(&options, line, 1515 if (process_server_config_line(&options, line,
1486 "command-line", 0, NULL, NULL) != 0) 1516 "command-line", 0, NULL, NULL) != 0)
1487 exit(1); 1517 exit(1);
1488 xfree(line); 1518 free(line);
1489 break; 1519 break;
1490 case '?': 1520 case '?':
1491 default: 1521 default:
@@ -1504,6 +1534,11 @@ main(int ac, char **av)
1504 1534
1505 OpenSSL_add_all_algorithms(); 1535 OpenSSL_add_all_algorithms();
1506 1536
1537 /* If requested, redirect the logs to the specified logfile. */
1538 if (logfile != NULL) {
1539 log_redirect_stderr_to(logfile);
1540 free(logfile);
1541 }
1507 /* 1542 /*
1508 * Force logging to stderr until we have loaded the private host 1543 * Force logging to stderr until we have loaded the private host
1509 * key (unless started from inetd) 1544 * key (unless started from inetd)
@@ -1612,32 +1647,55 @@ main(int ac, char **av)
1612 } else { 1647 } else {
1613 memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd)); 1648 memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd));
1614 privsep_pw = pwcopy(privsep_pw); 1649 privsep_pw = pwcopy(privsep_pw);
1615 xfree(privsep_pw->pw_passwd); 1650 free(privsep_pw->pw_passwd);
1616 privsep_pw->pw_passwd = xstrdup("*"); 1651 privsep_pw->pw_passwd = xstrdup("*");
1617 } 1652 }
1618 endpwent(); 1653 endpwent();
1619 1654
1620 /* load private host keys */ 1655 /* load host keys */
1621 sensitive_data.host_keys = xcalloc(options.num_host_key_files, 1656 sensitive_data.host_keys = xcalloc(options.num_host_key_files,
1622 sizeof(Key *)); 1657 sizeof(Key *));
1623 for (i = 0; i < options.num_host_key_files; i++) 1658 sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files,
1659 sizeof(Key *));
1660 for (i = 0; i < options.num_host_key_files; i++) {
1624 sensitive_data.host_keys[i] = NULL; 1661 sensitive_data.host_keys[i] = NULL;
1662 sensitive_data.host_pubkeys[i] = NULL;
1663 }
1664
1665 if (options.host_key_agent) {
1666 if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
1667 setenv(SSH_AUTHSOCKET_ENV_NAME,
1668 options.host_key_agent, 1);
1669 have_agent = ssh_agent_present();
1670 }
1625 1671
1626 for (i = 0; i < options.num_host_key_files; i++) { 1672 for (i = 0; i < options.num_host_key_files; i++) {
1627 key = key_load_private(options.host_key_files[i], "", NULL); 1673 key = key_load_private(options.host_key_files[i], "", NULL);
1674 pubkey = key_load_public(options.host_key_files[i], NULL);
1628 sensitive_data.host_keys[i] = key; 1675 sensitive_data.host_keys[i] = key;
1629 if (key == NULL) { 1676 sensitive_data.host_pubkeys[i] = pubkey;
1677
1678 if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 &&
1679 have_agent) {
1680 debug("will rely on agent for hostkey %s",
1681 options.host_key_files[i]);
1682 keytype = pubkey->type;
1683 } else if (key != NULL) {
1684 keytype = key->type;
1685 } else {
1630 error("Could not load host key: %s", 1686 error("Could not load host key: %s",
1631 options.host_key_files[i]); 1687 options.host_key_files[i]);
1632 sensitive_data.host_keys[i] = NULL; 1688 sensitive_data.host_keys[i] = NULL;
1689 sensitive_data.host_pubkeys[i] = NULL;
1633 continue; 1690 continue;
1634 } 1691 }
1635 if (auth_key_is_revoked(key, 1)) { 1692 if (auth_key_is_revoked(key != NULL ? key : pubkey, 1)) {
1636 key_free(key);
1637 sensitive_data.host_keys[i] = NULL; 1693 sensitive_data.host_keys[i] = NULL;
1694 sensitive_data.host_pubkeys[i] = NULL;
1638 continue; 1695 continue;
1639 } 1696 }
1640 switch (key->type) { 1697
1698 switch (keytype) {
1641 case KEY_RSA1: 1699 case KEY_RSA1:
1642 sensitive_data.ssh1_host_key = key; 1700 sensitive_data.ssh1_host_key = key;
1643 sensitive_data.have_ssh1_key = 1; 1701 sensitive_data.have_ssh1_key = 1;
@@ -1648,8 +1706,8 @@ main(int ac, char **av)
1648 sensitive_data.have_ssh2_key = 1; 1706 sensitive_data.have_ssh2_key = 1;
1649 break; 1707 break;
1650 } 1708 }
1651 debug("private host key: #%d type %d %s", i, key->type, 1709 debug("private host key: #%d type %d %s", i, keytype,
1652 key_type(key)); 1710 key_type(key ? key : pubkey));
1653 } 1711 }
1654 if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { 1712 if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
1655 logit("Disabling protocol version 1. Could not load host key"); 1713 logit("Disabling protocol version 1. Could not load host key");
@@ -1819,7 +1877,8 @@ main(int ac, char **av)
1819 1877
1820 /* Chdir to the root directory so that the current disk can be 1878 /* Chdir to the root directory so that the current disk can be
1821 unmounted if desired. */ 1879 unmounted if desired. */
1822 chdir("/"); 1880 if (chdir("/") == -1)
1881 error("chdir(\"/\"): %s", strerror(errno));
1823 1882
1824 /* ignore SIGPIPE */ 1883 /* ignore SIGPIPE */
1825 signal(SIGPIPE, SIG_IGN); 1884 signal(SIGPIPE, SIG_IGN);
@@ -2079,9 +2138,11 @@ main(int ac, char **av)
2079 buffer_init(&loginmsg); 2138 buffer_init(&loginmsg);
2080 auth_debug_reset(); 2139 auth_debug_reset();
2081 2140
2082 if (use_privsep) 2141 if (use_privsep) {
2083 if (privsep_preauth(authctxt) == 1) 2142 if (privsep_preauth(authctxt) == 1)
2084 goto authenticated; 2143 goto authenticated;
2144 } else if (compat20 && have_agent)
2145 auth_conn = ssh_get_authentication_connection();
2085 2146
2086 /* perform the key exchange */ 2147 /* perform the key exchange */
2087 /* authenticate user and start session */ 2148 /* authenticate user and start session */
@@ -2368,7 +2429,7 @@ do_ssh1_kex(void)
2368 MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); 2429 MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
2369 MD5_Final(session_key + 16, &md); 2430 MD5_Final(session_key + 16, &md);
2370 memset(buf, 0, bytes); 2431 memset(buf, 0, bytes);
2371 xfree(buf); 2432 free(buf);
2372 for (i = 0; i < 16; i++) 2433 for (i = 0; i < 16; i++)
2373 session_id[i] = session_key[i] ^ session_key[i + 16]; 2434 session_id[i] = session_key[i] ^ session_key[i + 16];
2374 } 2435 }
@@ -2395,6 +2456,23 @@ do_ssh1_kex(void)
2395 packet_write_wait(); 2456 packet_write_wait();
2396} 2457}
2397 2458
2459void
2460sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen,
2461 u_char *data, u_int dlen)
2462{
2463 if (privkey) {
2464 if (PRIVSEP(key_sign(privkey, signature, slen, data, dlen) < 0))
2465 fatal("%s: key_sign failed", __func__);
2466 } else if (use_privsep) {
2467 if (mm_key_sign(pubkey, signature, slen, data, dlen) < 0)
2468 fatal("%s: pubkey_sign failed", __func__);
2469 } else {
2470 if (ssh_agent_sign(auth_conn, pubkey, signature, slen, data,
2471 dlen))
2472 fatal("%s: ssh_agent_sign failed", __func__);
2473 }
2474}
2475
2398/* 2476/*
2399 * SSH2 key exchange: diffie-hellman-group1-sha1 2477 * SSH2 key exchange: diffie-hellman-group1-sha1
2400 */ 2478 */
@@ -2426,6 +2504,10 @@ do_ssh2_kex(void)
2426 if (options.kex_algorithms != NULL) 2504 if (options.kex_algorithms != NULL)
2427 myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; 2505 myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
2428 2506
2507 if (options.rekey_limit || options.rekey_interval)
2508 packet_set_rekey_limits((u_int32_t)options.rekey_limit,
2509 (time_t)options.rekey_interval);
2510
2429 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); 2511 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
2430 2512
2431#ifdef GSSAPI 2513#ifdef GSSAPI
@@ -2490,6 +2572,7 @@ do_ssh2_kex(void)
2490 kex->load_host_public_key=&get_hostkey_public_by_type; 2572 kex->load_host_public_key=&get_hostkey_public_by_type;
2491 kex->load_host_private_key=&get_hostkey_private_by_type; 2573 kex->load_host_private_key=&get_hostkey_private_by_type;
2492 kex->host_key_index=&get_hostkey_index; 2574 kex->host_key_index=&get_hostkey_index;
2575 kex->sign = sshd_hostkey_sign;
2493 2576
2494 xxx_kex = kex; 2577 xxx_kex = kex;
2495 2578