diff options
author | Colin Watson <cjwatson@debian.org> | 2016-08-06 10:49:59 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2016-08-07 12:18:58 +0100 |
commit | 477bb7636238c106f8cd7c868a8c0c5eabcfb3db (patch) | |
tree | 601176af2ecf358c36b766776a86845ad7a3cd6f /sshconnect2.c | |
parent | 747fac2de0d889183f67f6900194c0462c558544 (diff) | |
parent | 4c914ccd85bbf391c4dc61b85e3c178fef465e3f (diff) |
New upstream release (7.3p1).
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 118 |
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) | |||
554 | int | 553 | int |
555 | input_userauth_banner(int type, u_int32_t seq, void *ctxt) | 554 | input_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 | } |