aboutsummaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c321
1 files changed, 147 insertions, 174 deletions
diff --git a/ssh.c b/ssh.c
index d3619fe292a2..ce628848c6f5 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.475 2018/02/23 15:58:38 markus Exp $ */
+/* $OpenBSD: ssh.c,v 1.490 2018/07/27 05:34:42 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -87,9 +87,9 @@
#include "cipher.h"
#include "digest.h"
#include "packet.h"
-#include "buffer.h"
+#include "sshbuf.h"
#include "channels.h"
-#include "key.h"
+#include "sshkey.h"
#include "authfd.h"
#include "authfile.h"
#include "pathnames.h"
@@ -104,7 +104,6 @@
#include "sshpty.h"
#include "match.h"
#include "msg.h"
-#include "uidswap.h"
#include "version.h"
#include "ssherr.h"
#include "myproposal.h"
@@ -178,12 +177,8 @@ struct sockaddr_storage hostaddr;
/* Private host keys. */
Sensitive sensitive_data;
-/* Original real UID. */
-uid_t original_real_uid;
-uid_t original_effective_uid;
-
/* command to be executed */
-Buffer command;
+struct sshbuf *command;
/* Should we execute a command or invoke a subsystem? */
int subsystem_flag = 0;
@@ -224,7 +219,7 @@ tilde_expand_paths(char **paths, u_int num_paths)
char *cp;
for (i = 0; i < num_paths; i++) {
- cp = tilde_expand_filename(paths[i], original_real_uid);
+ cp = tilde_expand_filename(paths[i], getuid());
free(paths[i]);
paths[i] = cp;
}
@@ -504,6 +499,30 @@ resolve_canonicalize(char **hostp, int port)
}
/*
+ * Check the result of hostkey loading, ignoring some errors and
+ * fatal()ing for others.
+ */
+static void
+check_load(int r, const char *path, const char *message)
+{
+ switch (r) {
+ case 0:
+ break;
+ case SSH_ERR_INTERNAL_ERROR:
+ case SSH_ERR_ALLOC_FAIL:
+ fatal("load %s \"%s\": %s", message, path, ssh_err(r));
+ case SSH_ERR_SYSTEM_ERROR:
+ /* Ignore missing files */
+ if (errno == ENOENT)
+ break;
+ /* FALLTHROUGH */
+ default:
+ error("load %s \"%s\": %s", message, path, ssh_err(r));
+ break;
+ }
+}
+
+/*
* Read per-user configuration file. Ignore the system wide config
* file if the user specifies a config file on the command line.
*/
@@ -597,35 +616,10 @@ main(int ac, char **av)
*/
closefrom(STDERR_FILENO + 1);
- /*
- * Save the original real uid. It will be needed later (uid-swapping
- * may clobber the real uid).
- */
- original_real_uid = getuid();
- original_effective_uid = geteuid();
-
- /*
- * Use uid-swapping to give up root privileges for the duration of
- * option processing. We will re-instantiate the rights when we are
- * ready to create the privileged port, and will permanently drop
- * them when the port has been created (actually, when the connection
- * has been made, as we may need to create the port several times).
- */
- PRIV_END;
-
-#ifdef HAVE_SETRLIMIT
- /* If we are installed setuid root be careful to not drop core. */
- if (original_real_uid != original_effective_uid) {
- struct rlimit rlim;
- rlim.rlim_cur = rlim.rlim_max = 0;
- if (setrlimit(RLIMIT_CORE, &rlim) < 0)
- fatal("setrlimit failed: %.100s", strerror(errno));
- }
-#endif
/* Get user data. */
- pw = getpwuid(original_real_uid);
+ pw = getpwuid(getuid());
if (!pw) {
- logit("No user exists for uid %lu", (u_long)original_real_uid);
+ logit("No user exists for uid %lu", (u_long)getuid());
exit(255);
}
/* Take a copy of the returned structure. */
@@ -728,7 +722,6 @@ main(int ac, char **av)
fatal("Invalid multiplex command.");
break;
case 'P': /* deprecated */
- options.use_privileged_port = 0;
break;
case 'Q':
cp = NULL;
@@ -769,7 +762,7 @@ main(int ac, char **av)
options.gss_deleg_creds = 1;
break;
case 'i':
- p = tilde_expand_filename(optarg, original_real_uid);
+ p = tilde_expand_filename(optarg, getuid());
if (stat(p, &st) < 0)
fprintf(stderr, "Warning: Identity file %s "
"not accessible: %s.\n", p,
@@ -1042,7 +1035,8 @@ main(int ac, char **av)
#endif
/* Initialize the command to execute on remote host. */
- buffer_init(&command);
+ if ((command = sshbuf_new()) == NULL)
+ fatal("sshbuf_new failed");
/*
* Save the command to execute on the remote host in a buffer. There
@@ -1059,9 +1053,10 @@ main(int ac, char **av)
} else {
/* A command has been specified. Store it into the buffer. */
for (i = 0; i < ac; i++) {
- if (i)
- buffer_append(&command, " ", 1);
- buffer_append(&command, av[i], strlen(av[i]));
+ if ((r = sshbuf_putf(command, "%s%s",
+ i ? " " : "", av[i])) != 0)
+ fatal("%s: buffer error: %s",
+ __func__, ssh_err(r));
}
}
@@ -1171,6 +1166,14 @@ main(int ac, char **av)
*/
if (options.jump_host != NULL) {
char port_s[8];
+ const char *sshbin = argv0;
+
+ /*
+ * Try to use SSH indicated by argv[0], but fall back to
+ * "ssh" if it appears unavailable.
+ */
+ if (strchr(argv0, '/') != NULL && access(argv0, X_OK) != 0)
+ sshbin = "ssh";
/* Consistency check */
if (options.proxy_command != NULL)
@@ -1179,7 +1182,8 @@ main(int ac, char **av)
options.proxy_use_fdpass = 0;
snprintf(port_s, sizeof(port_s), "%d", options.jump_port);
xasprintf(&options.proxy_command,
- "ssh%s%s%s%s%s%s%s%s%s%.*s -W '[%%h]:%%p' %s",
+ "%s%s%s%s%s%s%s%s%s%s%.*s -W '[%%h]:%%p' %s",
+ sshbin,
/* Optional "-l user" argument if jump_user set */
options.jump_user == NULL ? "" : " -l ",
options.jump_user == NULL ? "" : options.jump_user,
@@ -1220,16 +1224,12 @@ main(int ac, char **av)
}
if (options.connection_attempts <= 0)
fatal("Invalid number of ConnectionAttempts");
-#ifndef HAVE_CYGWIN
- if (original_effective_uid != 0)
- options.use_privileged_port = 0;
-#endif
- if (buffer_len(&command) != 0 && options.remote_command != NULL)
+ if (sshbuf_len(command) != 0 && options.remote_command != NULL)
fatal("Cannot execute command-line and remote command.");
/* Cannot fork to background if no command. */
- if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
+ if (fork_after_authentication_flag && sshbuf_len(command) == 0 &&
options.remote_command == NULL && !no_shell_flag)
fatal("Cannot fork into background without a command "
"to execute.");
@@ -1242,7 +1242,7 @@ main(int ac, char **av)
tty_flag = 1;
/* Allocate a tty by default if no command specified. */
- if (buffer_len(&command) == 0 && options.remote_command == NULL)
+ if (sshbuf_len(command) == 0 && options.remote_command == NULL)
tty_flag = options.request_tty != REQUEST_TTY_NO;
/* Force no tty */
@@ -1269,7 +1269,8 @@ main(int ac, char **av)
strlcpy(shorthost, thishost, sizeof(shorthost));
shorthost[strcspn(thishost, ".")] = '\0';
snprintf(portstr, sizeof(portstr), "%d", options.port);
- snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid);
+ snprintf(uidstr, sizeof(uidstr), "%llu",
+ (unsigned long long)pw->pw_uid);
if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
@@ -1294,6 +1295,7 @@ main(int ac, char **av)
"L", shorthost,
"d", pw->pw_dir,
"h", host,
+ "i", uidstr,
"l", thishost,
"n", host_arg,
"p", portstr,
@@ -1302,18 +1304,19 @@ main(int ac, char **av)
(char *)NULL);
debug3("expanded RemoteCommand: %s", options.remote_command);
free(cp);
- buffer_append(&command, options.remote_command,
- strlen(options.remote_command));
+ if ((r = sshbuf_put(command, options.remote_command,
+ strlen(options.remote_command))) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
if (options.control_path != NULL) {
- cp = tilde_expand_filename(options.control_path,
- original_real_uid);
+ cp = tilde_expand_filename(options.control_path, getuid());
free(options.control_path);
options.control_path = percent_expand(cp,
"C", conn_hash_hex,
"L", shorthost,
"h", host,
+ "i", uidstr,
"l", thishost,
"n", host_arg,
"p", portstr,
@@ -1323,7 +1326,6 @@ main(int ac, char **av)
(char *)NULL);
free(cp);
}
- free(conn_hash_hex);
if (config_test) {
dump_client_config(&options, host);
@@ -1357,8 +1359,7 @@ main(int ac, char **av)
/* Open a connection to the remote host. */
if (ssh_connect(ssh, host, addrs, &hostaddr, options.port,
options.address_family, options.connection_attempts,
- &timeout_ms, options.tcp_keep_alive,
- options.use_privileged_port) != 0)
+ &timeout_ms, options.tcp_keep_alive) != 0)
exit(255);
if (addrs != NULL)
@@ -1373,100 +1374,45 @@ main(int ac, char **av)
debug3("timeout: %d ms remain after connect", timeout_ms);
/*
- * If we successfully made the connection, load the host private key
- * in case we will need it later for combined rsa-rhosts
- * authentication. This must be done before releasing extra
- * privileges, because the file is only readable by root.
- * If we cannot access the private keys, load the public keys
- * instead and try to execute the ssh-keysign helper instead.
+ * If we successfully made the connection and we have hostbased auth
+ * enabled, load the public keys so we can later use the ssh-keysign
+ * helper to sign challenges.
*/
sensitive_data.nkeys = 0;
sensitive_data.keys = NULL;
- sensitive_data.external_keysign = 0;
if (options.hostbased_authentication) {
- sensitive_data.nkeys = 11;
+ sensitive_data.nkeys = 10;
sensitive_data.keys = xcalloc(sensitive_data.nkeys,
- sizeof(struct sshkey)); /* XXX */
- for (i = 0; i < sensitive_data.nkeys; i++)
- sensitive_data.keys[i] = NULL;
-
- PRIV_START;
-#ifdef OPENSSL_HAS_ECC
- sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA,
- _PATH_HOST_ECDSA_KEY_FILE, "", NULL);
-#endif
- sensitive_data.keys[2] = key_load_private_cert(KEY_ED25519,
- _PATH_HOST_ED25519_KEY_FILE, "", NULL);
- sensitive_data.keys[3] = key_load_private_cert(KEY_RSA,
- _PATH_HOST_RSA_KEY_FILE, "", NULL);
- sensitive_data.keys[4] = key_load_private_cert(KEY_DSA,
- _PATH_HOST_DSA_KEY_FILE, "", NULL);
-#ifdef OPENSSL_HAS_ECC
- sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA,
- _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL);
-#endif
- sensitive_data.keys[6] = key_load_private_type(KEY_ED25519,
- _PATH_HOST_ED25519_KEY_FILE, "", NULL, NULL);
- sensitive_data.keys[7] = key_load_private_type(KEY_RSA,
- _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
- sensitive_data.keys[8] = key_load_private_type(KEY_DSA,
- _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
- sensitive_data.keys[9] = key_load_private_cert(KEY_XMSS,
- _PATH_HOST_XMSS_KEY_FILE, "", NULL);
- sensitive_data.keys[10] = key_load_private_type(KEY_XMSS,
- _PATH_HOST_XMSS_KEY_FILE, "", NULL, NULL);
- PRIV_END;
-
- if (options.hostbased_authentication == 1 &&
- sensitive_data.keys[0] == NULL &&
- sensitive_data.keys[5] == NULL &&
- sensitive_data.keys[6] == NULL &&
- sensitive_data.keys[7] == NULL &&
- sensitive_data.keys[8] == NULL &&
- sensitive_data.keys[9] == NULL) {
-#ifdef OPENSSL_HAS_ECC
- sensitive_data.keys[1] = key_load_cert(
- _PATH_HOST_ECDSA_KEY_FILE);
-#endif
- sensitive_data.keys[2] = key_load_cert(
- _PATH_HOST_ED25519_KEY_FILE);
- sensitive_data.keys[3] = key_load_cert(
- _PATH_HOST_RSA_KEY_FILE);
- sensitive_data.keys[4] = key_load_cert(
- _PATH_HOST_DSA_KEY_FILE);
-#ifdef OPENSSL_HAS_ECC
- sensitive_data.keys[5] = key_load_public(
- _PATH_HOST_ECDSA_KEY_FILE, NULL);
-#endif
- sensitive_data.keys[6] = key_load_public(
- _PATH_HOST_ED25519_KEY_FILE, NULL);
- sensitive_data.keys[7] = key_load_public(
- _PATH_HOST_RSA_KEY_FILE, NULL);
- sensitive_data.keys[8] = key_load_public(
- _PATH_HOST_DSA_KEY_FILE, NULL);
- sensitive_data.keys[9] = key_load_cert(
- _PATH_HOST_XMSS_KEY_FILE);
- sensitive_data.keys[10] = key_load_public(
- _PATH_HOST_XMSS_KEY_FILE, NULL);
- sensitive_data.external_keysign = 1;
+ sizeof(struct sshkey));
+
+ /* XXX check errors? */
+#define L_PUBKEY(p,o) do { \
+ if ((o) >= sensitive_data.nkeys) \
+ fatal("%s pubkey out of array bounds", __func__); \
+ check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \
+ p, "pubkey"); \
+} while (0)
+#define L_CERT(p,o) do { \
+ if ((o) >= sensitive_data.nkeys) \
+ fatal("%s cert out of array bounds", __func__); \
+ check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \
+} while (0)
+
+ if (options.hostbased_authentication == 1) {
+ L_CERT(_PATH_HOST_ECDSA_KEY_FILE, 0);
+ L_CERT(_PATH_HOST_ED25519_KEY_FILE, 1);
+ L_CERT(_PATH_HOST_RSA_KEY_FILE, 2);
+ L_CERT(_PATH_HOST_DSA_KEY_FILE, 3);
+ L_PUBKEY(_PATH_HOST_ECDSA_KEY_FILE, 4);
+ L_PUBKEY(_PATH_HOST_ED25519_KEY_FILE, 5);
+ L_PUBKEY(_PATH_HOST_RSA_KEY_FILE, 6);
+ L_PUBKEY(_PATH_HOST_DSA_KEY_FILE, 7);
+ L_CERT(_PATH_HOST_XMSS_KEY_FILE, 8);
+ L_PUBKEY(_PATH_HOST_XMSS_KEY_FILE, 9);
}
}
- /*
- * Get rid of any extra privileges that we may have. We will no
- * longer need them. Also, extra privileges could make it very hard
- * to read identity files and other non-world-readable files from the
- * user's home directory if it happens to be on a NFS volume where
- * root is mapped to nobody.
- */
- if (original_effective_uid == 0) {
- PRIV_START;
- permanently_set_uid(pw);
- }
- /*
- * Now that we are back to our own permissions, create ~/.ssh
- * directory if it doesn't already exist.
- */
+ /* Create ~/.ssh * directory if it doesn't already exist. */
if (config == NULL) {
r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
@@ -1485,17 +1431,22 @@ main(int ac, char **av)
/* load options.identity_files */
load_public_identity_files(pw);
- /* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */
+ /* optionally set the SSH_AUTHSOCKET_ENV_NAME variable */
if (options.identity_agent &&
strcmp(options.identity_agent, SSH_AUTHSOCKET_ENV_NAME) != 0) {
if (strcmp(options.identity_agent, "none") == 0) {
unsetenv(SSH_AUTHSOCKET_ENV_NAME);
} else {
p = tilde_expand_filename(options.identity_agent,
- original_real_uid);
- cp = percent_expand(p, "d", pw->pw_dir,
- "u", pw->pw_name, "l", thishost, "h", host,
- "r", options.user, (char *)NULL);
+ getuid());
+ cp = percent_expand(p,
+ "d", pw->pw_dir,
+ "h", host,
+ "i", uidstr,
+ "l", thishost,
+ "r", options.user,
+ "u", pw->pw_name,
+ (char *)NULL);
setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1);
free(cp);
free(p);
@@ -1527,7 +1478,7 @@ main(int ac, char **av)
if (sensitive_data.keys[i] != NULL) {
/* Destroys contents safely */
debug3("clear hostkey %d", i);
- key_free(sensitive_data.keys[i]);
+ sshkey_free(sensitive_data.keys[i]);
sensitive_data.keys[i] = NULL;
}
}
@@ -1537,7 +1488,7 @@ main(int ac, char **av)
free(options.identity_files[i]);
options.identity_files[i] = NULL;
if (options.identity_keys[i]) {
- key_free(options.identity_keys[i]);
+ sshkey_free(options.identity_keys[i]);
options.identity_keys[i] = NULL;
}
}
@@ -1638,10 +1589,10 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
logit("Allocated port %u for remote forward to %s:%d",
rfwd->allocated_port,
rfwd->connect_host, rfwd->connect_port);
- channel_update_permitted_opens(ssh,
+ channel_update_permission(ssh,
rfwd->handle, rfwd->allocated_port);
} else {
- channel_update_permitted_opens(ssh, rfwd->handle, -1);
+ channel_update_permission(ssh, rfwd->handle, -1);
}
}
@@ -1830,7 +1781,7 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
options.ip_qos_interactive, options.ip_qos_bulk);
client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"),
- NULL, fileno(stdin), &command, environ);
+ NULL, fileno(stdin), command, environ);
}
/* open new channel for a session */
@@ -1900,6 +1851,7 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
"L", shorthost,
"d", pw->pw_dir,
"h", host,
+ "i", uidstr,
"l", thishost,
"n", host_arg,
"p", portstr,
@@ -2009,8 +1961,10 @@ load_public_identity_files(struct passwd *pw)
u_int n_ids, n_certs;
char *identity_files[SSH_MAX_IDENTITY_FILES];
struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES];
+ int identity_file_userprovided[SSH_MAX_IDENTITY_FILES];
char *certificate_files[SSH_MAX_CERTIFICATE_FILES];
struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
+ int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES];
#ifdef ENABLE_PKCS11
struct sshkey **keys;
int nkeys;
@@ -2019,8 +1973,12 @@ load_public_identity_files(struct passwd *pw)
n_ids = n_certs = 0;
memset(identity_files, 0, sizeof(identity_files));
memset(identity_keys, 0, sizeof(identity_keys));
+ memset(identity_file_userprovided, 0,
+ sizeof(identity_file_userprovided));
memset(certificate_files, 0, sizeof(certificate_files));
memset(certificates, 0, sizeof(certificates));
+ memset(certificate_file_userprovided, 0,
+ sizeof(certificate_file_userprovided));
#ifdef ENABLE_PKCS11
if (options.pkcs11_provider != NULL &&
@@ -2030,7 +1988,7 @@ load_public_identity_files(struct passwd *pw)
&keys)) > 0) {
for (i = 0; i < nkeys; i++) {
if (n_ids >= SSH_MAX_IDENTITY_FILES) {
- key_free(keys[i]);
+ sshkey_free(keys[i]);
continue;
}
identity_keys[n_ids] = keys[i];
@@ -2041,8 +1999,6 @@ load_public_identity_files(struct passwd *pw)
free(keys);
}
#endif /* ENABLE_PKCS11 */
- if ((pw = getpwuid(original_real_uid)) == NULL)
- fatal("load_public_identity_files: getpwuid failed");
for (i = 0; i < options.num_identity_files; i++) {
if (n_ids >= SSH_MAX_IDENTITY_FILES ||
strcasecmp(options.identity_files[i], "none") == 0) {
@@ -2050,19 +2006,20 @@ load_public_identity_files(struct passwd *pw)
options.identity_files[i] = NULL;
continue;
}
- cp = tilde_expand_filename(options.identity_files[i],
- original_real_uid);
+ cp = tilde_expand_filename(options.identity_files[i], getuid());
filename = percent_expand(cp, "d", pw->pw_dir,
"u", pw->pw_name, "l", thishost, "h", host,
"r", options.user, (char *)NULL);
free(cp);
- public = key_load_public(filename, NULL);
+ check_load(sshkey_load_public(filename, &public, NULL),
+ filename, "pubkey");
debug("identity file %s type %d", filename,
public ? public->type : -1);
free(options.identity_files[i]);
identity_files[n_ids] = filename;
identity_keys[n_ids] = public;
-
+ identity_file_userprovided[n_ids] =
+ options.identity_file_userprovided[i];
if (++n_ids >= SSH_MAX_IDENTITY_FILES)
continue;
@@ -2073,23 +2030,26 @@ load_public_identity_files(struct passwd *pw)
if (options.num_certificate_files != 0)
continue;
xasprintf(&cp, "%s-cert", filename);
- public = key_load_public(cp, NULL);
+ check_load(sshkey_load_public(cp, &public, NULL),
+ filename, "pubkey");
debug("identity file %s type %d", cp,
public ? public->type : -1);
if (public == NULL) {
free(cp);
continue;
}
- if (!key_is_cert(public)) {
+ if (!sshkey_is_cert(public)) {
debug("%s: key %s type %s is not a certificate",
- __func__, cp, key_type(public));
- key_free(public);
+ __func__, cp, sshkey_type(public));
+ sshkey_free(public);
free(cp);
continue;
}
/* NB. leave filename pointing to private key */
identity_files[n_ids] = xstrdup(filename);
identity_keys[n_ids] = public;
+ identity_file_userprovided[n_ids] =
+ options.identity_file_userprovided[i];
n_ids++;
}
@@ -2097,13 +2057,19 @@ load_public_identity_files(struct passwd *pw)
fatal("%s: too many certificates", __func__);
for (i = 0; i < options.num_certificate_files; i++) {
cp = tilde_expand_filename(options.certificate_files[i],
- original_real_uid);
- filename = percent_expand(cp, "d", pw->pw_dir,
- "u", pw->pw_name, "l", thishost, "h", host,
- "r", options.user, (char *)NULL);
+ getuid());
+ filename = percent_expand(cp,
+ "d", pw->pw_dir,
+ "h", host,
+ "i", uidstr,
+ "l", thishost,
+ "r", options.user,
+ "u", pw->pw_name,
+ (char *)NULL);
free(cp);
- public = key_load_public(filename, NULL);
+ check_load(sshkey_load_public(filename, &public, NULL),
+ filename, "certificate");
debug("certificate file %s type %d", filename,
public ? public->type : -1);
free(options.certificate_files[i]);
@@ -2112,26 +2078,33 @@ load_public_identity_files(struct passwd *pw)
free(filename);
continue;
}
- if (!key_is_cert(public)) {
+ if (!sshkey_is_cert(public)) {
debug("%s: key %s type %s is not a certificate",
- __func__, filename, key_type(public));
- key_free(public);
+ __func__, filename, sshkey_type(public));
+ sshkey_free(public);
free(filename);
continue;
}
certificate_files[n_certs] = filename;
certificates[n_certs] = public;
+ certificate_file_userprovided[n_certs] =
+ options.certificate_file_userprovided[i];
++n_certs;
}
options.num_identity_files = n_ids;
memcpy(options.identity_files, identity_files, sizeof(identity_files));
memcpy(options.identity_keys, identity_keys, sizeof(identity_keys));
+ memcpy(options.identity_file_userprovided,
+ identity_file_userprovided, sizeof(identity_file_userprovided));
options.num_certificate_files = n_certs;
memcpy(options.certificate_files,
certificate_files, sizeof(certificate_files));
memcpy(options.certificates, certificates, sizeof(certificates));
+ memcpy(options.certificate_file_userprovided,
+ certificate_file_userprovided,
+ sizeof(certificate_file_userprovided));
}
static void