From 5c68ea8da790d711e6dd5f4c30d089c54032c59a Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Mon, 11 Feb 2019 09:44:42 +0000 Subject: upstream: cleanup GSSAPI authentication context after completion of the authmethod. Move function-static GSSAPI state to the client Authctxt structure. Make static a bunch of functions that aren't used outside this file. Based on patch from Markus Schmidt ; ok markus@ OpenBSD-Commit-ID: 497fb792c0ddb4f1ba631b6eed526861f115dbe5 --- sshconnect2.c | 155 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 88 insertions(+), 67 deletions(-) diff --git a/sshconnect2.c b/sshconnect2.c index 2aa7b9933..6d37e92f7 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.301 2019/01/21 10:38:54 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.302 2019/02/11 09:44:42 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -265,6 +265,11 @@ struct cauthctxt { struct cauthmethod *method; sig_atomic_t success; char *authlist; +#ifdef GSSAPI + /* gssapi */ + gss_OID_set gss_supported_mechs; + u_int mech_tried; +#endif /* pubkey */ struct idlist keys; int agent_fd; @@ -289,37 +294,36 @@ struct cauthmethod { int *batch_flag; /* flag in option struct that disables method */ }; -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(struct ssh *); -int userauth_pubkey(struct ssh *); -int userauth_passwd(struct ssh *); -int userauth_kbdint(struct ssh *); -int userauth_hostbased(struct ssh *); +static int input_userauth_service_accept(int, u_int32_t, struct ssh *); +static int input_userauth_ext_info(int, u_int32_t, struct ssh *); +static int input_userauth_success(int, u_int32_t, struct ssh *); +static int input_userauth_failure(int, u_int32_t, struct ssh *); +static int input_userauth_banner(int, u_int32_t, struct ssh *); +static int input_userauth_error(int, u_int32_t, struct ssh *); +static int input_userauth_info_req(int, u_int32_t, struct ssh *); +static int input_userauth_pk_ok(int, u_int32_t, struct ssh *); +static int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *); + +static int userauth_none(struct ssh *); +static int userauth_pubkey(struct ssh *); +static void userauth_pubkey_cleanup(struct ssh *); +static int userauth_passwd(struct ssh *); +static int userauth_kbdint(struct ssh *); +static int userauth_hostbased(struct ssh *); #ifdef GSSAPI -int userauth_gssapi(struct ssh *); -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 *); +static int userauth_gssapi(struct ssh *); +static void userauth_gssapi_cleanup(struct ssh *); +static int input_gssapi_response(int type, u_int32_t, struct ssh *); +static int input_gssapi_token(int type, u_int32_t, struct ssh *); +static int input_gssapi_error(int, u_int32_t, struct ssh *); +static int input_gssapi_errtok(int, u_int32_t, struct ssh *); #endif void userauth(struct ssh *, char *); static int sign_and_send_pubkey(struct ssh *ssh, Identity *); static void pubkey_prepare(Authctxt *); -static void pubkey_cleanup(Authctxt *); static void pubkey_reset(Authctxt *); static struct sshkey *load_identity_file(Identity *); @@ -331,7 +335,7 @@ Authmethod authmethods[] = { #ifdef GSSAPI {"gssapi-with-mic", userauth_gssapi, - NULL, + userauth_gssapi_cleanup, &options.gss_authentication, NULL}, #endif @@ -342,7 +346,7 @@ Authmethod authmethods[] = { NULL}, {"publickey", userauth_pubkey, - NULL, + userauth_pubkey_cleanup, &options.pubkey_authentication, NULL}, {"keyboard-interactive", @@ -390,6 +394,10 @@ ssh_userauth2(struct ssh *ssh, const char *local_user, authctxt.info_req_seen = 0; authctxt.attempt_kbdint = 0; authctxt.attempt_passwd = 0; +#if GSSAPI + authctxt.gss_supported_mechs = NULL; + authctxt.mech_tried = 0; +#endif authctxt.agent_fd = -1; pubkey_prepare(&authctxt); if (authctxt.method == NULL) { @@ -409,7 +417,6 @@ ssh_userauth2(struct ssh *ssh, const char *local_user, 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); if (!authctxt.success) @@ -418,7 +425,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user, } /* ARGSUSED */ -int +static int input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) { int r; @@ -450,7 +457,7 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) } /* ARGSUSED */ -int +static int input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh) { return kex_input_ext_info(type, seqnr, ssh); @@ -495,7 +502,7 @@ userauth(struct ssh *ssh, char *authlist) } /* ARGSUSED */ -int +static int input_userauth_error(int type, u_int32_t seq, struct ssh *ssh) { fatal("%s: bad message during authentication: type %d", __func__, type); @@ -503,7 +510,7 @@ input_userauth_error(int type, u_int32_t seq, struct ssh *ssh) } /* ARGSUSED */ -int +static int input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) { char *msg = NULL; @@ -523,7 +530,7 @@ input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) } /* ARGSUSED */ -int +static int input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -540,7 +547,8 @@ input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) return 0; } -int +#if 0 +static int input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -552,9 +560,10 @@ input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh) authctxt->method->name); return 0; } +#endif /* ARGSUSED */ -int +static int input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -609,7 +618,7 @@ format_identity(Identity *id) } /* ARGSUSED */ -int +static int input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -680,35 +689,36 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) } #ifdef GSSAPI -int +static int userauth_gssapi(struct ssh *ssh) { Authctxt *authctxt = (Authctxt *)ssh->authctxt; Gssctxt *gssctxt = NULL; - static gss_OID_set gss_supported = NULL; - static u_int mech = 0; OM_uint32 min; int r, ok = 0; + gss_OID mech = NULL; /* Try one GSSAPI method at a time, rather than sending them all at * once. */ - if (gss_supported == NULL) - gss_indicate_mechs(&min, &gss_supported); + if (authctxt->gss_supported_mechs == NULL) + gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); - /* Check to see if the mechanism is usable before we offer it */ - while (mech < gss_supported->count && !ok) { + /* Check to see whether the mechanism is usable before we offer it */ + while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && + !ok) { + mech = &authctxt->gss_supported_mechs-> + elements[authctxt->mech_tried]; /* My DER encoding requires length<128 */ - if (gss_supported->elements[mech].length < 128 && - ssh_gssapi_check_mechanism(&gssctxt, - &gss_supported->elements[mech], authctxt->host)) { + if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, + mech, authctxt->host)) { ok = 1; /* Mechanism works */ } else { - mech++; + authctxt->mech_tried++; } } - if (!ok) + if (!ok || mech == NULL) return 0; authctxt->methoddata=(void *)gssctxt; @@ -718,14 +728,10 @@ userauth_gssapi(struct ssh *ssh) (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_u32(ssh, 1)) != 0 || - (r = sshpkt_put_u32(ssh, - (gss_supported->elements[mech].length) + 2)) != 0 || + (r = sshpkt_put_u32(ssh, (mech->length) + 2)) != 0 || (r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 || - (r = sshpkt_put_u8(ssh, - gss_supported->elements[mech].length)) != 0 || - (r = sshpkt_put(ssh, - gss_supported->elements[mech].elements, - gss_supported->elements[mech].length)) != 0 || + (r = sshpkt_put_u8(ssh, mech->length)) != 0 || + (r = sshpkt_put(ssh, mech->elements, mech->length)) != 0 || (r = sshpkt_send(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); @@ -734,11 +740,24 @@ userauth_gssapi(struct ssh *ssh) ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); - mech++; /* Move along to next candidate */ + authctxt->mech_tried++; /* Move along to next candidate */ return 1; } +static void +userauth_gssapi_cleanup(struct ssh *ssh) +{ + Authctxt *authctxt = (Authctxt *)ssh->authctxt; + Gssctxt *gssctxt = (Gssctxt *)authctxt->methoddata; + + ssh_gssapi_delete_ctx(&gssctxt); + authctxt->methoddata = NULL; + + free(authctxt->gss_supported_mechs); + authctxt->gss_supported_mechs = NULL; +} + static OM_uint32 process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) { @@ -806,7 +825,7 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) } /* ARGSUSED */ -int +static int input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -851,7 +870,7 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) } /* ARGSUSED */ -int +static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -884,7 +903,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) } /* ARGSUSED */ -int +static int input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -919,7 +938,7 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) } /* ARGSUSED */ -int +static int input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) { char *msg = NULL; @@ -940,7 +959,7 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) } #endif /* GSSAPI */ -int +static int userauth_none(struct ssh *ssh) { Authctxt *authctxt = (Authctxt *)ssh->authctxt; @@ -956,7 +975,7 @@ userauth_none(struct ssh *ssh) return 1; } -int +static int userauth_passwd(struct ssh *ssh) { Authctxt *authctxt = (Authctxt *)ssh->authctxt; @@ -997,7 +1016,7 @@ userauth_passwd(struct ssh *ssh) * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST */ /* ARGSUSED */ -int +static int input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -1619,8 +1638,10 @@ pubkey_prepare(Authctxt *authctxt) } static void -pubkey_cleanup(Authctxt *authctxt) +userauth_pubkey_cleanup(struct ssh *ssh) { + Authctxt *authctxt = (Authctxt *)ssh->authctxt; + Identity *id; if (authctxt->agent_fd != -1) { @@ -1659,7 +1680,7 @@ try_identity(Identity *id) return 1; } -int +static int userauth_pubkey(struct ssh *ssh) { Authctxt *authctxt = (Authctxt *)ssh->authctxt; @@ -1707,7 +1728,7 @@ userauth_pubkey(struct ssh *ssh) /* * Send userauth request message specifying keyboard-interactive method. */ -int +static int userauth_kbdint(struct ssh *ssh) { Authctxt *authctxt = (Authctxt *)ssh->authctxt; @@ -1740,7 +1761,7 @@ userauth_kbdint(struct ssh *ssh) /* * parse INFO_REQUEST, prompt user and send INFO_RESPONSE */ -int +static int input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -1920,7 +1941,7 @@ ssh_keysign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, return 0; } -int +static int userauth_hostbased(struct ssh *ssh) { Authctxt *authctxt = (Authctxt *)ssh->authctxt; -- cgit v1.2.3