summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2020-02-21 11:57:14 +0000
committerColin Watson <cjwatson@debian.org>2020-02-21 11:57:14 +0000
commitf0de78bd4f29fa688c5df116f3f9cd43543a76d0 (patch)
tree856b0dee3f2764c13a32dad5ffe2424fab7fef41 /ssh-agent.c
parent4213eec74e74de6310c27a40c3e9759a08a73996 (diff)
parent8aa3455b16fddea4c0144a7c4a1edb10ec67dcc8 (diff)
Import openssh_8.2p1.orig.tar.gz
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c152
1 files changed, 123 insertions, 29 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index 9c6680a25..7eb6f0dc5 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.237 2019/06/28 13:35:04 deraadt Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.255 2020/02/06 22:30:54 naddy 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
@@ -41,6 +41,7 @@
41#include <sys/resource.h> 41#include <sys/resource.h>
42#include <sys/stat.h> 42#include <sys/stat.h>
43#include <sys/socket.h> 43#include <sys/socket.h>
44#include <sys/wait.h>
44#ifdef HAVE_SYS_TIME_H 45#ifdef HAVE_SYS_TIME_H
45# include <sys/time.h> 46# include <sys/time.h>
46#endif 47#endif
@@ -85,13 +86,14 @@
85#include "digest.h" 86#include "digest.h"
86#include "ssherr.h" 87#include "ssherr.h"
87#include "match.h" 88#include "match.h"
88 89#include "msg.h"
89#ifdef ENABLE_PKCS11 90#include "ssherr.h"
91#include "pathnames.h"
90#include "ssh-pkcs11.h" 92#include "ssh-pkcs11.h"
91#endif 93#include "sk-api.h"
92 94
93#ifndef DEFAULT_PKCS11_WHITELIST 95#ifndef DEFAULT_PROVIDER_WHITELIST
94# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*" 96# define DEFAULT_PROVIDER_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"
95#endif 97#endif
96 98
97/* Maximum accepted message length */ 99/* Maximum accepted message length */
@@ -123,6 +125,7 @@ typedef struct identity {
123 char *provider; 125 char *provider;
124 time_t death; 126 time_t death;
125 u_int confirm; 127 u_int confirm;
128 char *sk_provider;
126} Identity; 129} Identity;
127 130
128struct idtable { 131struct idtable {
@@ -146,8 +149,8 @@ pid_t cleanup_pid = 0;
146char socket_name[PATH_MAX]; 149char socket_name[PATH_MAX];
147char socket_dir[PATH_MAX]; 150char socket_dir[PATH_MAX];
148 151
149/* PKCS#11 path whitelist */ 152/* PKCS#11/Security key path whitelist */
150static char *pkcs11_whitelist; 153static char *provider_whitelist;
151 154
152/* locking */ 155/* locking */
153#define LOCK_SIZE 32 156#define LOCK_SIZE 32
@@ -189,6 +192,7 @@ free_identity(Identity *id)
189 sshkey_free(id->key); 192 sshkey_free(id->key);
190 free(id->provider); 193 free(id->provider);
191 free(id->comment); 194 free(id->comment);
195 free(id->sk_provider);
192 free(id); 196 free(id);
193} 197}
194 198
@@ -287,9 +291,11 @@ process_sign_request2(SocketEntry *e)
287 size_t dlen, slen = 0; 291 size_t dlen, slen = 0;
288 u_int compat = 0, flags; 292 u_int compat = 0, flags;
289 int r, ok = -1; 293 int r, ok = -1;
294 char *fp = NULL;
290 struct sshbuf *msg; 295 struct sshbuf *msg;
291 struct sshkey *key = NULL; 296 struct sshkey *key = NULL;
292 struct identity *id; 297 struct identity *id;
298 struct notifier_ctx *notifier = NULL;
293 299
294 if ((msg = sshbuf_new()) == NULL) 300 if ((msg = sshbuf_new()) == NULL)
295 fatal("%s: sshbuf_new failed", __func__); 301 fatal("%s: sshbuf_new failed", __func__);
@@ -308,15 +314,27 @@ process_sign_request2(SocketEntry *e)
308 verbose("%s: user refused key", __func__); 314 verbose("%s: user refused key", __func__);
309 goto send; 315 goto send;
310 } 316 }
317 if (sshkey_is_sk(id->key) &&
318 (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
319 if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
320 SSH_FP_DEFAULT)) == NULL)
321 fatal("%s: fingerprint failed", __func__);
322 notifier = notify_start(0,
323 "Confirm user presence for key %s %s",
324 sshkey_type(id->key), fp);
325 }
311 if ((r = sshkey_sign(id->key, &signature, &slen, 326 if ((r = sshkey_sign(id->key, &signature, &slen,
312 data, dlen, agent_decode_alg(key, flags), compat)) != 0) { 327 data, dlen, agent_decode_alg(key, flags),
328 id->sk_provider, compat)) != 0) {
313 error("%s: sshkey_sign: %s", __func__, ssh_err(r)); 329 error("%s: sshkey_sign: %s", __func__, ssh_err(r));
314 goto send; 330 goto send;
315 } 331 }
316 /* Success */ 332 /* Success */
317 ok = 0; 333 ok = 0;
318 send: 334 send:
335 notify_complete(notifier);
319 sshkey_free(key); 336 sshkey_free(key);
337 free(fp);
320 if (ok == 0) { 338 if (ok == 0) {
321 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 || 339 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
322 (r = sshbuf_put_string(msg, signature, slen)) != 0) 340 (r = sshbuf_put_string(msg, signature, slen)) != 0)
@@ -411,7 +429,8 @@ process_add_identity(SocketEntry *e)
411 Identity *id; 429 Identity *id;
412 int success = 0, confirm = 0; 430 int success = 0, confirm = 0;
413 u_int seconds, maxsign; 431 u_int seconds, maxsign;
414 char *comment = NULL; 432 char *fp, *comment = NULL, *ext_name = NULL, *sk_provider = NULL;
433 char canonical_provider[PATH_MAX];
415 time_t death = 0; 434 time_t death = 0;
416 struct sshkey *k = NULL; 435 struct sshkey *k = NULL;
417 u_char ctype; 436 u_char ctype;
@@ -423,10 +442,6 @@ process_add_identity(SocketEntry *e)
423 error("%s: decode private key: %s", __func__, ssh_err(r)); 442 error("%s: decode private key: %s", __func__, ssh_err(r));
424 goto err; 443 goto err;
425 } 444 }
426 if ((r = sshkey_shield_private(k)) != 0) {
427 error("%s: shield private key: %s", __func__, ssh_err(r));
428 goto err;
429 }
430 while (sshbuf_len(e->request)) { 445 while (sshbuf_len(e->request)) {
431 if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) { 446 if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) {
432 error("%s: buffer error: %s", __func__, ssh_err(r)); 447 error("%s: buffer error: %s", __func__, ssh_err(r));
@@ -456,15 +471,75 @@ process_add_identity(SocketEntry *e)
456 goto err; 471 goto err;
457 } 472 }
458 break; 473 break;
474 case SSH_AGENT_CONSTRAIN_EXTENSION:
475 if ((r = sshbuf_get_cstring(e->request,
476 &ext_name, NULL)) != 0) {
477 error("%s: cannot parse extension: %s",
478 __func__, ssh_err(r));
479 goto err;
480 }
481 debug("%s: constraint ext %s", __func__, ext_name);
482 if (strcmp(ext_name, "sk-provider@openssh.com") == 0) {
483 if (sk_provider != NULL) {
484 error("%s already set", ext_name);
485 goto err;
486 }
487 if ((r = sshbuf_get_cstring(e->request,
488 &sk_provider, NULL)) != 0) {
489 error("%s: cannot parse %s: %s",
490 __func__, ext_name, ssh_err(r));
491 goto err;
492 }
493 } else {
494 error("%s: unsupported constraint \"%s\"",
495 __func__, ext_name);
496 goto err;
497 }
498 free(ext_name);
499 break;
459 default: 500 default:
460 error("%s: Unknown constraint %d", __func__, ctype); 501 error("%s: Unknown constraint %d", __func__, ctype);
461 err: 502 err:
503 free(sk_provider);
504 free(ext_name);
462 sshbuf_reset(e->request); 505 sshbuf_reset(e->request);
463 free(comment); 506 free(comment);
464 sshkey_free(k); 507 sshkey_free(k);
465 goto send; 508 goto send;
466 } 509 }
467 } 510 }
511 if (sk_provider != NULL) {
512 if (!sshkey_is_sk(k)) {
513 error("Cannot add provider: %s is not an "
514 "authenticator-hosted key", sshkey_type(k));
515 free(sk_provider);
516 goto send;
517 }
518 if (strcasecmp(sk_provider, "internal") == 0) {
519 debug("%s: internal provider", __func__);
520 } else {
521 if (realpath(sk_provider, canonical_provider) == NULL) {
522 verbose("failed provider \"%.100s\": "
523 "realpath: %s", sk_provider,
524 strerror(errno));
525 free(sk_provider);
526 goto send;
527 }
528 free(sk_provider);
529 sk_provider = xstrdup(canonical_provider);
530 if (match_pattern_list(sk_provider,
531 provider_whitelist, 0) != 1) {
532 error("Refusing add key: "
533 "provider %s not whitelisted", sk_provider);
534 free(sk_provider);
535 goto send;
536 }
537 }
538 }
539 if ((r = sshkey_shield_private(k)) != 0) {
540 error("%s: shield private key: %s", __func__, ssh_err(r));
541 goto err;
542 }
468 543
469 success = 1; 544 success = 1;
470 if (lifetime && !death) 545 if (lifetime && !death)
@@ -478,11 +553,21 @@ process_add_identity(SocketEntry *e)
478 /* key state might have been updated */ 553 /* key state might have been updated */
479 sshkey_free(id->key); 554 sshkey_free(id->key);
480 free(id->comment); 555 free(id->comment);
556 free(id->sk_provider);
481 } 557 }
482 id->key = k; 558 id->key = k;
483 id->comment = comment; 559 id->comment = comment;
484 id->death = death; 560 id->death = death;
485 id->confirm = confirm; 561 id->confirm = confirm;
562 id->sk_provider = sk_provider;
563
564 if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT,
565 SSH_FP_DEFAULT)) == NULL)
566 fatal("%s: sshkey_fingerprint failed", __func__);
567 debug("%s: add %s %s \"%.100s\" (life: %u) (confirm: %u) "
568 "(provider: %s)", __func__, sshkey_ssh_name(k), fp, comment,
569 seconds, confirm, sk_provider == NULL ? "none" : sk_provider);
570 free(fp);
486send: 571send:
487 send_status(e, success); 572 send_status(e, success);
488} 573}
@@ -560,6 +645,7 @@ static void
560process_add_smartcard_key(SocketEntry *e) 645process_add_smartcard_key(SocketEntry *e)
561{ 646{
562 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; 647 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
648 char **comments = NULL;
563 int r, i, count = 0, success = 0, confirm = 0; 649 int r, i, count = 0, success = 0, confirm = 0;
564 u_int seconds; 650 u_int seconds;
565 time_t death = 0; 651 time_t death = 0;
@@ -600,7 +686,7 @@ process_add_smartcard_key(SocketEntry *e)
600 provider, strerror(errno)); 686 provider, strerror(errno));
601 goto send; 687 goto send;
602 } 688 }
603 if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { 689 if (match_pattern_list(canonical_provider, provider_whitelist, 0) != 1) {
604 verbose("refusing PKCS#11 add of \"%.100s\": " 690 verbose("refusing PKCS#11 add of \"%.100s\": "
605 "provider not whitelisted", canonical_provider); 691 "provider not whitelisted", canonical_provider);
606 goto send; 692 goto send;
@@ -609,28 +695,34 @@ process_add_smartcard_key(SocketEntry *e)
609 if (lifetime && !death) 695 if (lifetime && !death)
610 death = monotime() + lifetime; 696 death = monotime() + lifetime;
611 697
612 count = pkcs11_add_provider(canonical_provider, pin, &keys); 698 count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments);
613 for (i = 0; i < count; i++) { 699 for (i = 0; i < count; i++) {
614 k = keys[i]; 700 k = keys[i];
615 if (lookup_identity(k) == NULL) { 701 if (lookup_identity(k) == NULL) {
616 id = xcalloc(1, sizeof(Identity)); 702 id = xcalloc(1, sizeof(Identity));
617 id->key = k; 703 id->key = k;
704 keys[i] = NULL; /* transferred */
618 id->provider = xstrdup(canonical_provider); 705 id->provider = xstrdup(canonical_provider);
619 id->comment = xstrdup(canonical_provider); /* XXX */ 706 if (*comments[i] != '\0') {
707 id->comment = comments[i];
708 comments[i] = NULL; /* transferred */
709 } else {
710 id->comment = xstrdup(canonical_provider);
711 }
620 id->death = death; 712 id->death = death;
621 id->confirm = confirm; 713 id->confirm = confirm;
622 TAILQ_INSERT_TAIL(&idtab->idlist, id, next); 714 TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
623 idtab->nentries++; 715 idtab->nentries++;
624 success = 1; 716 success = 1;
625 } else {
626 sshkey_free(k);
627 } 717 }
628 keys[i] = NULL; 718 sshkey_free(keys[i]);
719 free(comments[i]);
629 } 720 }
630send: 721send:
631 free(pin); 722 free(pin);
632 free(provider); 723 free(provider);
633 free(keys); 724 free(keys);
725 free(comments);
634 send_status(e, success); 726 send_status(e, success);
635} 727}
636 728
@@ -1079,7 +1171,7 @@ usage(void)
1079{ 1171{
1080 fprintf(stderr, 1172 fprintf(stderr,
1081 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" 1173 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
1082 " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n" 1174 " [-P provider_whitelist] [-t life] [command [arg ...]]\n"
1083 " ssh-agent [-c | -s] -k\n"); 1175 " ssh-agent [-c | -s] -k\n");
1084 exit(1); 1176 exit(1);
1085} 1177}
@@ -1113,8 +1205,10 @@ main(int ac, char **av)
1113 1205
1114 platform_disable_tracing(0); /* strict=no */ 1206 platform_disable_tracing(0); /* strict=no */
1115 1207
1208#ifdef RLIMIT_NOFILE
1116 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) 1209 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
1117 fatal("%s: getrlimit: %s", __progname, strerror(errno)); 1210 fatal("%s: getrlimit: %s", __progname, strerror(errno));
1211#endif
1118 1212
1119 __progname = ssh_get_progname(av[0]); 1213 __progname = ssh_get_progname(av[0]);
1120 seed_rng(); 1214 seed_rng();
@@ -1135,9 +1229,9 @@ main(int ac, char **av)
1135 k_flag++; 1229 k_flag++;
1136 break; 1230 break;
1137 case 'P': 1231 case 'P':
1138 if (pkcs11_whitelist != NULL) 1232 if (provider_whitelist != NULL)
1139 fatal("-P option already specified"); 1233 fatal("-P option already specified");
1140 pkcs11_whitelist = xstrdup(optarg); 1234 provider_whitelist = xstrdup(optarg);
1141 break; 1235 break;
1142 case 's': 1236 case 's':
1143 if (c_flag) 1237 if (c_flag)
@@ -1173,8 +1267,8 @@ main(int ac, char **av)
1173 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) 1267 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
1174 usage(); 1268 usage();
1175 1269
1176 if (pkcs11_whitelist == NULL) 1270 if (provider_whitelist == NULL)
1177 pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST); 1271 provider_whitelist = xstrdup(DEFAULT_PROVIDER_WHITELIST);
1178 1272
1179 if (ac == 0 && !c_flag && !s_flag) { 1273 if (ac == 0 && !c_flag && !s_flag) {
1180 shell = getenv("SHELL"); 1274 shell = getenv("SHELL");
@@ -1329,10 +1423,10 @@ skip:
1329 if (ac > 0) 1423 if (ac > 0)
1330 parent_alive_interval = 10; 1424 parent_alive_interval = 10;
1331 idtab_init(); 1425 idtab_init();
1332 signal(SIGPIPE, SIG_IGN); 1426 ssh_signal(SIGPIPE, SIG_IGN);
1333 signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN); 1427 ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
1334 signal(SIGHUP, cleanup_handler); 1428 ssh_signal(SIGHUP, cleanup_handler);
1335 signal(SIGTERM, cleanup_handler); 1429 ssh_signal(SIGTERM, cleanup_handler);
1336 1430
1337 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) 1431 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1)
1338 fatal("%s: pledge: %s", __progname, strerror(errno)); 1432 fatal("%s: pledge: %s", __progname, strerror(errno));