mirror of git://anongit.mindrot.org/openssh.git
upstream: ssh client side of binding
send session ID, hostkey, signature and a flag indicating whether the agent connection is being forwarded to ssh agent each time a connection is opened via a new "session-bind@openssh.com" agent extension. ok markus@ OpenBSD-Commit-ID: 2f154844fe13167d3ab063f830d7455fcaa99135
This commit is contained in:
parent
b42c61d684
commit
e9497ecf73
31
authfd.c
31
authfd.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: authfd.c,v 1.127 2021/01/26 00:46:17 djm Exp $ */
|
||||
/* $OpenBSD: authfd.c,v 1.128 2021/12/19 22:08:48 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -650,3 +650,32 @@ ssh_remove_all_identities(int sock, int version)
|
|||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Binds a session ID to a hostkey via the initial KEX signature. */
|
||||
int
|
||||
ssh_agent_bind_hostkey(int sock, const struct sshkey *key,
|
||||
const struct sshbuf *session_id, const struct sshbuf *signature,
|
||||
int forwarding)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
int r;
|
||||
|
||||
if (key == NULL || session_id == NULL || signature == NULL)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_EXTENSION)) != 0 ||
|
||||
(r = sshbuf_put_cstring(msg, "session-bind@openssh.com")) != 0 ||
|
||||
(r = sshkey_puts(key, msg)) != 0 ||
|
||||
(r = sshbuf_put_stringb(msg, session_id)) != 0 ||
|
||||
(r = sshbuf_put_stringb(msg, signature)) != 0 ||
|
||||
(r = sshbuf_put_u8(msg, forwarding ? 1 : 0)) != 0)
|
||||
goto out;
|
||||
if ((r = ssh_request_reply_decode(sock, msg)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
||||
|
|
11
authfd.h
11
authfd.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: authfd.h,v 1.49 2020/06/26 05:03:36 djm Exp $ */
|
||||
/* $OpenBSD: authfd.h,v 1.50 2021/12/19 22:08:48 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -16,6 +16,8 @@
|
|||
#ifndef AUTHFD_H
|
||||
#define AUTHFD_H
|
||||
|
||||
struct sshbuf;
|
||||
|
||||
/* List of identities returned by ssh_fetch_identitylist() */
|
||||
struct ssh_identitylist {
|
||||
size_t nkeys;
|
||||
|
@ -43,6 +45,10 @@ int ssh_agent_sign(int sock, const struct sshkey *key,
|
|||
u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, const char *alg, u_int compat);
|
||||
|
||||
int ssh_agent_bind_hostkey(int sock, const struct sshkey *key,
|
||||
const struct sshbuf *session_id, const struct sshbuf *signature,
|
||||
int forwarding);
|
||||
|
||||
/* Messages for the authentication agent connection. */
|
||||
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
|
||||
|
@ -76,6 +82,9 @@ int ssh_agent_sign(int sock, const struct sshkey *key,
|
|||
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
|
||||
|
||||
/* generic extension mechanism */
|
||||
#define SSH_AGENTC_EXTENSION 27
|
||||
|
||||
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
#define SSH_AGENT_CONSTRAIN_MAXSIGN 3
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: clientloop.c,v 1.371 2021/11/18 21:32:11 djm Exp $ */
|
||||
/* $OpenBSD: clientloop.c,v 1.372 2021/12/19 22:08:48 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1597,6 +1597,12 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
|
|||
debug_fr(r, "ssh_get_authentication_socket");
|
||||
return NULL;
|
||||
}
|
||||
if ((r = ssh_agent_bind_hostkey(sock, ssh->kex->initial_hostkey,
|
||||
ssh->kex->session_id, ssh->kex->initial_sig, 1)) == 0)
|
||||
debug_f("bound agent to hostkey");
|
||||
else
|
||||
debug2_fr(r, "ssh_agent_bind_hostkey");
|
||||
|
||||
c = channel_new(ssh, "authentication agent connection",
|
||||
SSH_CHANNEL_OPEN, sock, sock, -1,
|
||||
CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshconnect2.c,v 1.351 2021/07/23 05:24:02 djm Exp $ */
|
||||
/* $OpenBSD: sshconnect2.c,v 1.352 2021/12/19 22:08:48 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
|
@ -391,7 +391,7 @@ void userauth(struct ssh *, char *);
|
|||
|
||||
static void pubkey_cleanup(struct ssh *);
|
||||
static int sign_and_send_pubkey(struct ssh *ssh, Identity *);
|
||||
static void pubkey_prepare(Authctxt *);
|
||||
static void pubkey_prepare(struct ssh *, Authctxt *);
|
||||
static void pubkey_reset(Authctxt *);
|
||||
static struct sshkey *load_identity_file(Identity *);
|
||||
|
||||
|
@ -465,7 +465,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
|
|||
authctxt.mech_tried = 0;
|
||||
#endif
|
||||
authctxt.agent_fd = -1;
|
||||
pubkey_prepare(&authctxt);
|
||||
pubkey_prepare(ssh, &authctxt);
|
||||
if (authctxt.method == NULL) {
|
||||
fatal_f("internal error: cannot send userauth none request");
|
||||
}
|
||||
|
@ -1631,6 +1631,36 @@ key_type_allowed_by_config(struct sshkey *key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* obtain a list of keys from the agent */
|
||||
static int
|
||||
get_agent_identities(struct ssh *ssh, int *agent_fdp,
|
||||
struct ssh_identitylist **idlistp)
|
||||
{
|
||||
int r, agent_fd;
|
||||
struct ssh_identitylist *idlist;
|
||||
|
||||
if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
|
||||
if (r != SSH_ERR_AGENT_NOT_PRESENT)
|
||||
debug_fr(r, "ssh_get_authentication_socket");
|
||||
return r;
|
||||
}
|
||||
if ((r = ssh_agent_bind_hostkey(agent_fd, ssh->kex->initial_hostkey,
|
||||
ssh->kex->session_id, ssh->kex->initial_sig, 0)) == 0)
|
||||
debug_f("bound agent to hostkey");
|
||||
else
|
||||
debug2_fr(r, "ssh_agent_bind_hostkey");
|
||||
|
||||
if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) {
|
||||
debug_fr(r, "ssh_fetch_identitylist");
|
||||
close(agent_fd);
|
||||
return r;
|
||||
}
|
||||
/* success */
|
||||
*agent_fdp = agent_fd;
|
||||
*idlistp = idlist;
|
||||
debug_f("agent returned %zu keys", idlist->nkeys);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* try keys in the following order:
|
||||
|
@ -1641,7 +1671,7 @@ key_type_allowed_by_config(struct sshkey *key)
|
|||
* 5. keys that are only listed in the config file
|
||||
*/
|
||||
static void
|
||||
pubkey_prepare(Authctxt *authctxt)
|
||||
pubkey_prepare(struct ssh *ssh, Authctxt *authctxt)
|
||||
{
|
||||
struct identity *id, *id2, *tmp;
|
||||
struct idlist agent, files, *preferred;
|
||||
|
@ -1703,14 +1733,7 @@ pubkey_prepare(Authctxt *authctxt)
|
|||
TAILQ_INSERT_TAIL(preferred, id, next);
|
||||
}
|
||||
/* list of keys supported by the agent */
|
||||
if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
|
||||
if (r != SSH_ERR_AGENT_NOT_PRESENT)
|
||||
debug_fr(r, "ssh_get_authentication_socket");
|
||||
} else if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) {
|
||||
if (r != SSH_ERR_AGENT_NO_IDENTITIES)
|
||||
debug_fr(r, "ssh_fetch_identitylist");
|
||||
close(agent_fd);
|
||||
} else {
|
||||
if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) {
|
||||
for (j = 0; j < idlist->nkeys; j++) {
|
||||
found = 0;
|
||||
TAILQ_FOREACH(id, &files, next) {
|
||||
|
|
Loading…
Reference in New Issue