diff options
author | djm@openbsd.org <djm@openbsd.org> | 2016-11-30 03:07:37 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2016-11-30 19:44:24 +1100 |
commit | 786d5994da79151180cb14a6cf157ebbba61c0cc (patch) | |
tree | 706aea69bf1507b0dca261fbc15739b2f24587a8 /ssh-agent.c | |
parent | 7844f357cdd90530eec81340847783f1f1da010b (diff) |
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
Diffstat (limited to 'ssh-agent.c')
-rw-r--r-- | ssh-agent.c | 43 |
1 files changed, 35 insertions, 8 deletions
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 | |||
90 | typedef enum { | 95 | typedef enum { |
91 | AUTH_UNUSED, | 96 | AUTH_UNUSED, |
92 | AUTH_SOCKET, | 97 | AUTH_SOCKET, |
@@ -134,6 +139,9 @@ pid_t cleanup_pid = 0; | |||
134 | char socket_name[PATH_MAX]; | 139 | char socket_name[PATH_MAX]; |
135 | char socket_dir[PATH_MAX]; | 140 | char socket_dir[PATH_MAX]; |
136 | 141 | ||
142 | /* PKCS#11 path whitelist */ | ||
143 | static 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) | |||
737 | static void | 745 | static void |
738 | process_add_smartcard_key(SocketEntry *e) | 746 | process_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 | ||