summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c83
1 files changed, 75 insertions, 8 deletions
diff --git a/sshd.c b/sshd.c
index 1306a62a7..174cc7a42 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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 */
195Kex *xxx_kex; 196Kex *xxx_kex;
196 197
198/* Daemon's agent connection */
199AuthenticationConnection *auth_conn = NULL;
200int 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
863Key *
864get_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
851int 871int
852get_hostkey_index(Key *key) 872get_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
2388void
2389sshd_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