summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2016-08-06 10:49:59 +0100
committerColin Watson <cjwatson@debian.org>2016-08-07 12:18:58 +0100
commit477bb7636238c106f8cd7c868a8c0c5eabcfb3db (patch)
tree601176af2ecf358c36b766776a86845ad7a3cd6f /sshconnect2.c
parent747fac2de0d889183f67f6900194c0462c558544 (diff)
parent4c914ccd85bbf391c4dc61b85e3c178fef465e3f (diff)
New upstream release (7.3p1).
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c118
1 files changed, 57 insertions, 61 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 40facdab5..34b9d304e 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.240 2016/03/14 16:20:54 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.247 2016/07/22 05:46:11 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -71,6 +71,7 @@
71#include "uidswap.h" 71#include "uidswap.h"
72#include "hostfile.h" 72#include "hostfile.h"
73#include "ssherr.h" 73#include "ssherr.h"
74#include "utf8.h"
74 75
75#ifdef GSSAPI 76#ifdef GSSAPI
76#include "ssh-gss.h" 77#include "ssh-gss.h"
@@ -176,13 +177,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
176 compat_cipher_proposal(options.ciphers); 177 compat_cipher_proposal(options.ciphers);
177 myproposal[PROPOSAL_ENC_ALGS_STOC] = 178 myproposal[PROPOSAL_ENC_ALGS_STOC] =
178 compat_cipher_proposal(options.ciphers); 179 compat_cipher_proposal(options.ciphers);
179 if (options.compression) { 180 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
180 myproposal[PROPOSAL_COMP_ALGS_CTOS] = 181 myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ?
181 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none"; 182 "zlib@openssh.com,zlib,none" : "none,zlib@openssh.com,zlib";
182 } else {
183 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
184 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib";
185 }
186 myproposal[PROPOSAL_MAC_ALGS_CTOS] = 183 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
187 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 184 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
188 if (options.hostkeyalgorithms != NULL) { 185 if (options.hostkeyalgorithms != NULL) {
@@ -206,12 +203,15 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
206 * client to the key exchange algorithm proposal */ 203 * client to the key exchange algorithm proposal */
207 orig = myproposal[PROPOSAL_KEX_ALGS]; 204 orig = myproposal[PROPOSAL_KEX_ALGS];
208 205
209 if (options.gss_trust_dns) 206 if (options.gss_server_identity)
210 gss_host = (char *)get_canonical_hostname(1); 207 gss_host = xstrdup(options.gss_server_identity);
208 else if (options.gss_trust_dns)
209 gss_host = remote_hostname(active_state);
211 else 210 else
212 gss_host = host; 211 gss_host = xstrdup(host);
213 212
214 gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); 213 gss = ssh_gssapi_client_mechanisms(gss_host,
214 options.gss_client_identity);
215 if (gss) { 215 if (gss) {
216 debug("Offering GSSAPI proposal: %s", gss); 216 debug("Offering GSSAPI proposal: %s", gss);
217 xasprintf(&myproposal[PROPOSAL_KEX_ALGS], 217 xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
@@ -238,6 +238,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
238#ifdef WITH_OPENSSL 238#ifdef WITH_OPENSSL
239 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; 239 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
240 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 240 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
241 kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client;
242 kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client;
243 kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client;
241 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 244 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
242 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 245 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
243# ifdef OPENSSL_HAS_ECC 246# ifdef OPENSSL_HAS_ECC
@@ -261,11 +264,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
261 kex->gss_deleg_creds = options.gss_deleg_creds; 264 kex->gss_deleg_creds = options.gss_deleg_creds;
262 kex->gss_trust_dns = options.gss_trust_dns; 265 kex->gss_trust_dns = options.gss_trust_dns;
263 kex->gss_client = options.gss_client_identity; 266 kex->gss_client = options.gss_client_identity;
264 if (options.gss_server_identity) { 267 kex->gss_host = gss_host;
265 kex->gss_host = options.gss_server_identity;
266 } else {
267 kex->gss_host = gss_host;
268 }
269 } 268 }
270#endif 269#endif
271 270
@@ -554,21 +553,15 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
554int 553int
555input_userauth_banner(int type, u_int32_t seq, void *ctxt) 554input_userauth_banner(int type, u_int32_t seq, void *ctxt)
556{ 555{
557 char *msg, *raw, *lang; 556 char *msg, *lang;
558 u_int len; 557 u_int len;
559 558
560 debug3("input_userauth_banner"); 559 debug3("%s", __func__);
561 raw = packet_get_string(&len); 560 msg = packet_get_string(&len);
562 lang = packet_get_string(NULL); 561 lang = packet_get_string(NULL);
563 if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { 562 if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO)
564 if (len > 65536) 563 fmprintf(stderr, "%s", msg);
565 len = 65536; 564 free(msg);
566 msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
567 strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
568 fprintf(stderr, "%s", msg);
569 free(msg);
570 }
571 free(raw);
572 free(lang); 565 free(lang);
573 return 0; 566 return 0;
574} 567}
@@ -620,7 +613,7 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
620 packet_check_eom(); 613 packet_check_eom();
621 614
622 if (partial != 0) { 615 if (partial != 0) {
623 logit("Authenticated with partial success."); 616 verbose("Authenticated with partial success.");
624 /* reset state */ 617 /* reset state */
625 pubkey_cleanup(authctxt); 618 pubkey_cleanup(authctxt);
626 pubkey_prepare(authctxt); 619 pubkey_prepare(authctxt);
@@ -714,14 +707,14 @@ userauth_gssapi(Authctxt *authctxt)
714 static u_int mech = 0; 707 static u_int mech = 0;
715 OM_uint32 min; 708 OM_uint32 min;
716 int ok = 0; 709 int ok = 0;
717 const char *gss_host; 710 char *gss_host;
718 711
719 if (options.gss_server_identity) 712 if (options.gss_server_identity)
720 gss_host = options.gss_server_identity; 713 gss_host = xstrdup(options.gss_server_identity);
721 else if (options.gss_trust_dns) 714 else if (options.gss_trust_dns)
722 gss_host = get_canonical_hostname(1); 715 gss_host = remote_hostname(active_state);
723 else 716 else
724 gss_host = authctxt->host; 717 gss_host = xstrdup(authctxt->host);
725 718
726 /* Try one GSSAPI method at a time, rather than sending them all at 719 /* Try one GSSAPI method at a time, rather than sending them all at
727 * once. */ 720 * once. */
@@ -729,6 +722,7 @@ userauth_gssapi(Authctxt *authctxt)
729 if (gss_supported == NULL) 722 if (gss_supported == NULL)
730 if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) { 723 if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) {
731 gss_supported = NULL; 724 gss_supported = NULL;
725 free(gss_host);
732 return 0; 726 return 0;
733 } 727 }
734 728
@@ -745,6 +739,8 @@ userauth_gssapi(Authctxt *authctxt)
745 } 739 }
746 } 740 }
747 741
742 free(gss_host);
743
748 if (!ok) 744 if (!ok)
749 return 0; 745 return 0;
750 746
@@ -1206,8 +1202,8 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1206 /* 1202 /*
1207 * If the key is an certificate, try to find a matching private key 1203 * If the key is an certificate, try to find a matching private key
1208 * and use it to complete the signature. 1204 * and use it to complete the signature.
1209 * If no such private key exists, return failure and continue with 1205 * If no such private key exists, fall back to trying the certificate
1210 * other methods of authentication. 1206 * key itself in case it has a private half already loaded.
1211 */ 1207 */
1212 if (key_is_cert(id->key)) { 1208 if (key_is_cert(id->key)) {
1213 matched = 0; 1209 matched = 0;
@@ -1408,29 +1404,6 @@ pubkey_prepare(Authctxt *authctxt)
1408 id->userprovided = options.identity_file_userprovided[i]; 1404 id->userprovided = options.identity_file_userprovided[i];
1409 TAILQ_INSERT_TAIL(&files, id, next); 1405 TAILQ_INSERT_TAIL(&files, id, next);
1410 } 1406 }
1411 /* Prefer PKCS11 keys that are explicitly listed */
1412 TAILQ_FOREACH_SAFE(id, &files, next, tmp) {
1413 if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0)
1414 continue;
1415 found = 0;
1416 TAILQ_FOREACH(id2, &files, next) {
1417 if (id2->key == NULL ||
1418 (id2->key->flags & SSHKEY_FLAG_EXT) == 0)
1419 continue;
1420 if (sshkey_equal(id->key, id2->key)) {
1421 TAILQ_REMOVE(&files, id, next);
1422 TAILQ_INSERT_TAIL(preferred, id, next);
1423 found = 1;
1424 break;
1425 }
1426 }
1427 /* If IdentitiesOnly set and key not found then don't use it */
1428 if (!found && options.identities_only) {
1429 TAILQ_REMOVE(&files, id, next);
1430 explicit_bzero(id, sizeof(*id));
1431 free(id);
1432 }
1433 }
1434 /* list of certificates specified by user */ 1407 /* list of certificates specified by user */
1435 for (i = 0; i < options.num_certificate_files; i++) { 1408 for (i = 0; i < options.num_certificate_files; i++) {
1436 key = options.certificates[i]; 1409 key = options.certificates[i];
@@ -1489,6 +1462,29 @@ pubkey_prepare(Authctxt *authctxt)
1489 } 1462 }
1490 authctxt->agent_fd = agent_fd; 1463 authctxt->agent_fd = agent_fd;
1491 } 1464 }
1465 /* Prefer PKCS11 keys that are explicitly listed */
1466 TAILQ_FOREACH_SAFE(id, &files, next, tmp) {
1467 if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0)
1468 continue;
1469 found = 0;
1470 TAILQ_FOREACH(id2, &files, next) {
1471 if (id2->key == NULL ||
1472 (id2->key->flags & SSHKEY_FLAG_EXT) == 0)
1473 continue;
1474 if (sshkey_equal(id->key, id2->key)) {
1475 TAILQ_REMOVE(&files, id, next);
1476 TAILQ_INSERT_TAIL(preferred, id, next);
1477 found = 1;
1478 break;
1479 }
1480 }
1481 /* If IdentitiesOnly set and key not found then don't use it */
1482 if (!found && options.identities_only) {
1483 TAILQ_REMOVE(&files, id, next);
1484 explicit_bzero(id, sizeof(*id));
1485 free(id);
1486 }
1487 }
1492 /* append remaining keys from the config file */ 1488 /* append remaining keys from the config file */
1493 for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) { 1489 for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {
1494 TAILQ_REMOVE(&files, id, next); 1490 TAILQ_REMOVE(&files, id, next);
@@ -2034,8 +2030,8 @@ authmethods_get(void)
2034 buffer_append(&b, method->name, strlen(method->name)); 2030 buffer_append(&b, method->name, strlen(method->name));
2035 } 2031 }
2036 } 2032 }
2037 buffer_append(&b, "\0", 1); 2033 if ((list = sshbuf_dup_string(&b)) == NULL)
2038 list = xstrdup(buffer_ptr(&b)); 2034 fatal("%s: sshbuf_dup_string failed", __func__);
2039 buffer_free(&b); 2035 buffer_free(&b);
2040 return list; 2036 return list;
2041} 2037}