- 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@
This commit is contained in:
parent
d93340cbb6
commit
85b45e0918
|
@ -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
4
auth.h
|
@ -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
3
kex.h
|
@ -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 *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
10
kexdhs.c
10
kexdhs.c
|
@ -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(); */
|
||||||
|
|
||||||
|
|
10
kexecdhs.c
10
kexecdhs.c
|
@ -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(); */
|
||||||
|
|
||||||
|
|
11
kexgexs.c
11
kexgexs.c
|
@ -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(); */
|
||||||
|
|
||||||
|
|
16
monitor.c
16
monitor.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
18
servconf.c
18
servconf.c
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
10
session.c
10
session.c
|
@ -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
83
sshd.c
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue