| version 1.214, 2016/09/12 01:22:38 |
version 1.215, 2016/11/30 03:07:37 |
|
|
| #include "misc.h" |
#include "misc.h" |
| #include "digest.h" |
#include "digest.h" |
| #include "ssherr.h" |
#include "ssherr.h" |
| |
#include "match.h" |
| |
|
| #ifdef ENABLE_PKCS11 |
#ifdef ENABLE_PKCS11 |
| #include "ssh-pkcs11.h" |
#include "ssh-pkcs11.h" |
| #endif |
#endif |
| |
|
| |
#ifndef DEFAULT_PKCS11_WHITELIST |
| |
# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" |
| |
#endif |
| |
|
| typedef enum { |
typedef enum { |
| AUTH_UNUSED, |
AUTH_UNUSED, |
| AUTH_SOCKET, |
AUTH_SOCKET, |
|
|
| char socket_name[PATH_MAX]; |
char socket_name[PATH_MAX]; |
| char socket_dir[PATH_MAX]; |
char socket_dir[PATH_MAX]; |
| |
|
| |
/* PKCS#11 path whitelist */ |
| |
static char *pkcs11_whitelist; |
| |
|
| /* locking */ |
/* locking */ |
| #define LOCK_SIZE 32 |
#define LOCK_SIZE 32 |
| #define LOCK_SALT_SIZE 16 |
#define LOCK_SALT_SIZE 16 |
|
|
| static void |
static void |
| process_add_smartcard_key(SocketEntry *e) |
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; |
int r, i, version, count = 0, success = 0, confirm = 0; |
| u_int seconds; |
u_int seconds; |
| time_t death = 0; |
time_t death = 0; |
|
|
| goto send; |
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) |
if (lifetime && !death) |
| death = monotime() + lifetime; |
death = monotime() + lifetime; |
| |
|
| count = pkcs11_add_provider(provider, pin, &keys); |
count = pkcs11_add_provider(canonical_provider, pin, &keys); |
| for (i = 0; i < count; i++) { |
for (i = 0; i < count; i++) { |
| k = keys[i]; |
k = keys[i]; |
| version = k->type == KEY_RSA1 ? 1 : 2; |
version = k->type == KEY_RSA1 ? 1 : 2; |
|
|
| if (lookup_identity(k, version) == NULL) { |
if (lookup_identity(k, version) == NULL) { |
| id = xcalloc(1, sizeof(Identity)); |
id = xcalloc(1, sizeof(Identity)); |
| id->key = k; |
id->key = k; |
| id->provider = xstrdup(provider); |
id->provider = xstrdup(canonical_provider); |
| id->comment = xstrdup(provider); /* XXX */ |
id->comment = xstrdup(canonical_provider); /* XXX */ |
| id->death = death; |
id->death = death; |
| id->confirm = confirm; |
id->confirm = confirm; |
| TAILQ_INSERT_TAIL(&tab->idlist, id, next); |
TAILQ_INSERT_TAIL(&tab->idlist, id, next); |
|
|
| { |
{ |
| fprintf(stderr, |
fprintf(stderr, |
| "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" |
"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"); |
" ssh-agent [-c | -s] -k\n"); |
| exit(1); |
exit(1); |
| } |
} |
|
|
| OpenSSL_add_all_algorithms(); |
OpenSSL_add_all_algorithms(); |
| #endif |
#endif |
| |
|
| while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) { |
while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) { |
| switch (ch) { |
switch (ch) { |
| case 'E': |
case 'E': |
| fingerprint_hash = ssh_digest_alg_by_name(optarg); |
fingerprint_hash = ssh_digest_alg_by_name(optarg); |
|
|
| case 'k': |
case 'k': |
| k_flag++; |
k_flag++; |
| break; |
break; |
| |
case 'P': |
| |
if (pkcs11_whitelist != NULL) |
| |
fatal("-P option already specified"); |
| |
pkcs11_whitelist = xstrdup(optarg); |
| |
break; |
| case 's': |
case 's': |
| if (c_flag) |
if (c_flag) |
| usage(); |
usage(); |
|
|
| if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) |
if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) |
| usage(); |
usage(); |
| |
|
| |
if (pkcs11_whitelist == NULL) |
| |
pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST); |
| |
|
| if (ac == 0 && !c_flag && !s_flag) { |
if (ac == 0 && !c_flag && !s_flag) { |
| shell = getenv("SHELL"); |
shell = getenv("SHELL"); |
| if (shell != NULL && (len = strlen(shell)) > 2 && |
if (shell != NULL && (len = strlen(shell)) > 2 && |
|
|
| signal(SIGTERM, cleanup_handler); |
signal(SIGTERM, cleanup_handler); |
| nalloc = 0; |
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)); |
fatal("%s: pledge: %s", __progname, strerror(errno)); |
| |
|
| while (1) { |
while (1) { |