summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-02-11 09:44:42 +0000
committerDamien Miller <djm@mindrot.org>2019-02-11 20:48:16 +1100
commit5c68ea8da790d711e6dd5f4c30d089c54032c59a (patch)
tree954417129df7d64e39781ba826652b7988c1f48d
parenta8c807f1956f81a92a758d3d0237d0ff06d0be5d (diff)
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
-rw-r--r--sshconnect2.c155
1 files changed, 88 insertions, 67 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 2aa7b993..6d37e92f 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;