diff options
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 96 |
1 files changed, 43 insertions, 53 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index f79c96beb..fae8b0f2c 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.239 2016/02/23 01:34:14 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" |
@@ -171,13 +172,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | |||
171 | compat_cipher_proposal(options.ciphers); | 172 | compat_cipher_proposal(options.ciphers); |
172 | myproposal[PROPOSAL_ENC_ALGS_STOC] = | 173 | myproposal[PROPOSAL_ENC_ALGS_STOC] = |
173 | compat_cipher_proposal(options.ciphers); | 174 | compat_cipher_proposal(options.ciphers); |
174 | if (options.compression) { | 175 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = |
175 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = | 176 | myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ? |
176 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none"; | 177 | "zlib@openssh.com,zlib,none" : "none,zlib@openssh.com,zlib"; |
177 | } else { | ||
178 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = | ||
179 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib"; | ||
180 | } | ||
181 | myproposal[PROPOSAL_MAC_ALGS_CTOS] = | 178 | myproposal[PROPOSAL_MAC_ALGS_CTOS] = |
182 | myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; | 179 | myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; |
183 | if (options.hostkeyalgorithms != NULL) { | 180 | if (options.hostkeyalgorithms != NULL) { |
@@ -206,6 +203,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | |||
206 | #ifdef WITH_OPENSSL | 203 | #ifdef WITH_OPENSSL |
207 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; | 204 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; |
208 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; | 205 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; |
206 | kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client; | ||
207 | kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; | ||
208 | kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client; | ||
209 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | 209 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
210 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; | 210 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; |
211 | # ifdef OPENSSL_HAS_ECC | 211 | # ifdef OPENSSL_HAS_ECC |
@@ -496,21 +496,15 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt) | |||
496 | int | 496 | int |
497 | input_userauth_banner(int type, u_int32_t seq, void *ctxt) | 497 | input_userauth_banner(int type, u_int32_t seq, void *ctxt) |
498 | { | 498 | { |
499 | char *msg, *raw, *lang; | 499 | char *msg, *lang; |
500 | u_int len; | 500 | u_int len; |
501 | 501 | ||
502 | debug3("input_userauth_banner"); | 502 | debug3("%s", __func__); |
503 | raw = packet_get_string(&len); | 503 | msg = packet_get_string(&len); |
504 | lang = packet_get_string(NULL); | 504 | lang = packet_get_string(NULL); |
505 | if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { | 505 | if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) |
506 | if (len > 65536) | 506 | fmprintf(stderr, "%s", msg); |
507 | len = 65536; | 507 | free(msg); |
508 | msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ | ||
509 | strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); | ||
510 | fprintf(stderr, "%s", msg); | ||
511 | free(msg); | ||
512 | } | ||
513 | free(raw); | ||
514 | free(lang); | 508 | free(lang); |
515 | return 0; | 509 | return 0; |
516 | } | 510 | } |
@@ -562,7 +556,7 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt) | |||
562 | packet_check_eom(); | 556 | packet_check_eom(); |
563 | 557 | ||
564 | if (partial != 0) { | 558 | if (partial != 0) { |
565 | logit("Authenticated with partial success."); | 559 | verbose("Authenticated with partial success."); |
566 | /* reset state */ | 560 | /* reset state */ |
567 | pubkey_cleanup(authctxt); | 561 | pubkey_cleanup(authctxt); |
568 | pubkey_prepare(authctxt); | 562 | pubkey_prepare(authctxt); |
@@ -1094,8 +1088,8 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) | |||
1094 | /* | 1088 | /* |
1095 | * If the key is an certificate, try to find a matching private key | 1089 | * If the key is an certificate, try to find a matching private key |
1096 | * and use it to complete the signature. | 1090 | * and use it to complete the signature. |
1097 | * If no such private key exists, return failure and continue with | 1091 | * If no such private key exists, fall back to trying the certificate |
1098 | * other methods of authentication. | 1092 | * key itself in case it has a private half already loaded. |
1099 | */ | 1093 | */ |
1100 | if (key_is_cert(id->key)) { | 1094 | if (key_is_cert(id->key)) { |
1101 | matched = 0; | 1095 | matched = 0; |
@@ -1112,12 +1106,8 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) | |||
1112 | "certificate", __func__, id->filename, | 1106 | "certificate", __func__, id->filename, |
1113 | id->agent_fd != -1 ? " from agent" : ""); | 1107 | id->agent_fd != -1 ? " from agent" : ""); |
1114 | } else { | 1108 | } else { |
1115 | /* XXX maybe verbose/error? */ | 1109 | debug("%s: no separate private key for certificate " |
1116 | debug("%s: no private key for certificate " | ||
1117 | "\"%s\"", __func__, id->filename); | 1110 | "\"%s\"", __func__, id->filename); |
1118 | free(blob); | ||
1119 | buffer_free(&b); | ||
1120 | return 0; | ||
1121 | } | 1111 | } |
1122 | } | 1112 | } |
1123 | 1113 | ||
@@ -1300,29 +1290,6 @@ pubkey_prepare(Authctxt *authctxt) | |||
1300 | id->userprovided = options.identity_file_userprovided[i]; | 1290 | id->userprovided = options.identity_file_userprovided[i]; |
1301 | TAILQ_INSERT_TAIL(&files, id, next); | 1291 | TAILQ_INSERT_TAIL(&files, id, next); |
1302 | } | 1292 | } |
1303 | /* Prefer PKCS11 keys that are explicitly listed */ | ||
1304 | TAILQ_FOREACH_SAFE(id, &files, next, tmp) { | ||
1305 | if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0) | ||
1306 | continue; | ||
1307 | found = 0; | ||
1308 | TAILQ_FOREACH(id2, &files, next) { | ||
1309 | if (id2->key == NULL || | ||
1310 | (id2->key->flags & SSHKEY_FLAG_EXT) == 0) | ||
1311 | continue; | ||
1312 | if (sshkey_equal(id->key, id2->key)) { | ||
1313 | TAILQ_REMOVE(&files, id, next); | ||
1314 | TAILQ_INSERT_TAIL(preferred, id, next); | ||
1315 | found = 1; | ||
1316 | break; | ||
1317 | } | ||
1318 | } | ||
1319 | /* If IdentitiesOnly set and key not found then don't use it */ | ||
1320 | if (!found && options.identities_only) { | ||
1321 | TAILQ_REMOVE(&files, id, next); | ||
1322 | explicit_bzero(id, sizeof(*id)); | ||
1323 | free(id); | ||
1324 | } | ||
1325 | } | ||
1326 | /* list of certificates specified by user */ | 1293 | /* list of certificates specified by user */ |
1327 | for (i = 0; i < options.num_certificate_files; i++) { | 1294 | for (i = 0; i < options.num_certificate_files; i++) { |
1328 | key = options.certificates[i]; | 1295 | key = options.certificates[i]; |
@@ -1381,6 +1348,29 @@ pubkey_prepare(Authctxt *authctxt) | |||
1381 | } | 1348 | } |
1382 | authctxt->agent_fd = agent_fd; | 1349 | authctxt->agent_fd = agent_fd; |
1383 | } | 1350 | } |
1351 | /* Prefer PKCS11 keys that are explicitly listed */ | ||
1352 | TAILQ_FOREACH_SAFE(id, &files, next, tmp) { | ||
1353 | if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0) | ||
1354 | continue; | ||
1355 | found = 0; | ||
1356 | TAILQ_FOREACH(id2, &files, next) { | ||
1357 | if (id2->key == NULL || | ||
1358 | (id2->key->flags & SSHKEY_FLAG_EXT) == 0) | ||
1359 | continue; | ||
1360 | if (sshkey_equal(id->key, id2->key)) { | ||
1361 | TAILQ_REMOVE(&files, id, next); | ||
1362 | TAILQ_INSERT_TAIL(preferred, id, next); | ||
1363 | found = 1; | ||
1364 | break; | ||
1365 | } | ||
1366 | } | ||
1367 | /* If IdentitiesOnly set and key not found then don't use it */ | ||
1368 | if (!found && options.identities_only) { | ||
1369 | TAILQ_REMOVE(&files, id, next); | ||
1370 | explicit_bzero(id, sizeof(*id)); | ||
1371 | free(id); | ||
1372 | } | ||
1373 | } | ||
1384 | /* append remaining keys from the config file */ | 1374 | /* append remaining keys from the config file */ |
1385 | for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) { | 1375 | for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) { |
1386 | TAILQ_REMOVE(&files, id, next); | 1376 | TAILQ_REMOVE(&files, id, next); |
@@ -1926,8 +1916,8 @@ authmethods_get(void) | |||
1926 | buffer_append(&b, method->name, strlen(method->name)); | 1916 | buffer_append(&b, method->name, strlen(method->name)); |
1927 | } | 1917 | } |
1928 | } | 1918 | } |
1929 | buffer_append(&b, "\0", 1); | 1919 | if ((list = sshbuf_dup_string(&b)) == NULL) |
1930 | list = xstrdup(buffer_ptr(&b)); | 1920 | fatal("%s: sshbuf_dup_string failed", __func__); |
1931 | buffer_free(&b); | 1921 | buffer_free(&b); |
1932 | return list; | 1922 | return list; |
1933 | } | 1923 | } |