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 25d6ebc53..395213553 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.213 2016/05/02 08:49:03 djm 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
@@ -36,7 +36,6 @@
36 36
37#include "includes.h" 37#include "includes.h"
38 38
39#include <sys/param.h> /* MIN MAX */
40#include <sys/types.h> 39#include <sys/types.h>
41#include <sys/param.h> 40#include <sys/param.h>
42#include <sys/resource.h> 41#include <sys/resource.h>
@@ -83,11 +82,16 @@
83#include "misc.h" 82#include "misc.h"
84#include "digest.h" 83#include "digest.h"
85#include "ssherr.h" 84#include "ssherr.h"
85#include "match.h"
86 86
87#ifdef ENABLE_PKCS11 87#ifdef ENABLE_PKCS11
88#include "ssh-pkcs11.h" 88#include "ssh-pkcs11.h"
89#endif 89#endif
90 90
91#ifndef DEFAULT_PKCS11_WHITELIST
92# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*"
93#endif
94
91typedef enum { 95typedef enum {
92 AUTH_UNUSED, 96 AUTH_UNUSED,
93 AUTH_SOCKET, 97 AUTH_SOCKET,
@@ -135,6 +139,9 @@ pid_t cleanup_pid = 0;
135char socket_name[PATH_MAX]; 139char socket_name[PATH_MAX];
136char socket_dir[PATH_MAX]; 140char socket_dir[PATH_MAX];
137 141
142/* PKCS#11 path whitelist */
143static char *pkcs11_whitelist;
144
138/* locking */ 145/* locking */
139#define LOCK_SIZE 32 146#define LOCK_SIZE 32
140#define LOCK_SALT_SIZE 16 147#define LOCK_SALT_SIZE 16
@@ -539,7 +546,7 @@ reaper(void)
539 tab->nentries--; 546 tab->nentries--;
540 } else 547 } else
541 deadline = (deadline == 0) ? id->death : 548 deadline = (deadline == 0) ? id->death :
542 MIN(deadline, id->death); 549 MINIMUM(deadline, id->death);
543 } 550 }
544 } 551 }
545 if (deadline == 0 || deadline <= now) 552 if (deadline == 0 || deadline <= now)
@@ -738,7 +745,7 @@ no_identities(SocketEntry *e, u_int type)
738static void 745static void
739process_add_smartcard_key(SocketEntry *e) 746process_add_smartcard_key(SocketEntry *e)
740{ 747{
741 char *provider = NULL, *pin; 748 char *provider = NULL, *pin, canonical_provider[PATH_MAX];
742 int r, i, version, count = 0, success = 0, confirm = 0; 749 int r, i, version, count = 0, success = 0, confirm = 0;
743 u_int seconds; 750 u_int seconds;
744 time_t death = 0; 751 time_t death = 0;
@@ -770,10 +777,21 @@ process_add_smartcard_key(SocketEntry *e)
770 goto send; 777 goto send;
771 } 778 }
772 } 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);
773 if (lifetime && !death) 791 if (lifetime && !death)
774 death = monotime() + lifetime; 792 death = monotime() + lifetime;
775 793
776 count = pkcs11_add_provider(provider, pin, &keys); 794 count = pkcs11_add_provider(canonical_provider, pin, &keys);
777 for (i = 0; i < count; i++) { 795 for (i = 0; i < count; i++) {
778 k = keys[i]; 796 k = keys[i];
779 version = k->type == KEY_RSA1 ? 1 : 2; 797 version = k->type == KEY_RSA1 ? 1 : 2;
@@ -781,8 +799,8 @@ process_add_smartcard_key(SocketEntry *e)
781 if (lookup_identity(k, version) == NULL) { 799 if (lookup_identity(k, version) == NULL) {
782 id = xcalloc(1, sizeof(Identity)); 800 id = xcalloc(1, sizeof(Identity));
783 id->key = k; 801 id->key = k;
784 id->provider = xstrdup(provider); 802 id->provider = xstrdup(canonical_provider);
785 id->comment = xstrdup(provider); /* XXX */ 803 id->comment = xstrdup(canonical_provider); /* XXX */
786 id->death = death; 804 id->death = death;
787 id->confirm = confirm; 805 id->confirm = confirm;
788 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 806 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
@@ -991,7 +1009,7 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
991 switch (sockets[i].type) { 1009 switch (sockets[i].type) {
992 case AUTH_SOCKET: 1010 case AUTH_SOCKET:
993 case AUTH_CONNECTION: 1011 case AUTH_CONNECTION:
994 n = MAX(n, sockets[i].fd); 1012 n = MAXIMUM(n, sockets[i].fd);
995 break; 1013 break;
996 case AUTH_UNUSED: 1014 case AUTH_UNUSED:
997 break; 1015 break;
@@ -1030,7 +1048,7 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
1030 deadline = reaper(); 1048 deadline = reaper();
1031 if (parent_alive_interval != 0) 1049 if (parent_alive_interval != 0)
1032 deadline = (deadline == 0) ? parent_alive_interval : 1050 deadline = (deadline == 0) ? parent_alive_interval :
1033 MIN(deadline, parent_alive_interval); 1051 MINIMUM(deadline, parent_alive_interval);
1034 if (deadline == 0) { 1052 if (deadline == 0) {
1035 *tvpp = NULL; 1053 *tvpp = NULL;
1036 } else { 1054 } else {
@@ -1173,7 +1191,7 @@ usage(void)
1173{ 1191{
1174 fprintf(stderr, 1192 fprintf(stderr,
1175 "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"
1176 " [-t life] [command [arg ...]]\n" 1194 " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n"
1177 " ssh-agent [-c | -s] -k\n"); 1195 " ssh-agent [-c | -s] -k\n");
1178 exit(1); 1196 exit(1);
1179} 1197}
@@ -1214,7 +1232,7 @@ main(int ac, char **av)
1214 __progname = ssh_get_progname(av[0]); 1232 __progname = ssh_get_progname(av[0]);
1215 seed_rng(); 1233 seed_rng();
1216 1234
1217 while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) { 1235 while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
1218 switch (ch) { 1236 switch (ch) {
1219 case 'E': 1237 case 'E':
1220 fingerprint_hash = ssh_digest_alg_by_name(optarg); 1238 fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -1229,6 +1247,11 @@ main(int ac, char **av)
1229 case 'k': 1247 case 'k':
1230 k_flag++; 1248 k_flag++;
1231 break; 1249 break;
1250 case 'P':
1251 if (pkcs11_whitelist != NULL)
1252 fatal("-P option already specified");
1253 pkcs11_whitelist = xstrdup(optarg);
1254 break;
1232 case 's': 1255 case 's':
1233 if (c_flag) 1256 if (c_flag)
1234 usage(); 1257 usage();
@@ -1263,6 +1286,9 @@ main(int ac, char **av)
1263 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))
1264 usage(); 1287 usage();
1265 1288
1289 if (pkcs11_whitelist == NULL)
1290 pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST);
1291
1266 if (ac == 0 && !c_flag && !s_flag) { 1292 if (ac == 0 && !c_flag && !s_flag) {
1267 shell = getenv("SHELL"); 1293 shell = getenv("SHELL");
1268 if (shell != NULL && (len = strlen(shell)) > 2 && 1294 if (shell != NULL && (len = strlen(shell)) > 2 &&
@@ -1410,7 +1436,7 @@ skip:
1410 signal(SIGTERM, cleanup_handler); 1436 signal(SIGTERM, cleanup_handler);
1411 nalloc = 0; 1437 nalloc = 0;
1412 1438
1413 if (pledge("stdio cpath unix id proc exec", NULL) == -1) 1439 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1)
1414 fatal("%s: pledge: %s", __progname, strerror(errno)); 1440 fatal("%s: pledge: %s", __progname, strerror(errno));
1415 platform_pledge_agent(); 1441 platform_pledge_agent();
1416 1442