summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ssh-agent.117
-rw-r--r--ssh-agent.c43
2 files changed, 50 insertions, 10 deletions
diff --git a/ssh-agent.1 b/ssh-agent.1
index c4b50bbdf..372adbe7c 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-agent.1,v 1.62 2015/11/15 23:54:15 jmc Exp $ 1.\" $OpenBSD: ssh-agent.1,v 1.63 2016/11/30 03:07:37 djm 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
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.Dd $Mdocdate: November 15 2015 $ 37.Dd $Mdocdate: November 30 2016 $
38.Dt SSH-AGENT 1 38.Dt SSH-AGENT 1
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -47,6 +47,7 @@
47.Op Fl a Ar bind_address 47.Op Fl a Ar bind_address
48.Op Fl E Ar fingerprint_hash 48.Op Fl E Ar fingerprint_hash
49.Op Fl t Ar life 49.Op Fl t Ar life
50.Op Fl P Ar pkcs11_whitelist
50.Op Ar command Op Ar arg ... 51.Op Ar command Op Ar arg ...
51.Nm ssh-agent 52.Nm ssh-agent
52.Op Fl c | s 53.Op Fl c | s
@@ -121,6 +122,18 @@ The default is
121Kill the current agent (given by the 122Kill the current agent (given by the
122.Ev SSH_AGENT_PID 123.Ev SSH_AGENT_PID
123environment variable). 124environment variable).
125.It Fl P
126Specify a pattern-list of acceptable paths for PKCS#11 shared libraries
127that may be added using the
128.Fl s
129option to
130.Xr ssh-add 1 .
131The default is to allow loading PKCS#11 libraries from
132.Dq /usr/lib/*,/usr/local/lib/* .
133PKCS#11 libraries that do not match the whitelist will be refused.
134See PATTERNS in
135.Xr ssh_config 5
136for a description of pattern-list syntax.
124.It Fl s 137.It Fl s
125Generate Bourne shell commands on 138Generate Bourne shell commands on
126.Dv stdout . 139.Dv stdout .
diff --git a/ssh-agent.c b/ssh-agent.c
index fd5f2b35d..395213553 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.214 2016/09/12 01:22:38 deraadt Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.215 2016/11/30 03:07:37 djm 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
@@ -82,11 +82,16 @@
82#include "misc.h" 82#include "misc.h"
83#include "digest.h" 83#include "digest.h"
84#include "ssherr.h" 84#include "ssherr.h"
85#include "match.h"
85 86
86#ifdef ENABLE_PKCS11 87#ifdef ENABLE_PKCS11
87#include "ssh-pkcs11.h" 88#include "ssh-pkcs11.h"
88#endif 89#endif
89 90
91#ifndef DEFAULT_PKCS11_WHITELIST
92# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*"
93#endif
94
90typedef enum { 95typedef enum {
91 AUTH_UNUSED, 96 AUTH_UNUSED,
92 AUTH_SOCKET, 97 AUTH_SOCKET,
@@ -134,6 +139,9 @@ pid_t cleanup_pid = 0;
134char socket_name[PATH_MAX]; 139char socket_name[PATH_MAX];
135char socket_dir[PATH_MAX]; 140char socket_dir[PATH_MAX];
136 141
142/* PKCS#11 path whitelist */
143static char *pkcs11_whitelist;
144
137/* locking */ 145/* locking */
138#define LOCK_SIZE 32 146#define LOCK_SIZE 32
139#define LOCK_SALT_SIZE 16 147#define LOCK_SALT_SIZE 16
@@ -737,7 +745,7 @@ no_identities(SocketEntry *e, u_int type)
737static void 745static void
738process_add_smartcard_key(SocketEntry *e) 746process_add_smartcard_key(SocketEntry *e)
739{ 747{
740 char *provider = NULL, *pin; 748 char *provider = NULL, *pin, canonical_provider[PATH_MAX];
741 int r, i, version, count = 0, success = 0, confirm = 0; 749 int r, i, version, count = 0, success = 0, confirm = 0;
742 u_int seconds; 750 u_int seconds;
743 time_t death = 0; 751 time_t death = 0;
@@ -769,10 +777,21 @@ process_add_smartcard_key(SocketEntry *e)
769 goto send; 777 goto send;
770 } 778 }
771 } 779 }
780 if (realpath(provider, canonical_provider) == NULL) {
781 verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
782 provider, strerror(errno));
783 goto send;
784 }
785 if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) {
786 verbose("refusing PKCS#11 add of \"%.100s\": "
787 "provider not whitelisted", canonical_provider);
788 goto send;
789 }
790 debug("%s: add %.100s", __func__, canonical_provider);
772 if (lifetime && !death) 791 if (lifetime && !death)
773 death = monotime() + lifetime; 792 death = monotime() + lifetime;
774 793
775 count = pkcs11_add_provider(provider, pin, &keys); 794 count = pkcs11_add_provider(canonical_provider, pin, &keys);
776 for (i = 0; i < count; i++) { 795 for (i = 0; i < count; i++) {
777 k = keys[i]; 796 k = keys[i];
778 version = k->type == KEY_RSA1 ? 1 : 2; 797 version = k->type == KEY_RSA1 ? 1 : 2;
@@ -780,8 +799,8 @@ process_add_smartcard_key(SocketEntry *e)
780 if (lookup_identity(k, version) == NULL) { 799 if (lookup_identity(k, version) == NULL) {
781 id = xcalloc(1, sizeof(Identity)); 800 id = xcalloc(1, sizeof(Identity));
782 id->key = k; 801 id->key = k;
783 id->provider = xstrdup(provider); 802 id->provider = xstrdup(canonical_provider);
784 id->comment = xstrdup(provider); /* XXX */ 803 id->comment = xstrdup(canonical_provider); /* XXX */
785 id->death = death; 804 id->death = death;
786 id->confirm = confirm; 805 id->confirm = confirm;
787 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 806 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
@@ -1172,7 +1191,7 @@ usage(void)
1172{ 1191{
1173 fprintf(stderr, 1192 fprintf(stderr,
1174 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" 1193 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
1175 " [-t life] [command [arg ...]]\n" 1194 " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n"
1176 " ssh-agent [-c | -s] -k\n"); 1195 " ssh-agent [-c | -s] -k\n");
1177 exit(1); 1196 exit(1);
1178} 1197}
@@ -1213,7 +1232,7 @@ main(int ac, char **av)
1213 __progname = ssh_get_progname(av[0]); 1232 __progname = ssh_get_progname(av[0]);
1214 seed_rng(); 1233 seed_rng();
1215 1234
1216 while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) { 1235 while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
1217 switch (ch) { 1236 switch (ch) {
1218 case 'E': 1237 case 'E':
1219 fingerprint_hash = ssh_digest_alg_by_name(optarg); 1238 fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -1228,6 +1247,11 @@ main(int ac, char **av)
1228 case 'k': 1247 case 'k':
1229 k_flag++; 1248 k_flag++;
1230 break; 1249 break;
1250 case 'P':
1251 if (pkcs11_whitelist != NULL)
1252 fatal("-P option already specified");
1253 pkcs11_whitelist = xstrdup(optarg);
1254 break;
1231 case 's': 1255 case 's':
1232 if (c_flag) 1256 if (c_flag)
1233 usage(); 1257 usage();
@@ -1262,6 +1286,9 @@ main(int ac, char **av)
1262 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) 1286 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
1263 usage(); 1287 usage();
1264 1288
1289 if (pkcs11_whitelist == NULL)
1290 pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST);
1291
1265 if (ac == 0 && !c_flag && !s_flag) { 1292 if (ac == 0 && !c_flag && !s_flag) {
1266 shell = getenv("SHELL"); 1293 shell = getenv("SHELL");
1267 if (shell != NULL && (len = strlen(shell)) > 2 && 1294 if (shell != NULL && (len = strlen(shell)) > 2 &&
@@ -1409,7 +1436,7 @@ skip:
1409 signal(SIGTERM, cleanup_handler); 1436 signal(SIGTERM, cleanup_handler);
1410 nalloc = 0; 1437 nalloc = 0;
1411 1438
1412 if (pledge("stdio cpath unix id proc exec", NULL) == -1) 1439 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1)
1413 fatal("%s: pledge: %s", __progname, strerror(errno)); 1440 fatal("%s: pledge: %s", __progname, strerror(errno));
1414 platform_pledge_agent(); 1441 platform_pledge_agent();
1415 1442