version 1.482, 2018/07/09 21:03:30 |
version 1.483, 2018/07/11 18:53:29 |
|
|
#include "packet.h" |
#include "packet.h" |
#include "sshbuf.h" |
#include "sshbuf.h" |
#include "channels.h" |
#include "channels.h" |
#include "key.h" |
#include "sshkey.h" |
#include "authfd.h" |
#include "authfd.h" |
#include "authfile.h" |
#include "authfile.h" |
#include "pathnames.h" |
#include "pathnames.h" |
|
|
} |
} |
|
|
/* |
/* |
|
* 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 |
* Read per-user configuration file. Ignore the system wide config |
* file if the user specifies a config file on the command line. |
* file if the user specifies a config file on the command line. |
*/ |
*/ |
|
|
|
|
/* |
/* |
* If we successfully made the connection, load the host private key |
* If we successfully made the connection, load the host private key |
* in case we will need it later for combined rsa-rhosts |
* in case we will need it later for hostbased |
* authentication. This must be done before releasing extra |
* authentication. This must be done before releasing extra |
* privileges, because the file is only readable by root. |
* privileges, because the file is only readable by root. |
* If we cannot access the private keys, load the public keys |
* If we cannot access the private keys, load the public keys |
|
|
if (options.hostbased_authentication) { |
if (options.hostbased_authentication) { |
sensitive_data.nkeys = 11; |
sensitive_data.nkeys = 11; |
sensitive_data.keys = xcalloc(sensitive_data.nkeys, |
sensitive_data.keys = xcalloc(sensitive_data.nkeys, |
sizeof(struct sshkey)); /* XXX */ |
sizeof(struct sshkey)); |
|
|
|
/* XXX check errors? */ |
|
#define L_KEY(t,p,o) \ |
|
check_load(sshkey_load_private_type(t, p, "", \ |
|
&(sensitive_data.keys[o]), NULL, NULL), p, "key") |
|
#define L_KEYCERT(t,p,o) \ |
|
check_load(sshkey_load_private_cert(t, p, "", \ |
|
&(sensitive_data.keys[o]), NULL), p, "cert and key") |
|
#define L_PUBKEY(p,o) \ |
|
check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \ |
|
p, "pubkey") |
|
#define L_CERT(p,o) \ |
|
check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert") |
|
|
PRIV_START; |
PRIV_START; |
sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, |
L_KEYCERT(KEY_ECDSA, _PATH_HOST_ECDSA_KEY_FILE, 1); |
_PATH_HOST_ECDSA_KEY_FILE, "", NULL); |
L_KEYCERT(KEY_ED25519, _PATH_HOST_ED25519_KEY_FILE, 2); |
sensitive_data.keys[2] = key_load_private_cert(KEY_ED25519, |
L_KEYCERT(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, 3); |
_PATH_HOST_ED25519_KEY_FILE, "", NULL); |
L_KEYCERT(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, 4); |
sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, |
L_KEY(KEY_ECDSA, _PATH_HOST_ECDSA_KEY_FILE, 5); |
_PATH_HOST_RSA_KEY_FILE, "", NULL); |
L_KEY(KEY_ED25519, _PATH_HOST_ED25519_KEY_FILE, 6); |
sensitive_data.keys[4] = key_load_private_cert(KEY_DSA, |
L_KEY(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, 7); |
_PATH_HOST_DSA_KEY_FILE, "", NULL); |
L_KEY(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, 8); |
sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA, |
L_KEYCERT(KEY_XMSS, _PATH_HOST_XMSS_KEY_FILE, 9); |
_PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); |
L_KEY(KEY_XMSS, _PATH_HOST_XMSS_KEY_FILE, 10); |
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; |
PRIV_END; |
|
|
if (options.hostbased_authentication == 1 && |
if (options.hostbased_authentication == 1 && |
|
|
sensitive_data.keys[6] == NULL && |
sensitive_data.keys[6] == NULL && |
sensitive_data.keys[7] == NULL && |
sensitive_data.keys[7] == NULL && |
sensitive_data.keys[8] == NULL && |
sensitive_data.keys[8] == NULL && |
sensitive_data.keys[9] == NULL) { |
sensitive_data.keys[9] == NULL && |
sensitive_data.keys[1] = key_load_cert( |
sensitive_data.keys[10] == NULL) { |
_PATH_HOST_ECDSA_KEY_FILE); |
L_CERT(_PATH_HOST_ECDSA_KEY_FILE, 1); |
sensitive_data.keys[2] = key_load_cert( |
L_CERT(_PATH_HOST_ED25519_KEY_FILE, 2); |
_PATH_HOST_ED25519_KEY_FILE); |
L_CERT(_PATH_HOST_RSA_KEY_FILE, 3); |
sensitive_data.keys[3] = key_load_cert( |
L_CERT(_PATH_HOST_DSA_KEY_FILE, 4); |
_PATH_HOST_RSA_KEY_FILE); |
L_PUBKEY(_PATH_HOST_ECDSA_KEY_FILE, 5); |
sensitive_data.keys[4] = key_load_cert( |
L_PUBKEY(_PATH_HOST_ED25519_KEY_FILE, 6); |
_PATH_HOST_DSA_KEY_FILE); |
L_PUBKEY(_PATH_HOST_RSA_KEY_FILE, 7); |
sensitive_data.keys[5] = key_load_public( |
L_PUBKEY(_PATH_HOST_DSA_KEY_FILE, 8); |
_PATH_HOST_ECDSA_KEY_FILE, NULL); |
L_CERT(_PATH_HOST_XMSS_KEY_FILE, 9); |
sensitive_data.keys[6] = key_load_public( |
L_PUBKEY(_PATH_HOST_XMSS_KEY_FILE, 10); |
_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; |
sensitive_data.external_keysign = 1; |
} |
} |
} |
} |
|
|
if (sensitive_data.keys[i] != NULL) { |
if (sensitive_data.keys[i] != NULL) { |
/* Destroys contents safely */ |
/* Destroys contents safely */ |
debug3("clear hostkey %d", i); |
debug3("clear hostkey %d", i); |
key_free(sensitive_data.keys[i]); |
sshkey_free(sensitive_data.keys[i]); |
sensitive_data.keys[i] = NULL; |
sensitive_data.keys[i] = NULL; |
} |
} |
} |
} |
|
|
free(options.identity_files[i]); |
free(options.identity_files[i]); |
options.identity_files[i] = NULL; |
options.identity_files[i] = NULL; |
if (options.identity_keys[i]) { |
if (options.identity_keys[i]) { |
key_free(options.identity_keys[i]); |
sshkey_free(options.identity_keys[i]); |
options.identity_keys[i] = NULL; |
options.identity_keys[i] = NULL; |
} |
} |
} |
} |
|
|
&keys)) > 0) { |
&keys)) > 0) { |
for (i = 0; i < nkeys; i++) { |
for (i = 0; i < nkeys; i++) { |
if (n_ids >= SSH_MAX_IDENTITY_FILES) { |
if (n_ids >= SSH_MAX_IDENTITY_FILES) { |
key_free(keys[i]); |
sshkey_free(keys[i]); |
continue; |
continue; |
} |
} |
identity_keys[n_ids] = keys[i]; |
identity_keys[n_ids] = keys[i]; |
|
|
"u", pw->pw_name, "l", thishost, "h", host, |
"u", pw->pw_name, "l", thishost, "h", host, |
"r", options.user, (char *)NULL); |
"r", options.user, (char *)NULL); |
free(cp); |
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, |
debug("identity file %s type %d", filename, |
public ? public->type : -1); |
public ? public->type : -1); |
free(options.identity_files[i]); |
free(options.identity_files[i]); |
|
|
if (options.num_certificate_files != 0) |
if (options.num_certificate_files != 0) |
continue; |
continue; |
xasprintf(&cp, "%s-cert", filename); |
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, |
debug("identity file %s type %d", cp, |
public ? public->type : -1); |
public ? public->type : -1); |
if (public == NULL) { |
if (public == NULL) { |
free(cp); |
free(cp); |
continue; |
continue; |
} |
} |
if (!key_is_cert(public)) { |
if (!sshkey_is_cert(public)) { |
debug("%s: key %s type %s is not a certificate", |
debug("%s: key %s type %s is not a certificate", |
__func__, cp, key_type(public)); |
__func__, cp, sshkey_type(public)); |
key_free(public); |
sshkey_free(public); |
free(cp); |
free(cp); |
continue; |
continue; |
} |
} |
|
|
(char *)NULL); |
(char *)NULL); |
free(cp); |
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, |
debug("certificate file %s type %d", filename, |
public ? public->type : -1); |
public ? public->type : -1); |
free(options.certificate_files[i]); |
free(options.certificate_files[i]); |
|
|
free(filename); |
free(filename); |
continue; |
continue; |
} |
} |
if (!key_is_cert(public)) { |
if (!sshkey_is_cert(public)) { |
debug("%s: key %s type %s is not a certificate", |
debug("%s: key %s type %s is not a certificate", |
__func__, filename, key_type(public)); |
__func__, filename, sshkey_type(public)); |
key_free(public); |
sshkey_free(public); |
free(filename); |
free(filename); |
continue; |
continue; |
} |
} |