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:
parent
7844f357cd
commit
786d5994da
17
ssh-agent.1
17
ssh-agent.1
|
@ -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 .
|
||||||
|
|
43
ssh-agent.c
43
ssh-agent.c
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue