diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 71 |
1 files changed, 52 insertions, 19 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.334 2010/02/08 22:03:05 jmc Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.335 2010/02/26 20:29:54 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1306,34 +1306,35 @@ load_public_identity_files(void) | |||
1306 | int i = 0; | 1306 | int i = 0; |
1307 | Key *public; | 1307 | Key *public; |
1308 | struct passwd *pw; | 1308 | struct passwd *pw; |
1309 | u_int n_ids; | ||
1310 | char *identity_files[SSH_MAX_IDENTITY_FILES]; | ||
1311 | Key *identity_keys[SSH_MAX_IDENTITY_FILES]; | ||
1309 | #ifdef ENABLE_PKCS11 | 1312 | #ifdef ENABLE_PKCS11 |
1310 | Key **keys; | 1313 | Key **keys; |
1311 | int nkeys; | 1314 | int nkeys; |
1315 | #endif /* PKCS11 */ | ||
1312 | 1316 | ||
1317 | n_ids = 0; | ||
1318 | bzero(identity_files, sizeof(identity_files)); | ||
1319 | bzero(identity_keys, sizeof(identity_keys)); | ||
1320 | |||
1321 | #ifdef ENABLE_PKCS11 | ||
1313 | if (options.pkcs11_provider != NULL && | 1322 | if (options.pkcs11_provider != NULL && |
1314 | options.num_identity_files < SSH_MAX_IDENTITY_FILES && | 1323 | options.num_identity_files < SSH_MAX_IDENTITY_FILES && |
1315 | (pkcs11_init(!options.batch_mode) == 0) && | 1324 | (pkcs11_init(!options.batch_mode) == 0) && |
1316 | (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, | 1325 | (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, |
1317 | &keys)) > 0) { | 1326 | &keys)) > 0) { |
1318 | int count = 0; | ||
1319 | for (i = 0; i < nkeys; i++) { | 1327 | for (i = 0; i < nkeys; i++) { |
1320 | count++; | 1328 | if (n_ids >= SSH_MAX_IDENTITY_FILES) { |
1321 | memmove(&options.identity_files[1], | 1329 | key_free(keys[i]); |
1322 | &options.identity_files[0], | 1330 | continue; |
1323 | sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1)); | 1331 | } |
1324 | memmove(&options.identity_keys[1], | 1332 | identity_keys[n_ids] = keys[i]; |
1325 | &options.identity_keys[0], | 1333 | identity_files[n_ids] = |
1326 | sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); | ||
1327 | options.num_identity_files++; | ||
1328 | options.identity_keys[0] = keys[i]; | ||
1329 | options.identity_files[0] = | ||
1330 | xstrdup(options.pkcs11_provider); /* XXX */ | 1334 | xstrdup(options.pkcs11_provider); /* XXX */ |
1335 | n_ids++; | ||
1331 | } | 1336 | } |
1332 | if (options.num_identity_files > SSH_MAX_IDENTITY_FILES) | ||
1333 | options.num_identity_files = SSH_MAX_IDENTITY_FILES; | ||
1334 | i = count; | ||
1335 | xfree(keys); | 1337 | xfree(keys); |
1336 | /* XXX leaks some keys */ | ||
1337 | } | 1338 | } |
1338 | #endif /* ENABLE_PKCS11 */ | 1339 | #endif /* ENABLE_PKCS11 */ |
1339 | if ((pw = getpwuid(original_real_uid)) == NULL) | 1340 | if ((pw = getpwuid(original_real_uid)) == NULL) |
@@ -1343,7 +1344,11 @@ load_public_identity_files(void) | |||
1343 | if (gethostname(thishost, sizeof(thishost)) == -1) | 1344 | if (gethostname(thishost, sizeof(thishost)) == -1) |
1344 | fatal("load_public_identity_files: gethostname: %s", | 1345 | fatal("load_public_identity_files: gethostname: %s", |
1345 | strerror(errno)); | 1346 | strerror(errno)); |
1346 | for (; i < options.num_identity_files; i++) { | 1347 | for (i = 0; i < options.num_identity_files; i++) { |
1348 | if (n_ids >= SSH_MAX_IDENTITY_FILES) { | ||
1349 | xfree(options.identity_files[i]); | ||
1350 | continue; | ||
1351 | } | ||
1347 | cp = tilde_expand_filename(options.identity_files[i], | 1352 | cp = tilde_expand_filename(options.identity_files[i], |
1348 | original_real_uid); | 1353 | original_real_uid); |
1349 | filename = percent_expand(cp, "d", pwdir, | 1354 | filename = percent_expand(cp, "d", pwdir, |
@@ -1354,9 +1359,37 @@ load_public_identity_files(void) | |||
1354 | debug("identity file %s type %d", filename, | 1359 | debug("identity file %s type %d", filename, |
1355 | public ? public->type : -1); | 1360 | public ? public->type : -1); |
1356 | xfree(options.identity_files[i]); | 1361 | xfree(options.identity_files[i]); |
1357 | options.identity_files[i] = filename; | 1362 | identity_files[n_ids] = filename; |
1358 | options.identity_keys[i] = public; | 1363 | identity_keys[n_ids] = public; |
1364 | |||
1365 | if (++n_ids >= SSH_MAX_IDENTITY_FILES) | ||
1366 | continue; | ||
1367 | |||
1368 | /* Try to add the certificate variant too */ | ||
1369 | xasprintf(&cp, "%s-cert", filename); | ||
1370 | public = key_load_public(cp, NULL); | ||
1371 | debug("identity file %s type %d", cp, | ||
1372 | public ? public->type : -1); | ||
1373 | if (public == NULL) { | ||
1374 | xfree(cp); | ||
1375 | continue; | ||
1376 | } | ||
1377 | if (!key_is_cert(public)) { | ||
1378 | debug("%s: key %s type %s is not a certificate", | ||
1379 | __func__, cp, key_type(public)); | ||
1380 | key_free(public); | ||
1381 | xfree(cp); | ||
1382 | continue; | ||
1383 | } | ||
1384 | identity_keys[n_ids] = public; | ||
1385 | /* point to the original path, most likely the private key */ | ||
1386 | identity_files[n_ids] = xstrdup(filename); | ||
1387 | n_ids++; | ||
1359 | } | 1388 | } |
1389 | options.num_identity_files = n_ids; | ||
1390 | memcpy(options.identity_files, identity_files, sizeof(identity_files)); | ||
1391 | memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); | ||
1392 | |||
1360 | bzero(pwname, strlen(pwname)); | 1393 | bzero(pwname, strlen(pwname)); |
1361 | xfree(pwname); | 1394 | xfree(pwname); |
1362 | bzero(pwdir, strlen(pwdir)); | 1395 | bzero(pwdir, strlen(pwdir)); |