[auth.h kex.h kexdhs.c kexecdhs.c kexgexs.c monitor.c servconf.c]
     [servconf.h session.c sshd.c sshd_config.5]
     add ssh-agent(1) support to sshd(8); allows encrypted hostkeys,
     or hostkeys on smartcards; most of the work by Zev Weiss; bz #1974
     ok djm@
This commit is contained in:
Damien Miller 2013-07-20 13:21:52 +10:00
parent d93340cbb6
commit 85b45e0918
12 changed files with 153 additions and 42 deletions

View File

@ -1,3 +1,12 @@
20130720
- (djm) OpenBSD CVS Sync
- markus@cvs.openbsd.org 2013/07/19 07:37:48
[auth.h kex.h kexdhs.c kexecdhs.c kexgexs.c monitor.c servconf.c]
[servconf.h session.c sshd.c sshd_config.5]
add ssh-agent(1) support to sshd(8); allows encrypted hostkeys,
or hostkeys on smartcards; most of the work by Zev Weiss; bz #1974
ok djm@
20130718 20130718
- (djm) OpenBSD CVS Sync - (djm) OpenBSD CVS Sync
- dtucker@cvs.openbsd.org 2013/06/10 19:19:44 - dtucker@cvs.openbsd.org 2013/06/10 19:19:44

4
auth.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.75 2013/06/21 00:34:49 djm Exp $ */ /* $OpenBSD: auth.h,v 1.76 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -198,10 +198,12 @@ check_key_in_hostfiles(struct passwd *, Key *, const char *,
/* hostkey handling */ /* hostkey handling */
Key *get_hostkey_by_index(int); Key *get_hostkey_by_index(int);
Key *get_hostkey_public_by_index(int);
Key *get_hostkey_public_by_type(int); Key *get_hostkey_public_by_type(int);
Key *get_hostkey_private_by_type(int); Key *get_hostkey_private_by_type(int);
int get_hostkey_index(Key *); int get_hostkey_index(Key *);
int ssh1_session_key(BIGNUM *); int ssh1_session_key(BIGNUM *);
void sshd_hostkey_sign(Key *, Key *, u_char **, u_int *, u_char *, u_int);
/* debug messages during authentication */ /* debug messages during authentication */
void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));

