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 <markus@blueflash.cc>; ok markus@ OpenBSD-Commit-ID: 497fb792c0ddb4f1ba631b6eed526861f115dbe5
This commit is contained in:
parent
a8c807f195
commit
5c68ea8da7
153
sshconnect2.c
153
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 *);
|
||||
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 *);
|
||||
|
||||
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 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;
|
||||
|
|
Loading…
Reference in New Issue