summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/sshconnect2.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2017-09-02 23:39:51 +0000
committerdes <des@FreeBSD.org>2017-09-02 23:39:51 +0000
commit7e3dcea1a1c17915cbd33fd8fcec2b5530f8d3d1 (patch)
tree0ad6b552b5cee69d3a46a71e4f906a8b18024b1d /crypto/openssh/sshconnect2.c
parentca26403304720e30901aa6f7bde4883af9662d2d (diff)
downloadFreeBSD-src-7e3dcea1a1c17915cbd33fd8fcec2b5530f8d3d1.zip
FreeBSD-src-7e3dcea1a1c17915cbd33fd8fcec2b5530f8d3d1.tar.gz
MFH (r322052): Upgrade OpenSSH to 7.5p1.
Diffstat (limited to 'crypto/openssh/sshconnect2.c')
-rw-r--r--crypto/openssh/sshconnect2.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c
index 103a2b3..f8a54be 100644
--- a/crypto/openssh/sshconnect2.c
+++ b/crypto/openssh/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.251 2016/12/04 23:54:02 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.255 2017/03/11 23:40:26 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -193,8 +193,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
}
if (options.rekey_limit || options.rekey_interval)
- packet_set_rekey_limits((u_int32_t)options.rekey_limit,
- (time_t)options.rekey_interval);
+ packet_set_rekey_limits(options.rekey_limit,
+ options.rekey_interval);
/* start key exchange */
if ((r = kex_setup(active_state, myproposal)) != 0)
@@ -934,14 +934,14 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
Authctxt *authctxt = ctxt;
char *info, *lang, *password = NULL, *retype = NULL;
char prompt[150];
- const char *host = options.host_key_alias ? options.host_key_alias :
- authctxt->host;
+ const char *host;
debug2("input_userauth_passwd_changereq");
if (authctxt == NULL)
fatal("input_userauth_passwd_changereq: "
"no authentication context");
+ host = options.host_key_alias ? options.host_key_alias : authctxt->host;
info = packet_get_string(NULL);
lang = packet_get_string(NULL);
@@ -996,11 +996,11 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
}
static const char *
-identity_sign_encode(struct identity *id)
+key_sign_encode(const struct sshkey *key)
{
struct ssh *ssh = active_state;
- if (id->key->type == KEY_RSA) {
+ if (key->type == KEY_RSA) {
switch (ssh->kex->rsa_sha2) {
case 256:
return "rsa-sha2-256";
@@ -1008,7 +1008,7 @@ identity_sign_encode(struct identity *id)
return "rsa-sha2-512";
}
}
- return key_ssh_name(id->key);
+ return key_ssh_name(key);
}
static int
@@ -1017,31 +1017,50 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
{
Key *prv;
int ret;
- const char *alg;
-
- alg = identity_sign_encode(id);
/* the agent supports this key */
- if (id->agent_fd != -1)
+ if (id->key != NULL && id->agent_fd != -1)
return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
- data, datalen, alg, compat);
+ data, datalen, key_sign_encode(id->key), compat);
/*
* we have already loaded the private key or
* the private key is stored in external hardware
*/
- if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))
- return (sshkey_sign(id->key, sigp, lenp, data, datalen, alg,
- compat));
+ if (id->key != NULL &&
+ (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)))
+ return (sshkey_sign(id->key, sigp, lenp, data, datalen,
+ key_sign_encode(id->key), compat));
+
/* load the private key from the file */
if ((prv = load_identity_file(id)) == NULL)
return SSH_ERR_KEY_NOT_FOUND;
- ret = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat);
+ ret = sshkey_sign(prv, sigp, lenp, data, datalen,
+ key_sign_encode(prv), compat);
sshkey_free(prv);
return (ret);
}
static int
+id_filename_matches(Identity *id, Identity *private_id)
+{
+ const char *suffixes[] = { ".pub", "-cert.pub", NULL };
+ size_t len = strlen(id->filename), plen = strlen(private_id->filename);
+ size_t i, slen;
+
+ if (strcmp(id->filename, private_id->filename) == 0)
+ return 1;
+ for (i = 0; suffixes[i]; i++) {
+ slen = strlen(suffixes[i]);
+ if (len > slen && plen == len - slen &&
+ strcmp(id->filename + (len - slen), suffixes[i]) == 0 &&
+ memcmp(id->filename, private_id->filename, plen) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+static int
sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
{
Buffer b;
@@ -1083,7 +1102,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
} else {
buffer_put_cstring(&b, authctxt->method->name);
buffer_put_char(&b, have_sig);
- buffer_put_cstring(&b, identity_sign_encode(id));
+ buffer_put_cstring(&b, key_sign_encode(id->key));
}
buffer_put_string(&b, blob, bloblen);
@@ -1103,6 +1122,24 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
break;
}
}
+ /*
+ * Exact key matches are preferred, but also allow
+ * filename matches for non-PKCS#11/agent keys that
+ * didn't load public keys. This supports the case
+ * of keeping just a private key file and public
+ * certificate on disk.
+ */
+ if (!matched && !id->isprivate && id->agent_fd == -1 &&
+ (id->key->flags & SSHKEY_FLAG_EXT) == 0) {
+ TAILQ_FOREACH(private_id, &authctxt->keys, next) {
+ if (private_id->key == NULL &&
+ id_filename_matches(id, private_id)) {
+ id = private_id;
+ matched = 1;
+ break;
+ }
+ }
+ }
if (matched) {
debug2("%s: using private key \"%s\"%s for "
"certificate", __func__, id->filename,
@@ -1181,7 +1218,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
packet_put_cstring(authctxt->method->name);
packet_put_char(have_sig);
if (!(datafellows & SSH_BUG_PKAUTH))
- packet_put_cstring(identity_sign_encode(id));
+ packet_put_cstring(key_sign_encode(id->key));
packet_put_string(blob, bloblen);
free(blob);
packet_send();
@@ -1632,7 +1669,7 @@ ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp,
if ((b = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
/* send # of sock, data to be signed */
- if ((r = sshbuf_put_u32(b, sock) != 0) ||
+ if ((r = sshbuf_put_u32(b, sock)) != 0 ||
(r = sshbuf_put_string(b, data, datalen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (ssh_msg_send(to[1], version, b) == -1)
OpenPOWER on IntegriCloud