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 $ */
22/*
33 * Author: Tatu Ylonen <ylo@cs.hut.fi>
44 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6969#include "misc.h"
7070#include "digest.h"
7171#include "ssherr.h"
72+ #include "match.h"
7273
7374#ifdef ENABLE_PKCS11
7475#include "ssh-pkcs11.h"
7576#endif
7677
78+ #ifndef DEFAULT_PKCS11_WHITELIST
79+ # define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*"
80+ #endif
81+
7782typedef enum {
7883 AUTH_UNUSED,
7984 AUTH_SOCKET,
@@ -121,6 +126,9 @@ pid_t cleanup_pid = 0;
121126char socket_name [PATH_MAX ];
122127char socket_dir [PATH_MAX ];
123128
129+ /* PKCS#11 path whitelist */
130+ static char * pkcs11_whitelist ;
131+
124132/* locking */
125133#define LOCK_SIZE 32
126134#define LOCK_SALT_SIZE 16
@@ -724,7 +732,7 @@ no_identities(SocketEntry *e, u_int type)
724732static void
725733process_add_smartcard_key (SocketEntry * e )
726734{
727- char * provider = NULL , * pin ;
735+ char * provider = NULL , * pin , canonical_provider [ PATH_MAX ] ;
728736 int r , i , version , count = 0 , success = 0 , confirm = 0 ;
729737 u_int seconds ;
730738 time_t death = 0 ;
@@ -756,19 +764,30 @@ process_add_smartcard_key(SocketEntry *e)
756764 goto send ;
757765 }
758766 }
767+ if (realpath (provider , canonical_provider ) == NULL ) {
768+ verbose ("failed PKCS#11 add of \"%.100s\": realpath: %s" ,
769+ provider , strerror (errno ));
770+ goto send ;
771+ }
772+ if (match_pattern_list (canonical_provider , pkcs11_whitelist , 0 ) != 1 ) {
773+ verbose ("refusing PKCS#11 add of \"%.100s\": "
774+ "provider not whitelisted" , canonical_provider );
775+ goto send ;
776+ }
777+ debug ("%s: add %.100s" , __func__ , canonical_provider );
759778 if (lifetime && !death )
760779 death = monotime () + lifetime ;
761780
762- count = pkcs11_add_provider (provider , pin , & keys );
781+ count = pkcs11_add_provider (canonical_provider , pin , & keys );
763782 for (i = 0 ; i < count ; i ++ ) {
764783 k = keys [i ];
765784 version = k -> type == KEY_RSA1 ? 1 : 2 ;
766785 tab = idtab_lookup (version );
767786 if (lookup_identity (k , version ) == NULL ) {
768787 id = xcalloc (1 , sizeof (Identity ));
769788 id -> key = k ;
770- id -> provider = xstrdup (provider );
771- id -> comment = xstrdup (provider ); /* XXX */
789+ id -> provider = xstrdup (canonical_provider );
790+ id -> comment = xstrdup (canonical_provider ); /* XXX */
772791 id -> death = death ;
773792 id -> confirm = confirm ;
774793 TAILQ_INSERT_TAIL (& tab -> idlist , id , next );
@@ -1157,7 +1176,7 @@ usage(void)
11571176{
11581177 fprintf (stderr ,
11591178 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
1160- " [-t life] [command [arg ...]]\n"
1179+ " [-P pkcs11_whitelist] [- t life] [command [arg ...]]\n"
11611180 " ssh-agent [-c | -s] -k\n" );
11621181 exit (1 );
11631182}
@@ -1191,7 +1210,7 @@ main(int ac, char **av)
11911210 OpenSSL_add_all_algorithms ();
11921211#endif
11931212
1194- while ((ch = getopt (ac , av , "cDdksE:a:t:" )) != -1 ) {
1213+ while ((ch = getopt (ac , av , "cDdksE:a:P: t:" )) != -1 ) {
11951214 switch (ch ) {
11961215 case 'E' :
11971216 fingerprint_hash = ssh_digest_alg_by_name (optarg );
@@ -1206,6 +1225,11 @@ main(int ac, char **av)
12061225 case 'k' :
12071226 k_flag ++ ;
12081227 break ;
1228+ case 'P' :
1229+ if (pkcs11_whitelist != NULL )
1230+ fatal ("-P option already specified" );
1231+ pkcs11_whitelist = xstrdup (optarg );
1232+ break ;
12091233 case 's' :
12101234 if (c_flag )
12111235 usage ();
@@ -1240,6 +1264,9 @@ main(int ac, char **av)
12401264 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag ))
12411265 usage ();
12421266
1267+ if (pkcs11_whitelist == NULL )
1268+ pkcs11_whitelist = xstrdup (DEFAULT_PKCS11_WHITELIST );
1269+
12431270 if (ac == 0 && !c_flag && !s_flag ) {
12441271 shell = getenv ("SHELL" );
12451272 if (shell != NULL && (len = strlen (shell )) > 2 &&
@@ -1385,7 +1412,7 @@ main(int ac, char **av)
13851412 signal (SIGTERM , cleanup_handler );
13861413 nalloc = 0 ;
13871414
1388- if (pledge ("stdio cpath unix id proc exec" , NULL ) == -1 )
1415+ if (pledge ("stdio rpath cpath unix id proc exec" , NULL ) == -1 )
13891416 fatal ("%s: pledge: %s" , __progname , strerror (errno ));
13901417
13911418 while (1 ) {
0 commit comments