version 1.168, 2023/07/06 22:17:59 |
version 1.169, 2023/12/18 14:46:56 |
|
|
} |
} |
|
|
static int |
static int |
delete_stdin(int agent_fd, int qflag) |
delete_stdin(int agent_fd, int qflag, int key_only, int cert_only) |
{ |
{ |
char *line = NULL, *cp; |
char *line = NULL, *cp; |
size_t linesize = 0; |
size_t linesize = 0; |
|
|
error_r(r, "(stdin):%d: invalid key", lnum); |
error_r(r, "(stdin):%d: invalid key", lnum); |
continue; |
continue; |
} |
} |
if (delete_one(agent_fd, key, cp, "(stdin)", qflag) == 0) |
if ((!key_only && !cert_only) || |
ret = 0; |
(key_only && !sshkey_is_cert(key)) || |
|
(cert_only && sshkey_is_cert(key))) { |
|
if (delete_one(agent_fd, key, cp, |
|
"(stdin)", qflag) == 0) |
|
ret = 0; |
|
} |
} |
} |
sshkey_free(key); |
sshkey_free(key); |
free(line); |
free(line); |
|
|
} |
} |
|
|
static int |
static int |
delete_file(int agent_fd, const char *filename, int key_only, int qflag) |
delete_file(int agent_fd, const char *filename, int key_only, |
|
int cert_only, int qflag) |
{ |
{ |
struct sshkey *public, *cert = NULL; |
struct sshkey *public, *cert = NULL; |
char *certpath = NULL, *comment = NULL; |
char *certpath = NULL, *comment = NULL; |
int r, ret = -1; |
int r, ret = -1; |
|
|
if (strcmp(filename, "-") == 0) |
if (strcmp(filename, "-") == 0) |
return delete_stdin(agent_fd, qflag); |
return delete_stdin(agent_fd, qflag, key_only, cert_only); |
|
|
if ((r = sshkey_load_public(filename, &public, &comment)) != 0) { |
if ((r = sshkey_load_public(filename, &public, &comment)) != 0) { |
printf("Bad key file %s: %s\n", filename, ssh_err(r)); |
printf("Bad key file %s: %s\n", filename, ssh_err(r)); |
return -1; |
return -1; |
} |
} |
if (delete_one(agent_fd, public, comment, filename, qflag) == 0) |
if ((!key_only && !cert_only) || |
ret = 0; |
(key_only && !sshkey_is_cert(public)) || |
|
(cert_only && sshkey_is_cert(public))) { |
|
if (delete_one(agent_fd, public, comment, filename, qflag) == 0) |
|
ret = 0; |
|
} |
|
|
if (key_only) |
if (key_only) |
goto out; |
goto out; |
|
|
} |
} |
|
|
static int |
static int |
add_file(int agent_fd, const char *filename, int key_only, int qflag, |
add_file(int agent_fd, const char *filename, int key_only, int cert_only, |
const char *skprovider, struct dest_constraint **dest_constraints, |
int qflag, const char *skprovider, |
|
struct dest_constraint **dest_constraints, |
size_t ndest_constraints) |
size_t ndest_constraints) |
{ |
{ |
struct sshkey *private, *cert; |
struct sshkey *private, *cert; |
|
|
skprovider = NULL; |
skprovider = NULL; |
} |
} |
|
|
if ((r = ssh_add_identity_constrained(agent_fd, private, comment, |
if (!cert_only && |
|
(r = ssh_add_identity_constrained(agent_fd, private, comment, |
lifetime, confirm, maxsign, skprovider, |
lifetime, confirm, maxsign, skprovider, |
dest_constraints, ndest_constraints)) == 0) { |
dest_constraints, ndest_constraints)) == 0) { |
ret = 0; |
ret = 0; |
|
|
xasprintf(&certpath, "%s-cert.pub", filename); |
xasprintf(&certpath, "%s-cert.pub", filename); |
if ((r = sshkey_load_public(certpath, &cert, NULL)) != 0) { |
if ((r = sshkey_load_public(certpath, &cert, NULL)) != 0) { |
if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT) |
if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT) |
error_r(r, "Failed to load certificate \"%s\"", certpath); |
error_r(r, "Failed to load certificate \"%s\"", |
|
certpath); |
goto out; |
goto out; |
} |
} |
|
|
|
|
|
|
static int |
static int |
update_card(int agent_fd, int add, const char *id, int qflag, |
update_card(int agent_fd, int add, const char *id, int qflag, |
struct dest_constraint **dest_constraints, size_t ndest_constraints) |
int key_only, int cert_only, |
|
struct dest_constraint **dest_constraints, size_t ndest_constraints, |
|
struct sshkey **certs, size_t ncerts) |
{ |
{ |
char *pin = NULL; |
char *pin = NULL; |
int r, ret = -1; |
int r, ret = -1; |
|
|
|
if (key_only) |
|
ncerts = 0; |
|
|
if (add) { |
if (add) { |
if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", |
if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", |
RP_ALLOW_STDIN)) == NULL) |
RP_ALLOW_STDIN)) == NULL) |
|
|
} |
} |
|
|
if ((r = ssh_update_card(agent_fd, add, id, pin == NULL ? "" : pin, |
if ((r = ssh_update_card(agent_fd, add, id, pin == NULL ? "" : pin, |
lifetime, confirm, dest_constraints, ndest_constraints)) == 0) { |
lifetime, confirm, dest_constraints, ndest_constraints, |
|
cert_only, certs, ncerts)) == 0) { |
ret = 0; |
ret = 0; |
if (!qflag) { |
if (!qflag) { |
fprintf(stderr, "Card %s: %s\n", |
fprintf(stderr, "Card %s: %s\n", |
|
|
} |
} |
|
|
static int |
static int |
do_file(int agent_fd, int deleting, int key_only, char *file, int qflag, |
do_file(int agent_fd, int deleting, int key_only, int cert_only, |
const char *skprovider, struct dest_constraint **dest_constraints, |
char *file, int qflag, const char *skprovider, |
size_t ndest_constraints) |
struct dest_constraint **dest_constraints, size_t ndest_constraints) |
{ |
{ |
if (deleting) { |
if (deleting) { |
if (delete_file(agent_fd, file, key_only, qflag) == -1) |
if (delete_file(agent_fd, file, key_only, |
|
cert_only, qflag) == -1) |
return -1; |
return -1; |
} else { |
} else { |
if (add_file(agent_fd, file, key_only, qflag, skprovider, |
if (add_file(agent_fd, file, key_only, cert_only, qflag, |
dest_constraints, ndest_constraints) == -1) |
skprovider, dest_constraints, ndest_constraints) == -1) |
return -1; |
return -1; |
} |
} |
return 0; |
return 0; |
|
|
int agent_fd; |
int agent_fd; |
char *pkcs11provider = NULL, *skprovider = NULL; |
char *pkcs11provider = NULL, *skprovider = NULL; |
char **dest_constraint_strings = NULL, **hostkey_files = NULL; |
char **dest_constraint_strings = NULL, **hostkey_files = NULL; |
int r, i, ch, deleting = 0, ret = 0, key_only = 0, do_download = 0; |
int r, i, ch, deleting = 0, ret = 0, key_only = 0, cert_only = 0; |
int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0; |
int do_download = 0, xflag = 0, lflag = 0, Dflag = 0; |
|
int qflag = 0, Tflag = 0; |
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; |
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; |
LogLevel log_level = SYSLOG_LEVEL_INFO; |
LogLevel log_level = SYSLOG_LEVEL_INFO; |
|
struct sshkey *k, **certs = NULL; |
struct dest_constraint **dest_constraints = NULL; |
struct dest_constraint **dest_constraints = NULL; |
size_t ndest_constraints = 0; |
size_t ndest_constraints = 0i, ncerts = 0; |
|
|
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
sanitise_stdfd(); |
sanitise_stdfd(); |
|
|
|
|
skprovider = getenv("SSH_SK_PROVIDER"); |
skprovider = getenv("SSH_SK_PROVIDER"); |
|
|
while ((ch = getopt(argc, argv, "vkKlLcdDTxXE:e:h:H:M:m:qs:S:t:")) != -1) { |
while ((ch = getopt(argc, argv, "vkKlLCcdDTxXE:e:h:H:M:m:qs:S:t:")) != -1) { |
switch (ch) { |
switch (ch) { |
case 'v': |
case 'v': |
if (log_level == SYSLOG_LEVEL_INFO) |
if (log_level == SYSLOG_LEVEL_INFO) |
|
|
case 'k': |
case 'k': |
key_only = 1; |
key_only = 1; |
break; |
break; |
|
case 'C': |
|
cert_only = 1; |
|
break; |
case 'K': |
case 'K': |
do_download = 1; |
do_download = 1; |
break; |
break; |
|
|
goto done; |
goto done; |
} |
} |
if (pkcs11provider != NULL) { |
if (pkcs11provider != NULL) { |
|
for (i = 0; i < argc; i++) { |
|
if ((r = sshkey_load_public(argv[i], &k, NULL)) != 0) |
|
fatal_fr(r, "load certificate %s", argv[i]); |
|
certs = xrecallocarray(certs, ncerts, ncerts + 1, |
|
sizeof(*certs)); |
|
debug2("%s: %s", argv[i], sshkey_ssh_name(k)); |
|
certs[ncerts++] = k; |
|
} |
|
debug2_f("loaded %zu certificates", ncerts); |
if (update_card(agent_fd, !deleting, pkcs11provider, |
if (update_card(agent_fd, !deleting, pkcs11provider, |
qflag, dest_constraints, ndest_constraints) == -1) |
qflag, key_only, cert_only, |
|
dest_constraints, ndest_constraints, |
|
certs, ncerts) == -1) |
ret = 1; |
ret = 1; |
goto done; |
goto done; |
} |
} |
|
|
default_files[i]); |
default_files[i]); |
if (stat(buf, &st) == -1) |
if (stat(buf, &st) == -1) |
continue; |
continue; |
if (do_file(agent_fd, deleting, key_only, buf, |
if (do_file(agent_fd, deleting, key_only, cert_only, |
qflag, skprovider, |
buf, qflag, skprovider, |
dest_constraints, ndest_constraints) == -1) |
dest_constraints, ndest_constraints) == -1) |
ret = 1; |
ret = 1; |
else |
else |
|
|
ret = 1; |
ret = 1; |
} else { |
} else { |
for (i = 0; i < argc; i++) { |
for (i = 0; i < argc; i++) { |
if (do_file(agent_fd, deleting, key_only, |
if (do_file(agent_fd, deleting, key_only, cert_only, |
argv[i], qflag, skprovider, |
argv[i], qflag, skprovider, |
dest_constraints, ndest_constraints) == -1) |
dest_constraints, ndest_constraints) == -1) |
ret = 1; |
ret = 1; |