summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c50
1 files changed, 38 insertions, 12 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index 25d6ebc53c94..395213553043 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.213 2016/05/02 08:49:03 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.215 2016/11/30 03:07:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -36,7 +36,6 @@
#include "includes.h"
-#include <sys/param.h> /* MIN MAX */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/resource.h>
@@ -83,11 +82,16 @@
#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
+
typedef enum {
AUTH_UNUSED,
AUTH_SOCKET,
@@ -135,6 +139,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
@@ -539,7 +546,7 @@ reaper(void)
tab->nentries--;
} else
deadline = (deadline == 0) ? id->death :
- MIN(deadline, id->death);
+ MINIMUM(deadline, id->death);
}
}
if (deadline == 0 || deadline <= now)
@@ -738,7 +745,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;
@@ -770,10 +777,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;
@@ -781,8 +799,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);
@@ -991,7 +1009,7 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
switch (sockets[i].type) {
case AUTH_SOCKET:
case AUTH_CONNECTION:
- n = MAX(n, sockets[i].fd);
+ n = MAXIMUM(n, sockets[i].fd);
break;
case AUTH_UNUSED:
break;
@@ -1030,7 +1048,7 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
deadline = reaper();
if (parent_alive_interval != 0)
deadline = (deadline == 0) ? parent_alive_interval :
- MIN(deadline, parent_alive_interval);
+ MINIMUM(deadline, parent_alive_interval);
if (deadline == 0) {
*tvpp = NULL;
} else {
@@ -1173,7 +1191,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");
exit(1);
}
@@ -1214,7 +1232,7 @@ main(int ac, char **av)
__progname = ssh_get_progname(av[0]);
seed_rng();
- while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) {
+ while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
switch (ch) {
case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -1229,6 +1247,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();
@@ -1263,6 +1286,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 &&
@@ -1410,7 +1436,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();