diff options
author | Renato Botelho <renato@netgate.com> | 2017-02-09 11:26:48 -0200 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2017-02-09 11:26:48 -0200 |
commit | 4a05f5440acda223e6a0ec5157bc32ecc0f09ff9 (patch) | |
tree | 4c2ece480e5d4155ed35bec62996de40eb179f18 /crypto/openssh/ssh-agent.c | |
parent | 681a482d8fc4bfc14a24f7a9d75cca6337f2a520 (diff) | |
parent | a1e52233c91fd46e666297270ab655f1abff8535 (diff) | |
download | FreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.zip FreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.tar.gz |
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'crypto/openssh/ssh-agent.c')
-rw-r--r-- | crypto/openssh/ssh-agent.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c index 8113022..9cad00a 100644 --- a/crypto/openssh/ssh-agent.c +++ b/crypto/openssh/ssh-agent.c @@ -84,11 +84,16 @@ __RCSID("$FreeBSD$"); #include "misc.h" #include "digest.h" #include "ssherr.h" +#include "match.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" #endif +#ifndef DEFAULT_PKCS11_WHITELIST +# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" +#endif + #if defined(HAVE_SYS_PRCTL_H) #include <sys/prctl.h> /* For prctl() and PR_SET_DUMPABLE */ #endif @@ -140,6 +145,9 @@ pid_t cleanup_pid = 0; char socket_name[PATH_MAX]; char socket_dir[PATH_MAX]; +/* PKCS#11 path whitelist */ +static char *pkcs11_whitelist; + /* locking */ #define LOCK_SIZE 32 #define LOCK_SALT_SIZE 16 @@ -761,7 +769,7 @@ no_identities(SocketEntry *e, u_int type) static void process_add_smartcard_key(SocketEntry *e) { - char *provider = NULL, *pin; + char *provider = NULL, *pin, canonical_provider[PATH_MAX]; int r, i, version, count = 0, success = 0, confirm = 0; u_int seconds; time_t death = 0; @@ -793,10 +801,21 @@ process_add_smartcard_key(SocketEntry *e) goto send; } } + if (realpath(provider, canonical_provider) == NULL) { + verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", + provider, strerror(errno)); + goto send; + } + if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { + verbose("refusing PKCS#11 add of \"%.100s\": " + "provider not whitelisted", canonical_provider); + goto send; + } + debug("%s: add %.100s", __func__, canonical_provider); if (lifetime && !death) death = monotime() + lifetime; - count = pkcs11_add_provider(provider, pin, &keys); + count = pkcs11_add_provider(canonical_provider, pin, &keys); for (i = 0; i < count; i++) { k = keys[i]; version = k->type == KEY_RSA1 ? 1 : 2; @@ -804,8 +823,8 @@ process_add_smartcard_key(SocketEntry *e) if (lookup_identity(k, version) == NULL) { id = xcalloc(1, sizeof(Identity)); id->key = k; - id->provider = xstrdup(provider); - id->comment = xstrdup(provider); /* XXX */ + id->provider = xstrdup(canonical_provider); + id->comment = xstrdup(canonical_provider); /* XXX */ id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); @@ -1200,7 +1219,7 @@ usage(void) { fprintf(stderr, "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" - " [-t life] [command [arg ...]]\n" + " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n" " ssh-agent [-c | -s] -k\n"); fprintf(stderr, " -x Exit when the last client disconnects.\n"); exit(1); @@ -1246,7 +1265,7 @@ main(int ac, char **av) __progname = ssh_get_progname(av[0]); seed_rng(); - while ((ch = getopt(ac, av, "cDdksE:a:t:x")) != -1) { + while ((ch = getopt(ac, av, "cDdksE:a:P:t:x")) != -1) { switch (ch) { case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); @@ -1261,6 +1280,11 @@ main(int ac, char **av) case 'k': k_flag++; break; + case 'P': + if (pkcs11_whitelist != NULL) + fatal("-P option already specified"); + pkcs11_whitelist = xstrdup(optarg); + break; case 's': if (c_flag) usage(); @@ -1298,6 +1322,9 @@ main(int ac, char **av) if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) usage(); + if (pkcs11_whitelist == NULL) + pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST); + if (ac == 0 && !c_flag && !s_flag) { shell = getenv("SHELL"); if (shell != NULL && (len = strlen(shell)) > 2 && @@ -1445,7 +1472,7 @@ skip: signal(SIGTERM, cleanup_handler); nalloc = 0; - if (pledge("stdio cpath unix id proc exec", NULL) == -1) + if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) fatal("%s: pledge: %s", __progname, strerror(errno)); platform_pledge_agent(); |