diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 83 |
1 files changed, 75 insertions, 8 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.403 2013/06/05 02:27:50 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" |
@@ -194,6 +195,10 @@ char *server_version_string = NULL; | |||
194 | /* for rekeying XXX fixme */ | 195 | /* for rekeying XXX fixme */ |
195 | Kex *xxx_kex; | 196 | Kex *xxx_kex; |
196 | 197 | ||
198 | /* Daemon's agent connection */ | ||
199 | AuthenticationConnection *auth_conn = NULL; | ||
200 | int have_agent = 0; | ||
201 | |||
197 | /* | 202 | /* |
198 | * Any really sensitive data in the application is contained in this | 203 | * Any really sensitive data in the application is contained in this |
199 | * structure. The idea is that this structure could be locked into memory so | 204 | * structure. The idea is that this structure could be locked into memory so |
@@ -206,6 +211,7 @@ struct { | |||
206 | Key *server_key; /* ephemeral server key */ | 211 | Key *server_key; /* ephemeral server key */ |
207 | Key *ssh1_host_key; /* ssh1 host key */ | 212 | Key *ssh1_host_key; /* ssh1 host key */ |
208 | Key **host_keys; /* all private host keys */ | 213 | Key **host_keys; /* all private host keys */ |
214 | Key **host_pubkeys; /* all public host keys */ | ||
209 | Key **host_certificates; /* all public host certificates */ | 215 | Key **host_certificates; /* all public host certificates */ |
210 | int have_ssh1_key; | 216 | int have_ssh1_key; |
211 | int have_ssh2_key; | 217 | int have_ssh2_key; |
@@ -653,6 +659,8 @@ privsep_preauth(Authctxt *authctxt) | |||
653 | debug2("Network child is on pid %ld", (long)pid); | 659 | debug2("Network child is on pid %ld", (long)pid); |
654 | 660 | ||
655 | pmonitor->m_pid = pid; | 661 | pmonitor->m_pid = pid; |
662 | if (have_agent) | ||
663 | auth_conn = ssh_get_authentication_connection(); | ||
656 | if (box != NULL) | 664 | if (box != NULL) |
657 | ssh_sandbox_parent_preauth(box, pid); | 665 | ssh_sandbox_parent_preauth(box, pid); |
658 | monitor_child_preauth(authctxt, pmonitor); | 666 | monitor_child_preauth(authctxt, pmonitor); |
@@ -767,6 +775,8 @@ list_hostkey_types(void) | |||
767 | for (i = 0; i < options.num_host_key_files; i++) { | 775 | for (i = 0; i < options.num_host_key_files; i++) { |
768 | key = sensitive_data.host_keys[i]; | 776 | key = sensitive_data.host_keys[i]; |
769 | if (key == NULL) | 777 | if (key == NULL) |
778 | key = sensitive_data.host_pubkeys[i]; | ||
779 | if (key == NULL) | ||
770 | continue; | 780 | continue; |
771 | switch (key->type) { | 781 | switch (key->type) { |
772 | case KEY_RSA: | 782 | case KEY_RSA: |
@@ -819,6 +829,8 @@ get_hostkey_by_type(int type, int need_private) | |||
819 | break; | 829 | break; |
820 | default: | 830 | default: |
821 | key = sensitive_data.host_keys[i]; | 831 | key = sensitive_data.host_keys[i]; |
832 | if (key == NULL && !need_private) | ||
833 | key = sensitive_data.host_pubkeys[i]; | ||
822 | break; | 834 | break; |
823 | } | 835 | } |
824 | if (key != NULL && key->type == type) | 836 | if (key != NULL && key->type == type) |
@@ -848,6 +860,14 @@ get_hostkey_by_index(int ind) | |||
848 | return (sensitive_data.host_keys[ind]); | 860 | return (sensitive_data.host_keys[ind]); |
849 | } | 861 | } |
850 | 862 | ||
863 | Key * | ||
864 | get_hostkey_public_by_index(int ind) | ||
865 | { | ||
866 | if (ind < 0 || ind >= options.num_host_key_files) | ||
867 | return (NULL); | ||
868 | return (sensitive_data.host_pubkeys[ind]); | ||
869 | } | ||
870 | |||
851 | int | 871 | int |
852 | get_hostkey_index(Key *key) | 872 | get_hostkey_index(Key *key) |
853 | { | 873 | { |
@@ -860,6 +880,8 @@ get_hostkey_index(Key *key) | |||
860 | } else { | 880 | } else { |
861 | if (key == sensitive_data.host_keys[i]) | 881 | if (key == sensitive_data.host_keys[i]) |
862 | return (i); | 882 | return (i); |
883 | if (key == sensitive_data.host_pubkeys[i]) | ||
884 | return (i); | ||
863 | } | 885 | } |
864 | } | 886 | } |
865 | return (-1); | 887 | return (-1); |
@@ -1344,6 +1366,8 @@ main(int ac, char **av) | |||
1344 | u_int64_t ibytes, obytes; | 1366 | u_int64_t ibytes, obytes; |
1345 | mode_t new_umask; | 1367 | mode_t new_umask; |
1346 | Key *key; | 1368 | Key *key; |
1369 | Key *pubkey; | ||
1370 | int keytype; | ||
1347 | Authctxt *authctxt; | 1371 | Authctxt *authctxt; |
1348 | struct connection_info *connection_info = get_connection_info(0, 0); | 1372 | struct connection_info *connection_info = get_connection_info(0, 0); |
1349 | 1373 | ||
@@ -1623,22 +1647,45 @@ main(int ac, char **av) | |||
1623 | } | 1647 | } |
1624 | endpwent(); | 1648 | endpwent(); |
1625 | 1649 | ||
1626 | /* load private host keys */ | 1650 | /* load host keys */ |
1627 | sensitive_data.host_keys = xcalloc(options.num_host_key_files, | 1651 | sensitive_data.host_keys = xcalloc(options.num_host_key_files, |
1628 | sizeof(Key *)); | 1652 | sizeof(Key *)); |
1629 | for (i = 0; i < options.num_host_key_files; i++) | 1653 | sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, |
1654 | sizeof(Key *)); | ||
1655 | for (i = 0; i < options.num_host_key_files; i++) { | ||
1630 | sensitive_data.host_keys[i] = NULL; | 1656 | sensitive_data.host_keys[i] = NULL; |
1657 | sensitive_data.host_pubkeys[i] = NULL; | ||
1658 | } | ||
1659 | |||
1660 | if (options.host_key_agent) { | ||
1661 | if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) | ||
1662 | setenv(SSH_AUTHSOCKET_ENV_NAME, | ||
1663 | options.host_key_agent, 1); | ||
1664 | have_agent = ssh_agent_present(); | ||
1665 | } | ||
1631 | 1666 | ||
1632 | for (i = 0; i < options.num_host_key_files; i++) { | 1667 | for (i = 0; i < options.num_host_key_files; i++) { |
1633 | key = key_load_private(options.host_key_files[i], "", NULL); | 1668 | key = key_load_private(options.host_key_files[i], "", NULL); |
1669 | pubkey = key_load_public(options.host_key_files[i], NULL); | ||
1634 | sensitive_data.host_keys[i] = key; | 1670 | sensitive_data.host_keys[i] = key; |
1635 | if (key == NULL) { | 1671 | sensitive_data.host_pubkeys[i] = pubkey; |
1672 | |||
1673 | if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 && | ||
1674 | have_agent) { | ||
1675 | debug("will rely on agent for hostkey %s", | ||
1676 | options.host_key_files[i]); | ||
1677 | keytype = pubkey->type; | ||
1678 | } else if (key != NULL) { | ||
1679 | keytype = key->type; | ||
1680 | } else { | ||
1636 | error("Could not load host key: %s", | 1681 | error("Could not load host key: %s", |
1637 | options.host_key_files[i]); | 1682 | options.host_key_files[i]); |
1638 | sensitive_data.host_keys[i] = NULL; | 1683 | sensitive_data.host_keys[i] = NULL; |
1684 | sensitive_data.host_pubkeys[i] = NULL; | ||
1639 | continue; | 1685 | continue; |
1640 | } | 1686 | } |
1641 | switch (key->type) { | 1687 | |
1688 | switch (keytype) { | ||
1642 | case KEY_RSA1: | 1689 | case KEY_RSA1: |
1643 | sensitive_data.ssh1_host_key = key; | 1690 | sensitive_data.ssh1_host_key = key; |
1644 | sensitive_data.have_ssh1_key = 1; | 1691 | sensitive_data.have_ssh1_key = 1; |
@@ -1649,8 +1696,8 @@ main(int ac, char **av) | |||
1649 | sensitive_data.have_ssh2_key = 1; | 1696 | sensitive_data.have_ssh2_key = 1; |
1650 | break; | 1697 | break; |
1651 | } | 1698 | } |
1652 | debug("private host key: #%d type %d %s", i, key->type, | 1699 | debug("private host key: #%d type %d %s", i, keytype, |
1653 | key_type(key)); | 1700 | key_type(key ? key : pubkey)); |
1654 | } | 1701 | } |
1655 | if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { | 1702 | if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { |
1656 | logit("Disabling protocol version 1. Could not load host key"); | 1703 | logit("Disabling protocol version 1. Could not load host key"); |
@@ -2020,9 +2067,11 @@ main(int ac, char **av) | |||
2020 | buffer_init(&loginmsg); | 2067 | buffer_init(&loginmsg); |
2021 | auth_debug_reset(); | 2068 | auth_debug_reset(); |
2022 | 2069 | ||
2023 | if (use_privsep) | 2070 | if (use_privsep) { |
2024 | if (privsep_preauth(authctxt) == 1) | 2071 | if (privsep_preauth(authctxt) == 1) |
2025 | goto authenticated; | 2072 | goto authenticated; |
2073 | } else if (compat20 && have_agent) | ||
2074 | auth_conn = ssh_get_authentication_connection(); | ||
2026 | 2075 | ||
2027 | /* perform the key exchange */ | 2076 | /* perform the key exchange */ |
2028 | /* authenticate user and start session */ | 2077 | /* authenticate user and start session */ |
@@ -2336,6 +2385,23 @@ do_ssh1_kex(void) | |||
2336 | packet_write_wait(); | 2385 | packet_write_wait(); |
2337 | } | 2386 | } |
2338 | 2387 | ||
2388 | void | ||
2389 | sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen, | ||
2390 | u_char *data, u_int dlen) | ||
2391 | { | ||
2392 | if (privkey) { | ||
2393 | if (PRIVSEP(key_sign(privkey, signature, slen, data, dlen) < 0)) | ||
2394 | fatal("%s: key_sign failed", __func__); | ||
2395 | } else if (use_privsep) { | ||
2396 | if (mm_key_sign(pubkey, signature, slen, data, dlen) < 0) | ||
2397 | fatal("%s: pubkey_sign failed", __func__); | ||
2398 | } else { | ||
2399 | if (ssh_agent_sign(auth_conn, pubkey, signature, slen, data, | ||
2400 | dlen)) | ||
2401 | fatal("%s: ssh_agent_sign failed", __func__); | ||
2402 | } | ||
2403 | } | ||
2404 | |||
2339 | /* | 2405 | /* |
2340 | * SSH2 key exchange: diffie-hellman-group1-sha1 | 2406 | * SSH2 key exchange: diffie-hellman-group1-sha1 |
2341 | */ | 2407 | */ |
@@ -2386,6 +2452,7 @@ do_ssh2_kex(void) | |||
2386 | kex->load_host_public_key=&get_hostkey_public_by_type; | 2452 | kex->load_host_public_key=&get_hostkey_public_by_type; |
2387 | kex->load_host_private_key=&get_hostkey_private_by_type; | 2453 | kex->load_host_private_key=&get_hostkey_private_by_type; |
2388 | kex->host_key_index=&get_hostkey_index; | 2454 | kex->host_key_index=&get_hostkey_index; |
2455 | kex->sign = sshd_hostkey_sign; | ||
2389 | 2456 | ||
2390 | xxx_kex = kex; | 2457 | xxx_kex = kex; |
2391 | 2458 | ||