summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c141
1 files changed, 77 insertions, 64 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index f8a54beea949..be9397e481bd 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.255 2017/03/11 23:40:26 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.266 2017/08/27 00:38:41 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -93,7 +93,7 @@ char *xxx_host;
struct sockaddr *xxx_hostaddr;
static int
-verify_host_key_callback(Key *hostkey, struct ssh *ssh)
+verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
{
if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
fatal("Host key verification failed.");
@@ -217,7 +217,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
kex->server_version_string=server_version_string;
kex->verify_host_key=&verify_host_key_callback;
- dispatch_run(DISPATCH_BLOCK, &kex->done, active_state);
+ ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done);
/* remove ext-info from the KEX proposals for rekeying */
myproposal[PROPOSAL_KEX_ALGS] =
@@ -287,16 +287,16 @@ struct cauthmethod {
int *batch_flag; /* flag in option struct that disables method */
};
-int input_userauth_service_accept(int, u_int32_t, void *);
-int input_userauth_ext_info(int, u_int32_t, void *);
-int input_userauth_success(int, u_int32_t, void *);
-int input_userauth_success_unexpected(int, u_int32_t, void *);
-int input_userauth_failure(int, u_int32_t, void *);
-int input_userauth_banner(int, u_int32_t, void *);
-int input_userauth_error(int, u_int32_t, void *);
-int input_userauth_info_req(int, u_int32_t, void *);
-int input_userauth_pk_ok(int, u_int32_t, void *);
-int input_userauth_passwd_changereq(int, u_int32_t, void *);
+int input_userauth_service_accept(int, u_int32_t, struct ssh *);
+int input_userauth_ext_info(int, u_int32_t, struct ssh *);
+int input_userauth_success(int, u_int32_t, struct ssh *);
+int input_userauth_success_unexpected(int, u_int32_t, struct ssh *);
+int input_userauth_failure(int, u_int32_t, struct ssh *);
+int input_userauth_banner(int, u_int32_t, struct ssh *);
+int input_userauth_error(int, u_int32_t, struct ssh *);
+int input_userauth_info_req(int, u_int32_t, struct ssh *);
+int input_userauth_pk_ok(int, u_int32_t, struct ssh *);
+int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *);
int userauth_none(Authctxt *);
int userauth_pubkey(Authctxt *);
@@ -306,11 +306,11 @@ int userauth_hostbased(Authctxt *);
#ifdef GSSAPI
int userauth_gssapi(Authctxt *authctxt);
-int input_gssapi_response(int type, u_int32_t, void *);
-int input_gssapi_token(int type, u_int32_t, void *);
-int input_gssapi_hash(int type, u_int32_t, void *);
-int input_gssapi_error(int, u_int32_t, void *);
-int input_gssapi_errtok(int, u_int32_t, void *);
+int input_gssapi_response(int type, u_int32_t, struct ssh *);
+int input_gssapi_token(int type, u_int32_t, struct ssh *);
+int input_gssapi_hash(int type, u_int32_t, struct ssh *);
+int input_gssapi_error(int, u_int32_t, struct ssh *);
+int input_gssapi_errtok(int, u_int32_t, struct ssh *);
#endif
void userauth(Authctxt *, char *);
@@ -319,7 +319,7 @@ static int sign_and_send_pubkey(Authctxt *, Identity *);
static void pubkey_prepare(Authctxt *);
static void pubkey_cleanup(Authctxt *);
static void pubkey_reset(Authctxt *);
-static Key *load_identity_file(Identity *);
+static struct sshkey *load_identity_file(Identity *);
static Authmethod *authmethod_get(char *authlist);
static Authmethod *authmethod_lookup(const char *name);
@@ -397,10 +397,12 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
(r = sshpkt_send(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
+ ssh->authctxt = &authctxt;
ssh_dispatch_init(ssh, &input_userauth_error);
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info);
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept);
- ssh_dispatch_run(ssh, DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
+ ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */
+ ssh->authctxt = NULL;
pubkey_cleanup(&authctxt);
ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
@@ -412,10 +414,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
/* ARGSUSED */
int
-input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt)
+input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
- struct ssh *ssh = active_state;
+ Authctxt *authctxt = ssh->authctxt;
int r;
if (ssh_packet_remaining(ssh) > 0) {
@@ -446,9 +447,9 @@ input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt)
/* ARGSUSED */
int
-input_userauth_ext_info(int type, u_int32_t seqnr, void *ctxt)
+input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh)
{
- return kex_input_ext_info(type, seqnr, active_state);
+ return kex_input_ext_info(type, seqnr, ssh);
}
void
@@ -468,7 +469,8 @@ userauth(Authctxt *authctxt, char *authlist)
for (;;) {
Authmethod *method = authmethod_get(authlist);
if (method == NULL)
- fatal("Permission denied (%s).", authlist);
+ fatal("%s@%s: Permission denied (%s).",
+ authctxt->server_user, authctxt->host, authlist);
authctxt->method = method;
/* reset the per method handler */
@@ -488,7 +490,7 @@ userauth(Authctxt *authctxt, char *authlist)
/* ARGSUSED */
int
-input_userauth_error(int type, u_int32_t seq, void *ctxt)
+input_userauth_error(int type, u_int32_t seq, struct ssh *ssh)
{
fatal("input_userauth_error: bad message during authentication: "
"type %d", type);
@@ -497,7 +499,7 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
-input_userauth_banner(int type, u_int32_t seq, void *ctxt)
+input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh)
{
char *msg, *lang;
u_int len;
@@ -514,9 +516,9 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
-input_userauth_success(int type, u_int32_t seq, void *ctxt)
+input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
if (authctxt == NULL)
fatal("input_userauth_success: no authentication context");
@@ -531,9 +533,9 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
}
int
-input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
+input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
if (authctxt == NULL)
fatal("%s: no authentication context", __func__);
@@ -545,9 +547,9 @@ input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
-input_userauth_failure(int type, u_int32_t seq, void *ctxt)
+input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
char *authlist = NULL;
int partial;
@@ -571,10 +573,10 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
-input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
+input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
- Key *key = NULL;
+ Authctxt *authctxt = ssh->authctxt;
+ struct sshkey *key = NULL;
Identity *id = NULL;
Buffer b;
int pktype, sent = 0;
@@ -702,9 +704,9 @@ userauth_gssapi(Authctxt *authctxt)
}
static OM_uint32
-process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
+process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt = authctxt->methoddata;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
@@ -757,9 +759,9 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
/* ARGSUSED */
int
-input_gssapi_response(int type, u_int32_t plen, void *ctxt)
+input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
int oidlen;
char *oidv;
@@ -787,7 +789,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
free(oidv);
- if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) {
+ if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) {
/* Start again with next method on list */
debug("Trying to start again");
userauth(authctxt, NULL);
@@ -798,9 +800,9 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
/* ARGSUSED */
int
-input_gssapi_token(int type, u_int32_t plen, void *ctxt)
+input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
gss_buffer_desc recv_tok;
OM_uint32 status;
u_int slen;
@@ -813,7 +815,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
packet_check_eom();
- status = process_gssapi_token(ctxt, &recv_tok);
+ status = process_gssapi_token(ssh, &recv_tok);
free(recv_tok.value);
@@ -827,9 +829,9 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
/* ARGSUSED */
int
-input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
+input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc recv_tok;
@@ -858,7 +860,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
/* ARGSUSED */
int
-input_gssapi_error(int type, u_int32_t plen, void *ctxt)
+input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
{
char *msg;
char *lang;
@@ -893,7 +895,7 @@ int
userauth_passwd(Authctxt *authctxt)
{
static int attempt = 0;
- char prompt[150];
+ char prompt[256];
char *password;
const char *host = options.host_key_alias ? options.host_key_alias :
authctxt->host;
@@ -929,11 +931,11 @@ userauth_passwd(Authctxt *authctxt)
*/
/* ARGSUSED */
int
-input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
+input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
char *info, *lang, *password = NULL, *retype = NULL;
- char prompt[150];
+ char prompt[256];
const char *host;
debug2("input_userauth_passwd_changereq");
@@ -1015,7 +1017,7 @@ static int
identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
{
- Key *prv;
+ struct sshkey *prv;
int ret;
/* the agent supports this key */
@@ -1035,6 +1037,11 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
/* load the private key from the file */
if ((prv = load_identity_file(id)) == NULL)
return SSH_ERR_KEY_NOT_FOUND;
+ if (id->key != NULL && !sshkey_equal_public(prv, id->key)) {
+ error("%s: private key %s contents do not match public",
+ __func__, id->filename);
+ return SSH_ERR_KEY_NOT_FOUND;
+ }
ret = sshkey_sign(prv, sigp, lenp, data, datalen,
key_sign_encode(prv), compat);
sshkey_free(prv);
@@ -1225,10 +1232,10 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
return 1;
}
-static Key *
+static struct sshkey *
load_identity_file(Identity *id)
{
- Key *private = NULL;
+ struct sshkey *private = NULL;
char prompt[300], *passphrase, *comment;
int r, perm_ok = 0, quit = 0, i;
struct stat st;
@@ -1317,8 +1324,6 @@ pubkey_prepare(Authctxt *authctxt)
/* list of keys stored in the filesystem and PKCS#11 */
for (i = 0; i < options.num_identity_files; i++) {
key = options.identity_keys[i];
- if (key && key->type == KEY_RSA1)
- continue;
if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER)
continue;
options.identity_keys[i] = NULL;
@@ -1347,7 +1352,7 @@ pubkey_prepare(Authctxt *authctxt)
if (r != SSH_ERR_AGENT_NOT_PRESENT)
debug("%s: ssh_get_authentication_socket: %s",
__func__, ssh_err(r));
- } else if ((r = ssh_fetch_identitylist(agent_fd, 2, &idlist)) != 0) {
+ } else if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) {
if (r != SSH_ERR_AGENT_NO_IDENTITIES)
debug("%s: ssh_fetch_identitylist: %s",
__func__, ssh_err(r));
@@ -1471,7 +1476,7 @@ try_identity(Identity *id)
key_type(id->key), id->filename);
return (0);
}
- return (id->key->type != KEY_RSA1);
+ return 1;
}
int
@@ -1479,6 +1484,7 @@ userauth_pubkey(Authctxt *authctxt)
{
Identity *id;
int sent = 0;
+ char *fp;
while ((id = TAILQ_FIRST(&authctxt->keys))) {
if (id->tried++)
@@ -1493,8 +1499,16 @@ userauth_pubkey(Authctxt *authctxt)
*/
if (id->key != NULL) {
if (try_identity(id)) {
- debug("Offering %s public key: %s",
- key_type(id->key), id->filename);
+ if ((fp = sshkey_fingerprint(id->key,
+ options.fingerprint_hash,
+ SSH_FP_DEFAULT)) == NULL) {
+ error("%s: sshkey_fingerprint failed",
+ __func__);
+ return 0;
+ }
+ debug("Offering public key: %s %s %s",
+ sshkey_type(id->key), fp, id->filename);
+ free(fp);
sent = send_pubkey_test(authctxt, id);
}
} else {
@@ -1552,9 +1566,9 @@ userauth_kbdint(Authctxt *authctxt)
* parse INFO_REQUEST, prompt user and send INFO_RESPONSE
*/
int
-input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
+input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
{
- Authctxt *authctxt = ctxt;
+ Authctxt *authctxt = ssh->authctxt;
char *name, *inst, *lang, *prompt, *response;
u_int num_prompts, i;
int echo = 0;
@@ -1755,7 +1769,6 @@ userauth_hostbased(Authctxt *authctxt)
private = NULL;
for (i = 0; i < authctxt->sensitive->nkeys; i++) {
if (authctxt->sensitive->keys[i] == NULL ||
- authctxt->sensitive->keys[i]->type == KEY_RSA1 ||
authctxt->sensitive->keys[i]->type == KEY_UNSPEC)
continue;
if (match_pattern_list(