3
kex.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.h,v 1.55 2013/04/19 01:06:50 djm Exp $ */ /* $OpenBSD: kex.h,v 1.56 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -139,6 +139,7 @@ struct Kex {
Key *(*load_host_public_key)(int); Key *(*load_host_public_key)(int);
Key *(*load_host_private_key)(int); Key *(*load_host_private_key)(int);
int (*host_key_index)(Key *); int (*host_key_index)(Key *);
void (*sign)(Key *, Key *, u_char **, u_int *, u_char *, u_int);
void (*kex[KEX_MAX])(Kex *); void (*kex[KEX_MAX])(Kex *);
}; };

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexdhs.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */ /* $OpenBSD: kexdhs.c,v 1.14 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved.
* *
@ -80,9 +80,6 @@ kexdh_server(Kex *kex)
if (server_host_public == NULL) if (server_host_public == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type); fatal("Unsupported hostkey type %d", kex->hostkey_type);
server_host_private = kex->load_host_private_key(kex->hostkey_type); server_host_private = kex->load_host_private_key(kex->hostkey_type);
if (server_host_private == NULL)
fatal("Missing private key for hostkey type %d",
kex->hostkey_type);
/* key, cert */ /* key, cert */
if ((dh_client_pub = BN_new()) == NULL) if ((dh_client_pub = BN_new()) == NULL)
@ -144,9 +141,8 @@ kexdh_server(Kex *kex)
} }
/* sign H */ /* sign H */
if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, kex->sign(server_host_private, server_host_public, &signature, &slen,
hashlen)) < 0) hash, hashlen);
fatal("kexdh_server: key_sign failed");
/* destroy_sensitive_data(); */ /* destroy_sensitive_data(); */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexecdhs.c,v 1.4 2013/05/17 00:13:13 djm Exp $ */ /* $OpenBSD: kexecdhs.c,v 1.5 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved.
@ -78,9 +78,6 @@ kexecdh_server(Kex *kex)
if (server_host_public == NULL) if (server_host_public == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type); fatal("Unsupported hostkey type %d", kex->hostkey_type);
server_host_private = kex->load_host_private_key(kex->hostkey_type); server_host_private = kex->load_host_private_key(kex->hostkey_type);
if (server_host_private == NULL)
fatal("Missing private key for hostkey type %d",
kex->hostkey_type);
debug("expecting SSH2_MSG_KEX_ECDH_INIT"); debug("expecting SSH2_MSG_KEX_ECDH_INIT");
packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); packet_read_expect(SSH2_MSG_KEX_ECDH_INIT);
@ -139,9 +136,8 @@ kexecdh_server(Kex *kex)
} }
/* sign H */ /* sign H */
if (PRIVSEP(key_sign(server_host_private, &signature, &slen, kex->sign(server_host_private, server_host_public, &signature, &slen,
hash, hashlen)) < 0) hash, hashlen);
fatal("kexdh_server: key_sign failed");
/* destroy_sensitive_data(); */ /* destroy_sensitive_data(); */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexgexs.c,v 1.15 2013/05/17 00:13:13 djm Exp $ */ /* $OpenBSD: kexgexs.c,v 1.16 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -68,10 +68,6 @@ kexgex_server(Kex *kex)
if (server_host_public == NULL) if (server_host_public == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type); fatal("Unsupported hostkey type %d", kex->hostkey_type);
server_host_private = kex->load_host_private_key(kex->hostkey_type); server_host_private = kex->load_host_private_key(kex->hostkey_type);
if (server_host_private == NULL)
fatal("Missing private key for hostkey type %d",
kex->hostkey_type);
type = packet_read(); type = packet_read();
switch (type) { switch (type) {
@ -187,9 +183,8 @@ kexgex_server(Kex *kex)
} }
/* sign H */ /* sign H */
if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, kex->sign(server_host_private, server_host_public, &signature, &slen,
hashlen)) < 0) hash, hashlen);
fatal("kexgex_server: key_sign failed");
/* destroy_sensitive_data(); */ /* destroy_sensitive_data(); */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.126 2013/06/21 00:34:49 djm Exp $ */ /* $OpenBSD: monitor.c,v 1.127 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org> * Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -97,6 +97,7 @@
#include "ssh2.h" #include "ssh2.h"
#include "jpake.h" #include "jpake.h"
#include "roaming.h" #include "roaming.h"
#include "authfd.h"
#ifdef GSSAPI #ifdef GSSAPI
static Gssctxt *gsscontext = NULL; static Gssctxt *gsscontext = NULL;
@ -686,6 +687,8 @@ mm_answer_moduli(int sock, Buffer *m)
return (0); return (0);
} }
extern AuthenticationConnection *auth_conn;
int int
mm_answer_sign(int sock, Buffer *m) mm_answer_sign(int sock, Buffer *m)
{ {
@ -714,10 +717,16 @@ mm_answer_sign(int sock, Buffer *m)
memcpy(session_id2, p, session_id2_len); memcpy(session_id2, p, session_id2_len);
} }
if ((key = get_hostkey_by_index(keyid)) == NULL) if ((key = get_hostkey_by_index(keyid)) != NULL) {
fatal("%s: no hostkey from index %d", __func__, keyid);
if (key_sign(key, &signature, &siglen, p, datlen) < 0) if (key_sign(key, &signature, &siglen, p, datlen) < 0)
fatal("%s: key_sign failed", __func__); fatal("%s: key_sign failed", __func__);
} else if ((key = get_hostkey_public_by_index(keyid)) != NULL &&
auth_conn != NULL) {
if (ssh_agent_sign(auth_conn, key, &signature, &siglen, p,
datlen) < 0)
fatal("%s: ssh_agent_sign failed", __func__);
} else
fatal("%s: no hostkey from index %d", __func__, keyid);
debug3("%s: signature %p(%u)", __func__, signature, siglen); debug3("%s: signature %p(%u)", __func__, signature, siglen);
@ -1864,6 +1873,7 @@ mm_get_kex(Buffer *m)
kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_public_key=&get_hostkey_public_by_type;
kex->load_host_private_key=&get_hostkey_private_by_type; kex->load_host_private_key=&get_hostkey_private_by_type;
kex->host_key_index=&get_hostkey_index; kex->host_key_index=&get_hostkey_index;
kex->sign = sshd_hostkey_sign;
return (kex); return (kex);
} }

View File

@ -1,5 +1,5 @@
/* $OpenBSD: servconf.c,v 1.239 2013/05/17 00:13:14 djm Exp $ */ /* $OpenBSD: servconf.c,v 1.240 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -79,6 +79,7 @@ initialize_server_options(ServerOptions *options)
options->address_family = -1; options->address_family = -1;
options->num_host_key_files = 0; options->num_host_key_files = 0;
options->num_host_cert_files = 0; options->num_host_cert_files = 0;
options->host_key_agent = NULL;
options->pid_file = NULL; options->pid_file = NULL;
options->server_key_bits = -1; options->server_key_bits = -1;
options->login_grace_time = -1; options->login_grace_time = -1;
@ -344,7 +345,7 @@ typedef enum {
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
sKexAlgorithms, sIPQoS, sVersionAddendum, sKexAlgorithms, sIPQoS, sVersionAddendum,
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
sAuthenticationMethods, sAuthenticationMethods, sHostKeyAgent,
sDeprecated, sUnsupported sDeprecated, sUnsupported
} ServerOpCodes; } ServerOpCodes;
@ -369,6 +370,7 @@ static struct {
{ "port", sPort, SSHCFG_GLOBAL }, { "port", sPort, SSHCFG_GLOBAL },
{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
{ "pidfile", sPidFile, SSHCFG_GLOBAL }, { "pidfile", sPidFile, SSHCFG_GLOBAL },
{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
@ -978,6 +980,17 @@ process_server_config_line(ServerOptions *options, char *line,
} }
break; break;
case sHostKeyAgent:
charptr = &options->host_key_agent;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing socket name.",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
xstrdup(arg) : derelativise_path(arg);
break;
case sHostCertificate: case sHostCertificate:
intptr = &options->num_host_cert_files; intptr = &options->num_host_cert_files;
if (*intptr >= MAX_HOSTKEYS) if (*intptr >= MAX_HOSTKEYS)
@ -2011,6 +2024,7 @@ dump_config(ServerOptions *o)
dump_cfg_string(sVersionAddendum, o->version_addendum); dump_cfg_string(sVersionAddendum, o->version_addendum);
dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
dump_cfg_string(sHostKeyAgent, o->host_key_agent);
/* string arguments requiring a lookup */ /* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level)); dump_cfg_string(sLogLevel, log_level_name(o->log_level));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.108 2013/05/16 04:09:14 dtucker Exp $ */ /* $OpenBSD: servconf.h,v 1.109 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -65,6 +65,7 @@ typedef struct {
int num_host_key_files; /* Number of files for host keys. */ int num_host_key_files; /* Number of files for host keys. */
char *host_cert_files[MAX_HOSTCERTS]; /* Files containing host certs. */ char *host_cert_files[MAX_HOSTCERTS]; /* Files containing host certs. */
int num_host_cert_files; /* Number of files for host certs. */ int num_host_cert_files; /* Number of files for host certs. */
char *host_key_agent; /* ssh-agent socket for host keys. */
char *pid_file; /* Where to put our pid */ char *pid_file; /* Where to put our pid */
int server_key_bits;/* Size of the server key. */ int server_key_bits;/* Size of the server key. */
int login_grace_time; /* Disconnect if no auth in this time int login_grace_time; /* Disconnect if no auth in this time

View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.265 2013/05/17 00:13:14 djm Exp $ */ /* $OpenBSD: session.c,v 1.266 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -80,6 +80,7 @@
#include "hostfile.h" #include "hostfile.h"
#include "auth.h" #include "auth.h"
#include "auth-options.h" #include "auth-options.h"
#include "authfd.h"
#include "pathnames.h" #include "pathnames.h"
#include "log.h" #include "log.h"
#include "servconf.h" #include "servconf.h"
@ -1589,6 +1590,13 @@ launch_login(struct passwd *pw, const char *hostname)
static void static void
child_close_fds(void) child_close_fds(void)
{ {
extern AuthenticationConnection *auth_conn;
if (auth_conn) {
ssh_close_authentication_connection(auth_conn);
auth_conn = NULL;
}
if (packet_get_connection_in() == packet_get_connection_out()) if (packet_get_connection_in() == packet_get_connection_out())
close(packet_get_connection_in()); close(packet_get_connection_in());
else { else {

83
sshd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.403 2013/06/05 02:27:50 dtucker Exp $ */ /* $OpenBSD: sshd.c,v 1.404 2013/07/19 07:37:48 markus Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -106,6 +106,7 @@
#include "canohost.h" #include "canohost.h"
#include "hostfile.h" #include "hostfile.h"
#include "auth.h" #include "auth.h"
#include "authfd.h"
#include "misc.h" #include "misc.h"
#include "msg.h" #include "msg.h"
#include "dispatch.h" #include "dispatch.h"
@ -194,6 +195,10 @@ char *server_version_string = NULL;
/* for rekeying XXX fixme */ /* for rekeying XXX fixme */
Kex *xxx_kex; Kex *xxx_kex;
/* Daemon's agent connection */
AuthenticationConnection *auth_conn = NULL;
int have_agent = 0;
/* /*
* Any really sensitive data in the application is contained in this * Any really sensitive data in the application is contained in this
* structure. The idea is that this structure could be locked into memory so * structure. The idea is that this structure could be locked into memory so
@ -206,6 +211,7 @@ struct {
Key *server_key; /* ephemeral server key */ Key *server_key; /* ephemeral server key */
Key *ssh1_host_key; /* ssh1 host key */ Key *ssh1_host_key; /* ssh1 host key */
Key **host_keys; /* all private host keys */ Key **host_keys; /* all private host keys */
Key **host_pubkeys; /* all public host keys */
Key **host_certificates; /* all public host certificates */ Key **host_certificates; /* all public host certificates */
int have_ssh1_key; int have_ssh1_key;
int have_ssh2_key; int have_ssh2_key;
@ -653,6 +659,8 @@ privsep_preauth(Authctxt *authctxt)
debug2("Network child is on pid %ld", (long)pid); debug2("Network child is on pid %ld", (long)pid);
pmonitor->m_pid = pid; pmonitor->m_pid = pid;
if (have_agent)
auth_conn = ssh_get_authentication_connection();
if (box != NULL) if (box != NULL)
ssh_sandbox_parent_preauth(box, pid); ssh_sandbox_parent_preauth(box, pid);
monitor_child_preauth(authctxt, pmonitor); monitor_child_preauth(authctxt, pmonitor);
@ -766,6 +774,8 @@ list_hostkey_types(void)
buffer_init(&b); buffer_init(&b);
for (i = 0; i < options.num_host_key_files; i++) { for (i = 0; i < options.num_host_key_files; i++) {
key = sensitive_data.host_keys[i]; key = sensitive_data.host_keys[i];
if (key == NULL)
key = sensitive_data.host_pubkeys[i];
if (key == NULL) if (key == NULL)
continue; continue;
switch (key->type) { switch (key->type) {
@ -819,6 +829,8 @@ get_hostkey_by_type(int type, int need_private)
break; break;
default: default:
key = sensitive_data.host_keys[i]; key = sensitive_data.host_keys[i];
if (key == NULL && !need_private)
key = sensitive_data.host_pubkeys[i];
break; break;
} }
if (key != NULL && key->type == type) if (key != NULL && key->type == type)
@ -848,6 +860,14 @@ get_hostkey_by_index(int ind)
return (sensitive_data.host_keys[ind]); return (sensitive_data.host_keys[ind]);
} }
Key *
get_hostkey_public_by_index(int ind)
{
if (ind < 0 || ind >= options.num_host_key_files)
return (NULL);
return (sensitive_data.host_pubkeys[ind]);
}
int int
get_hostkey_index(Key *key) get_hostkey_index(Key *key)
{ {
@ -860,6 +880,8 @@ get_hostkey_index(Key *key)
} else { } else {
if (key == sensitive_data.host_keys[i]) if (key == sensitive_data.host_keys[i])
return (i); return (i);
if (key == sensitive_data.host_pubkeys[i])
return (i);
} }
} }
return (-1); return (-1);
@ -1344,6 +1366,8 @@ main(int ac, char **av)
u_int64_t ibytes, obytes; u_int64_t ibytes, obytes;
mode_t new_umask; mode_t new_umask;
Key *key; Key *key;
Key *pubkey;
int keytype;
Authctxt *authctxt; Authctxt *authctxt;
struct connection_info *connection_info = get_connection_info(0, 0); struct connection_info *connection_info = get_connection_info(0, 0);
@ -1623,22 +1647,45 @@ main(int ac, char **av)
} }
endpwent(); endpwent();
/* load private host keys */ /* load host keys */
sensitive_data.host_keys = xcalloc(options.num_host_key_files, sensitive_data.host_keys = xcalloc(options.num_host_key_files,
sizeof(Key *)); sizeof(Key *));
for (i = 0; i < options.num_host_key_files; i++) sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files,
sizeof(Key *));
for (i = 0; i < options.num_host_key_files; i++) {
sensitive_data.host_keys[i] = NULL; sensitive_data.host_keys[i] = NULL;
sensitive_data.host_pubkeys[i] = NULL;
}
if (options.host_key_agent) {
if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
setenv(SSH_AUTHSOCKET_ENV_NAME,
options.host_key_agent, 1);
have_agent = ssh_agent_present();
}
for (i = 0; i < options.num_host_key_files; i++) { for (i = 0; i < options.num_host_key_files; i++) {
key = key_load_private(options.host_key_files[i], "", NULL); key = key_load_private(options.host_key_files[i], "", NULL);
pubkey = key_load_public(options.host_key_files[i], NULL);
sensitive_data.host_keys[i] = key; sensitive_data.host_keys[i] = key;
if (key == NULL) { sensitive_data.host_pubkeys[i] = pubkey;
if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 &&
have_agent) {
debug("will rely on agent for hostkey %s",
options.host_key_files[i]);
keytype = pubkey->type;
} else if (key != NULL) {
keytype = key->type;
} else {
error("Could not load host key: %s", error("Could not load host key: %s",
options.host_key_files[i]); options.host_key_files[i]);
sensitive_data.host_keys[i] = NULL; sensitive_data.host_keys[i] = NULL;
sensitive_data.host_pubkeys[i] = NULL;
continue; continue;
} }
switch (key->type) {
switch (keytype) {
case KEY_RSA1: case KEY_RSA1:
sensitive_data.ssh1_host_key = key; sensitive_data.ssh1_host_key = key;
sensitive_data.have_ssh1_key = 1; sensitive_data.have_ssh1_key = 1;
@ -1649,8 +1696,8 @@ main(int ac, char **av)
sensitive_data.have_ssh2_key = 1; sensitive_data.have_ssh2_key = 1;
break; break;
} }
debug("private host key: #%d type %d %s", i, key->type, debug("private host key: #%d type %d %s", i, keytype,
key_type(key)); key_type(key ? key : pubkey));
} }
if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
logit("Disabling protocol version 1. Could not load host key"); logit("Disabling protocol version 1. Could not load host key");
@ -2020,9 +2067,11 @@ main(int ac, char **av)
buffer_init(&loginmsg); buffer_init(&loginmsg);
auth_debug_reset(); auth_debug_reset();
if (use_privsep) if (use_privsep) {
if (privsep_preauth(authctxt) == 1) if (privsep_preauth(authctxt) == 1)
goto authenticated; goto authenticated;
} else if (compat20 && have_agent)
auth_conn = ssh_get_authentication_connection();
/* perform the key exchange */ /* perform the key exchange */
/* authenticate user and start session */ /* authenticate user and start session */
@ -2336,6 +2385,23 @@ do_ssh1_kex(void)
packet_write_wait(); packet_write_wait();
} }
void
sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen,
u_char *data, u_int dlen)
{
if (privkey) {
if (PRIVSEP(key_sign(privkey, signature, slen, data, dlen) < 0))
fatal("%s: key_sign failed", __func__);
} else if (use_privsep) {
if (mm_key_sign(pubkey, signature, slen, data, dlen) < 0)
fatal("%s: pubkey_sign failed", __func__);
} else {
if (ssh_agent_sign(auth_conn, pubkey, signature, slen, data,
dlen))
fatal("%s: ssh_agent_sign failed", __func__);
}
}
/* /*
* SSH2 key exchange: diffie-hellman-group1-sha1 * SSH2 key exchange: diffie-hellman-group1-sha1
*/ */
@ -2386,6 +2452,7 @@ do_ssh2_kex(void)
kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_public_key=&get_hostkey_public_by_type;
kex->load_host_private_key=&get_hostkey_private_by_type; kex->load_host_private_key=&get_hostkey_private_by_type;
kex->host_key_index=&get_hostkey_index; kex->host_key_index=&get_hostkey_index;
kex->sign = sshd_hostkey_sign;
xxx_kex = kex; xxx_kex = kex;

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: sshd_config.5,v 1.161 2013/06/27 14:05:37 jmc Exp $ .\" $OpenBSD: sshd_config.5,v 1.162 2013/07/19 07:37:48 markus Exp $
.Dd $Mdocdate: June 27 2013 $ .Dd $Mdocdate: July 19 2013 $
.Dt SSHD_CONFIG 5 .Dt SSHD_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -546,6 +546,18 @@ keys are used for version 1 and
or or
.Dq rsa .Dq rsa
are used for version 2 of the SSH protocol. are used for version 2 of the SSH protocol.
It is also possible to specify public host key files instead.
In this case operations on the private key will be delegated
to an
.Xr ssh-agent 1 .
.It Cm HostKeyAgent
Identifies the UNIX-domain socket used to communicate
with an agent that has access to the private host keys.
If
.Dq SSH_AUTH_SOCK
is specified, the location of the socket will be read from the
.Ev SSH_AUTH_SOCK
environment variable.
.It Cm IgnoreRhosts .It Cm IgnoreRhosts
Specifies that Specifies that
.Pa .rhosts .Pa .rhosts