upstream commit

add a whitelist of paths from which ssh-agent will load
(via ssh-pkcs11-helper) a PKCS#11 module; ok markus@

Upstream-ID: fe79769469d9cd6d26fe0dc15751b83ef2a06e8f
This commit is contained in:
djm@openbsd.org 2016-11-30 03:07:37 +00:00 committed by Damien Miller
parent 7844f357cd
commit 786d5994da
2 changed files with 50 additions and 10 deletions

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-agent.1,v 1.62 2015/11/15 23:54:15 jmc Exp $ .\" $OpenBSD: ssh-agent.1,v 1.63 2016/11/30 03:07:37 djm Exp $
.\" .\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: November 15 2015 $ .Dd $Mdocdate: November 30 2016 $
.Dt SSH-AGENT 1 .Dt SSH-AGENT 1
.Os .Os
.Sh NAME .Sh NAME
@ -47,6 +47,7 @@
.Op Fl a Ar bind_address .Op Fl a Ar bind_address
.Op Fl E Ar fingerprint_hash .Op Fl E Ar fingerprint_hash
.Op Fl t Ar life .Op Fl t Ar life
.Op Fl P Ar pkcs11_whitelist
.Op Ar command Op Ar arg ... .Op Ar command Op Ar arg ...
.Nm ssh-agent .Nm ssh-agent
.Op Fl c | s .Op Fl c | s
@ -121,6 +122,18 @@ The default is
Kill the current agent (given by the Kill the current agent (given by the
.Ev SSH_AGENT_PID .Ev SSH_AGENT_PID
environment variable). environment variable).
.It Fl P
Specify a pattern-list of acceptable paths for PKCS#11 shared libraries
that may be added using the
.Fl s
option to
.Xr ssh-add 1 .
The default is to allow loading PKCS#11 libraries from
.Dq /usr/lib/*,/usr/local/lib/* .
PKCS#11 libraries that do not match the whitelist will be refused.
See PATTERNS in
.Xr ssh_config 5
for a description of pattern-list syntax.
.It Fl s .It Fl s
Generate Bourne shell commands on Generate Bourne shell commands on
.Dv stdout . .Dv stdout .

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-agent.c,v 1.214 2016/09/12 01:22:38 deraadt Exp $ */ /* $OpenBSD: ssh-agent.c,v 1.215 2016/11/30 03:07:37 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -82,11 +82,16 @@
#include "misc.h" #include "misc.h"
#include "digest.h" #include "digest.h"
#include "ssherr.h" #include "ssherr.h"
#include "match.h"
#ifdef ENABLE_PKCS11 #ifdef ENABLE_PKCS11
#include "ssh-pkcs11.h" #include "ssh-pkcs11.h"
#endif #endif
#ifndef DEFAULT_PKCS11_WHITELIST
# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*"
#endif
typedef enum { typedef enum {
AUTH_UNUSED, AUTH_UNUSED,
AUTH_SOCKET, AUTH_SOCKET,
@ -134,6 +139,9 @@ pid_t cleanup_pid = 0;
char socket_name[PATH_MAX]; char socket_name[PATH_MAX];
char socket_dir[PATH_MAX]; char socket_dir[PATH_MAX];
/* PKCS#11 path whitelist */
static char *pkcs11_whitelist;
/* locking */ /* locking */
#define LOCK_SIZE 32 #define LOCK_SIZE 32
#define LOCK_SALT_SIZE 16 #define LOCK_SALT_SIZE 16
@ -737,7 +745,7 @@ no_identities(SocketEntry *e, u_int type)
static void static void
process_add_smartcard_key(SocketEntry *e) 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; int r, i, version, count = 0, success = 0, confirm = 0;
u_int seconds; u_int seconds;
time_t death = 0; time_t death = 0;
@ -769,10 +777,21 @@ process_add_smartcard_key(SocketEntry *e)
goto send; 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) if (lifetime && !death)
death = monotime() + lifetime; death = monotime() + lifetime;
count = pkcs11_add_provider(provider, pin, &keys); count = pkcs11_add_provider(canonical_provider, pin, &keys);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
k = keys[i]; k = keys[i];
version = k->type == KEY_RSA1 ? 1 : 2; version = k->type == KEY_RSA1 ? 1 : 2;
@ -780,8 +799,8 @@ process_add_smartcard_key(SocketEntry *e)
if (lookup_identity(k, version) == NULL) { if (lookup_identity(k, version) == NULL) {
id = xcalloc(1, sizeof(Identity)); id = xcalloc(1, sizeof(Identity));
id->key = k; id->key = k;
id->provider = xstrdup(provider); id->provider = xstrdup(canonical_provider);
id->comment = xstrdup(provider); /* XXX */ id->comment = xstrdup(canonical_provider); /* XXX */
id->death = death; id->death = death;
id->confirm = confirm; id->confirm = confirm;
TAILQ_INSERT_TAIL(&tab->idlist, id, next); TAILQ_INSERT_TAIL(&tab->idlist, id, next);
@ -1172,7 +1191,7 @@ usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" "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"); " ssh-agent [-c | -s] -k\n");
exit(1); exit(1);
} }
@ -1213,7 +1232,7 @@ main(int ac, char **av)
__progname = ssh_get_progname(av[0]); __progname = ssh_get_progname(av[0]);
seed_rng(); seed_rng();
while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) { while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
switch (ch) { switch (ch) {
case 'E': case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg); fingerprint_hash = ssh_digest_alg_by_name(optarg);
@ -1228,6 +1247,11 @@ main(int ac, char **av)
case 'k': case 'k':
k_flag++; k_flag++;
break; break;
case 'P':
if (pkcs11_whitelist != NULL)
fatal("-P option already specified");
pkcs11_whitelist = xstrdup(optarg);
break;
case 's': case 's':
if (c_flag) if (c_flag)
usage(); usage();
@ -1262,6 +1286,9 @@ main(int ac, char **av)
if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
usage(); usage();
if (pkcs11_whitelist == NULL)
pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST);
if (ac == 0 && !c_flag && !s_flag) { if (ac == 0 && !c_flag && !s_flag) {
shell = getenv("SHELL"); shell = getenv("SHELL");
if (shell != NULL && (len = strlen(shell)) > 2 && if (shell != NULL && (len = strlen(shell)) > 2 &&
@ -1409,7 +1436,7 @@ skip:
signal(SIGTERM, cleanup_handler); signal(SIGTERM, cleanup_handler);
nalloc = 0; 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)); fatal("%s: pledge: %s", __progname, strerror(errno));
platform_pledge_agent(); platform_pledge_agent();