diff options
author | des <des@FreeBSD.org> | 2017-09-02 23:39:51 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2017-09-02 23:39:51 +0000 |
commit | 7e3dcea1a1c17915cbd33fd8fcec2b5530f8d3d1 (patch) | |
tree | 0ad6b552b5cee69d3a46a71e4f906a8b18024b1d /crypto/openssh/sshconnect2.c | |
parent | ca26403304720e30901aa6f7bde4883af9662d2d (diff) | |
download | FreeBSD-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.c | 77 |
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) |