diff options
author | Colin Watson <cjwatson@debian.org> | 2017-10-04 11:23:58 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2017-10-05 23:58:12 +0100 |
commit | 0556ea972b15607b7e13ff31bc05840881c91dd3 (patch) | |
tree | d6b8d48062d0278b5ae0eeff42d0e9afa9f26860 /sshd.c | |
parent | db2122d97eb1ecdd8d99b7bf79b0dd2b5addfd92 (diff) | |
parent | 801a62eedaaf47b20dbf4b426dc3e084bf0c8d49 (diff) |
New upstream release (7.6p1)
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 87 |
1 files changed, 43 insertions, 44 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.485 2017/03/15 03:52:30 deraadt Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.492 2017/09/12 06:32:07 djm 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 |
@@ -92,7 +92,6 @@ | |||
92 | #include "xmalloc.h" | 92 | #include "xmalloc.h" |
93 | #include "ssh.h" | 93 | #include "ssh.h" |
94 | #include "ssh2.h" | 94 | #include "ssh2.h" |
95 | #include "rsa.h" | ||
96 | #include "sshpty.h" | 95 | #include "sshpty.h" |
97 | #include "packet.h" | 96 | #include "packet.h" |
98 | #include "log.h" | 97 | #include "log.h" |
@@ -210,10 +209,10 @@ int have_agent = 0; | |||
210 | * not very useful. Currently, memory locking is not implemented. | 209 | * not very useful. Currently, memory locking is not implemented. |
211 | */ | 210 | */ |
212 | struct { | 211 | struct { |
213 | Key **host_keys; /* all private host keys */ | 212 | struct sshkey **host_keys; /* all private host keys */ |
214 | Key **host_pubkeys; /* all public host keys */ | 213 | struct sshkey **host_pubkeys; /* all public host keys */ |
215 | Key **host_certificates; /* all public host certificates */ | 214 | struct sshkey **host_certificates; /* all public host certificates */ |
216 | int have_ssh2_key; | 215 | int have_ssh2_key; |
217 | } sensitive_data; | 216 | } sensitive_data; |
218 | 217 | ||
219 | /* This is set to true when a signal is received. */ | 218 | /* This is set to true when a signal is received. */ |
@@ -238,6 +237,7 @@ int startup_pipe; /* in child */ | |||
238 | int use_privsep = -1; | 237 | int use_privsep = -1; |
239 | struct monitor *pmonitor = NULL; | 238 | struct monitor *pmonitor = NULL; |
240 | int privsep_is_preauth = 1; | 239 | int privsep_is_preauth = 1; |
240 | static int privsep_chroot = 1; | ||
241 | 241 | ||
242 | /* global authentication context */ | 242 | /* global authentication context */ |
243 | Authctxt *the_authctxt = NULL; | 243 | Authctxt *the_authctxt = NULL; |
@@ -465,10 +465,8 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) | |||
465 | chop(server_version_string); | 465 | chop(server_version_string); |
466 | debug("Local version string %.200s", server_version_string); | 466 | debug("Local version string %.200s", server_version_string); |
467 | 467 | ||
468 | if (remote_major == 2 || | 468 | if (remote_major != 2 || |
469 | (remote_major == 1 && remote_minor == 99)) { | 469 | (remote_major == 1 && remote_minor != 99)) { |
470 | enable_compat20(); | ||
471 | } else { | ||
472 | s = "Protocol major versions differ.\n"; | 470 | s = "Protocol major versions differ.\n"; |
473 | (void) atomicio(vwrite, sock_out, s, strlen(s)); | 471 | (void) atomicio(vwrite, sock_out, s, strlen(s)); |
474 | close(sock_in); | 472 | close(sock_in); |
@@ -503,7 +501,7 @@ destroy_sensitive_data(void) | |||
503 | void | 501 | void |
504 | demote_sensitive_data(void) | 502 | demote_sensitive_data(void) |
505 | { | 503 | { |
506 | Key *tmp; | 504 | struct sshkey *tmp; |
507 | int i; | 505 | int i; |
508 | 506 | ||
509 | for (i = 0; i < options.num_host_key_files; i++) { | 507 | for (i = 0; i < options.num_host_key_files; i++) { |
@@ -557,7 +555,7 @@ privsep_preauth_child(void) | |||
557 | demote_sensitive_data(); | 555 | demote_sensitive_data(); |
558 | 556 | ||
559 | /* Demote the child */ | 557 | /* Demote the child */ |
560 | if (getuid() == 0 || geteuid() == 0) { | 558 | if (privsep_chroot) { |
561 | /* Change our root directory */ | 559 | /* Change our root directory */ |
562 | if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) | 560 | if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) |
563 | fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, | 561 | fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, |
@@ -666,6 +664,7 @@ privsep_postauth(Authctxt *authctxt) | |||
666 | else if (pmonitor->m_pid != 0) { | 664 | else if (pmonitor->m_pid != 0) { |
667 | verbose("User child is on pid %ld", (long)pmonitor->m_pid); | 665 | verbose("User child is on pid %ld", (long)pmonitor->m_pid); |
668 | buffer_clear(&loginmsg); | 666 | buffer_clear(&loginmsg); |
667 | monitor_clear_keystate(pmonitor); | ||
669 | monitor_child_postauth(pmonitor); | 668 | monitor_child_postauth(pmonitor); |
670 | 669 | ||
671 | /* NEVERREACHED */ | 670 | /* NEVERREACHED */ |
@@ -703,7 +702,7 @@ list_hostkey_types(void) | |||
703 | const char *p; | 702 | const char *p; |
704 | char *ret; | 703 | char *ret; |
705 | int i; | 704 | int i; |
706 | Key *key; | 705 | struct sshkey *key; |
707 | 706 | ||
708 | buffer_init(&b); | 707 | buffer_init(&b); |
709 | for (i = 0; i < options.num_host_key_files; i++) { | 708 | for (i = 0; i < options.num_host_key_files; i++) { |
@@ -759,11 +758,11 @@ list_hostkey_types(void) | |||
759 | return ret; | 758 | return ret; |
760 | } | 759 | } |
761 | 760 | ||
762 | static Key * | 761 | static struct sshkey * |
763 | get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) | 762 | get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) |
764 | { | 763 | { |
765 | int i; | 764 | int i; |
766 | Key *key; | 765 | struct sshkey *key; |
767 | 766 | ||
768 | for (i = 0; i < options.num_host_key_files; i++) { | 767 | for (i = 0; i < options.num_host_key_files; i++) { |
769 | switch (type) { | 768 | switch (type) { |
@@ -787,19 +786,19 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) | |||
787 | return NULL; | 786 | return NULL; |
788 | } | 787 | } |
789 | 788 | ||
790 | Key * | 789 | struct sshkey * |
791 | get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) | 790 | get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) |
792 | { | 791 | { |
793 | return get_hostkey_by_type(type, nid, 0, ssh); | 792 | return get_hostkey_by_type(type, nid, 0, ssh); |
794 | } | 793 | } |
795 | 794 | ||
796 | Key * | 795 | struct sshkey * |
797 | get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) | 796 | get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) |
798 | { | 797 | { |
799 | return get_hostkey_by_type(type, nid, 1, ssh); | 798 | return get_hostkey_by_type(type, nid, 1, ssh); |
800 | } | 799 | } |
801 | 800 | ||
802 | Key * | 801 | struct sshkey * |
803 | get_hostkey_by_index(int ind) | 802 | get_hostkey_by_index(int ind) |
804 | { | 803 | { |
805 | if (ind < 0 || ind >= options.num_host_key_files) | 804 | if (ind < 0 || ind >= options.num_host_key_files) |
@@ -807,7 +806,7 @@ get_hostkey_by_index(int ind) | |||
807 | return (sensitive_data.host_keys[ind]); | 806 | return (sensitive_data.host_keys[ind]); |
808 | } | 807 | } |
809 | 808 | ||
810 | Key * | 809 | struct sshkey * |
811 | get_hostkey_public_by_index(int ind, struct ssh *ssh) | 810 | get_hostkey_public_by_index(int ind, struct ssh *ssh) |
812 | { | 811 | { |
813 | if (ind < 0 || ind >= options.num_host_key_files) | 812 | if (ind < 0 || ind >= options.num_host_key_files) |
@@ -816,7 +815,7 @@ get_hostkey_public_by_index(int ind, struct ssh *ssh) | |||
816 | } | 815 | } |
817 | 816 | ||
818 | int | 817 | int |
819 | get_hostkey_index(Key *key, int compare, struct ssh *ssh) | 818 | get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) |
820 | { | 819 | { |
821 | int i; | 820 | int i; |
822 | 821 | ||
@@ -1383,8 +1382,8 @@ main(int ac, char **av) | |||
1383 | u_int n; | 1382 | u_int n; |
1384 | u_int64_t ibytes, obytes; | 1383 | u_int64_t ibytes, obytes; |
1385 | mode_t new_umask; | 1384 | mode_t new_umask; |
1386 | Key *key; | 1385 | struct sshkey *key; |
1387 | Key *pubkey; | 1386 | struct sshkey *pubkey; |
1388 | int keytype; | 1387 | int keytype; |
1389 | Authctxt *authctxt; | 1388 | Authctxt *authctxt; |
1390 | struct connection_info *connection_info = get_connection_info(0, 0); | 1389 | struct connection_info *connection_info = get_connection_info(0, 0); |
@@ -1638,9 +1637,6 @@ main(int ac, char **av) | |||
1638 | "enabled authentication methods"); | 1637 | "enabled authentication methods"); |
1639 | } | 1638 | } |
1640 | 1639 | ||
1641 | /* set default channel AF */ | ||
1642 | channel_set_af(options.address_family); | ||
1643 | |||
1644 | /* Check that there are no remaining arguments. */ | 1640 | /* Check that there are no remaining arguments. */ |
1645 | if (optind < ac) { | 1641 | if (optind < ac) { |
1646 | fprintf(stderr, "Extra argument %s.\n", av[optind]); | 1642 | fprintf(stderr, "Extra argument %s.\n", av[optind]); |
@@ -1656,8 +1652,9 @@ main(int ac, char **av) | |||
1656 | ); | 1652 | ); |
1657 | 1653 | ||
1658 | /* Store privilege separation user for later use if required. */ | 1654 | /* Store privilege separation user for later use if required. */ |
1655 | privsep_chroot = use_privsep && (getuid() == 0 || geteuid() == 0); | ||
1659 | if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { | 1656 | if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { |
1660 | if (use_privsep || options.kerberos_authentication) | 1657 | if (privsep_chroot || options.kerberos_authentication) |
1661 | fatal("Privilege separation user %s does not exist", | 1658 | fatal("Privilege separation user %s does not exist", |
1662 | SSH_PRIVSEP_USER); | 1659 | SSH_PRIVSEP_USER); |
1663 | } else { | 1660 | } else { |
@@ -1671,9 +1668,9 @@ main(int ac, char **av) | |||
1671 | 1668 | ||
1672 | /* load host keys */ | 1669 | /* load host keys */ |
1673 | sensitive_data.host_keys = xcalloc(options.num_host_key_files, | 1670 | sensitive_data.host_keys = xcalloc(options.num_host_key_files, |
1674 | sizeof(Key *)); | 1671 | sizeof(struct sshkey *)); |
1675 | sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, | 1672 | sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, |
1676 | sizeof(Key *)); | 1673 | sizeof(struct sshkey *)); |
1677 | 1674 | ||
1678 | if (options.host_key_agent) { | 1675 | if (options.host_key_agent) { |
1679 | if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) | 1676 | if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) |
@@ -1692,14 +1689,6 @@ main(int ac, char **av) | |||
1692 | key = key_load_private(options.host_key_files[i], "", NULL); | 1689 | key = key_load_private(options.host_key_files[i], "", NULL); |
1693 | pubkey = key_load_public(options.host_key_files[i], NULL); | 1690 | pubkey = key_load_public(options.host_key_files[i], NULL); |
1694 | 1691 | ||
1695 | if ((pubkey != NULL && pubkey->type == KEY_RSA1) || | ||
1696 | (key != NULL && key->type == KEY_RSA1)) { | ||
1697 | verbose("Ignoring RSA1 key %s", | ||
1698 | options.host_key_files[i]); | ||
1699 | key_free(key); | ||
1700 | key_free(pubkey); | ||
1701 | continue; | ||
1702 | } | ||
1703 | if (pubkey == NULL && key != NULL) | 1692 | if (pubkey == NULL && key != NULL) |
1704 | pubkey = key_demote(key); | 1693 | pubkey = key_demote(key); |
1705 | sensitive_data.host_keys[i] = key; | 1694 | sensitive_data.host_keys[i] = key; |
@@ -1748,7 +1737,7 @@ main(int ac, char **av) | |||
1748 | * indices to the public keys that they relate to. | 1737 | * indices to the public keys that they relate to. |
1749 | */ | 1738 | */ |
1750 | sensitive_data.host_certificates = xcalloc(options.num_host_key_files, | 1739 | sensitive_data.host_certificates = xcalloc(options.num_host_key_files, |
1751 | sizeof(Key *)); | 1740 | sizeof(struct sshkey *)); |
1752 | for (i = 0; i < options.num_host_key_files; i++) | 1741 | for (i = 0; i < options.num_host_key_files; i++) |
1753 | sensitive_data.host_certificates[i] = NULL; | 1742 | sensitive_data.host_certificates[i] = NULL; |
1754 | 1743 | ||
@@ -1786,7 +1775,7 @@ main(int ac, char **av) | |||
1786 | key_type(key)); | 1775 | key_type(key)); |
1787 | } | 1776 | } |
1788 | 1777 | ||
1789 | if (use_privsep) { | 1778 | if (privsep_chroot) { |
1790 | struct stat st; | 1779 | struct stat st; |
1791 | 1780 | ||
1792 | if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || | 1781 | if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || |
@@ -1987,8 +1976,14 @@ main(int ac, char **av) | |||
1987 | packet_set_connection(sock_in, sock_out); | 1976 | packet_set_connection(sock_in, sock_out); |
1988 | packet_set_server(); | 1977 | packet_set_server(); |
1989 | ssh = active_state; /* XXX */ | 1978 | ssh = active_state; /* XXX */ |
1979 | |||
1990 | check_ip_options(ssh); | 1980 | check_ip_options(ssh); |
1991 | 1981 | ||
1982 | /* Prepare the channels layer */ | ||
1983 | channel_init_channels(ssh); | ||
1984 | channel_set_af(ssh, options.address_family); | ||
1985 | process_permitopen(ssh, &options); | ||
1986 | |||
1992 | /* Set SO_KEEPALIVE if requested. */ | 1987 | /* Set SO_KEEPALIVE if requested. */ |
1993 | if (options.tcp_keep_alive && packet_connection_is_on_socket() && | 1988 | if (options.tcp_keep_alive && packet_connection_is_on_socket() && |
1994 | setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) | 1989 | setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) |
@@ -2136,6 +2131,7 @@ main(int ac, char **av) | |||
2136 | */ | 2131 | */ |
2137 | if (use_privsep) { | 2132 | if (use_privsep) { |
2138 | mm_send_keystate(pmonitor); | 2133 | mm_send_keystate(pmonitor); |
2134 | packet_clear_keys(); | ||
2139 | exit(0); | 2135 | exit(0); |
2140 | } | 2136 | } |
2141 | 2137 | ||
@@ -2183,10 +2179,10 @@ main(int ac, char **av) | |||
2183 | options.client_alive_count_max); | 2179 | options.client_alive_count_max); |
2184 | 2180 | ||
2185 | /* Try to send all our hostkeys to the client */ | 2181 | /* Try to send all our hostkeys to the client */ |
2186 | notify_hostkeys(active_state); | 2182 | notify_hostkeys(ssh); |
2187 | 2183 | ||
2188 | /* Start session. */ | 2184 | /* Start session. */ |
2189 | do_authenticated(authctxt); | 2185 | do_authenticated(ssh, authctxt); |
2190 | 2186 | ||
2191 | /* The connection has been terminated. */ | 2187 | /* The connection has been terminated. */ |
2192 | packet_get_bytes(&ibytes, &obytes); | 2188 | packet_get_bytes(&ibytes, &obytes); |
@@ -2213,8 +2209,9 @@ main(int ac, char **av) | |||
2213 | } | 2209 | } |
2214 | 2210 | ||
2215 | int | 2211 | int |
2216 | sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, | 2212 | sshd_hostkey_sign(struct sshkey *privkey, struct sshkey *pubkey, |
2217 | const u_char *data, size_t dlen, const char *alg, u_int flag) | 2213 | u_char **signature, size_t *slen, const u_char *data, size_t dlen, |
2214 | const char *alg, u_int flag) | ||
2218 | { | 2215 | { |
2219 | int r; | 2216 | int r; |
2220 | u_int xxx_slen, xxx_dlen = dlen; | 2217 | u_int xxx_slen, xxx_dlen = dlen; |
@@ -2343,7 +2340,7 @@ do_ssh2_kex(void) | |||
2343 | kex->host_key_index=&get_hostkey_index; | 2340 | kex->host_key_index=&get_hostkey_index; |
2344 | kex->sign = sshd_hostkey_sign; | 2341 | kex->sign = sshd_hostkey_sign; |
2345 | 2342 | ||
2346 | dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); | 2343 | ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); |
2347 | 2344 | ||
2348 | session_id2 = kex->session_id; | 2345 | session_id2 = kex->session_id; |
2349 | session_id2_len = kex->session_id_len; | 2346 | session_id2_len = kex->session_id_len; |
@@ -2362,8 +2359,10 @@ do_ssh2_kex(void) | |||
2362 | void | 2359 | void |
2363 | cleanup_exit(int i) | 2360 | cleanup_exit(int i) |
2364 | { | 2361 | { |
2362 | struct ssh *ssh = active_state; /* XXX */ | ||
2363 | |||
2365 | if (the_authctxt) { | 2364 | if (the_authctxt) { |
2366 | do_cleanup(the_authctxt); | 2365 | do_cleanup(ssh, the_authctxt); |
2367 | if (use_privsep && privsep_is_preauth && | 2366 | if (use_privsep && privsep_is_preauth && |
2368 | pmonitor != NULL && pmonitor->m_pid > 1) { | 2367 | pmonitor != NULL && pmonitor->m_pid > 1) { |
2369 | debug("Killing privsep child %d", pmonitor->m_pid); | 2368 | debug("Killing privsep child %d", pmonitor->m_pid); |