summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c96
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)
496int 496int
497input_userauth_banner(int type, u_int32_t seq, void *ctxt) 497input_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}