[PATCH 2/2] move internal auth state in http_auth_state.

Nikos Mavrogiannopoulos nmav at redhat.com
Fri Feb 20 06:59:32 PST 2015


Signed-off-by: Nikos Mavrogiannopoulos <nmav at redhat.com>
---
 gssapi.c               | 40 ++++++++++++++++++++-------------------
 http.c                 | 21 ++++++++-------------
 ntlm.c                 | 38 ++++++++++++++++++-------------------
 openconnect-internal.h | 30 ++++++++++++++---------------
 sspi.c                 | 51 +++++++++++++++++++++++++-------------------------
 5 files changed, 89 insertions(+), 91 deletions(-)

diff --git a/gssapi.c b/gssapi.c
index 5fb78ba..5e44978 100644
--- a/gssapi.c
+++ b/gssapi.c
@@ -54,7 +54,8 @@ static const gss_OID_desc gss_mech_spnego = {
 	(void *)&spnego_OID
 };
 
-static int gssapi_setup(struct openconnect_info *vpninfo, const char *service, int proxy)
+static int gssapi_setup(struct openconnect_info *vpninfo, struct http_auth_state *auth_state,
+			const char *service, int proxy)
 {
 	OM_uint32 major, minor;
 	gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
@@ -67,7 +68,7 @@ static int gssapi_setup(struct openconnect_info *vpninfo, const char *service, i
 	token.value = name;
 
 	major = gss_import_name(&minor, &token, (gss_OID)GSS_C_NT_HOSTBASED_SERVICE,
-				&vpninfo->gss_target_name[proxy]);
+				&auth_state->gss_target_name);
 	free(name);
 	if (GSS_ERROR(major)) {
 		vpn_progress(vpninfo, PRG_ERR,
@@ -90,7 +91,7 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
 	gss_buffer_desc out = GSS_C_EMPTY_BUFFER;
 	gss_OID mech = GSS_C_NO_OID;
 
-	if (auth_state->state == AUTH_AVAILABLE && gssapi_setup(vpninfo, "HTTP", proxy)) {
+	if (auth_state->state == AUTH_AVAILABLE && gssapi_setup(vpninfo, auth_state, "HTTP", proxy)) {
 		auth_state->state = AUTH_FAILED;
 		return -EIO;
 	}
@@ -109,8 +110,8 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
 	}
 
 	major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL,
-				     &vpninfo->gss_context[proxy],
-				     vpninfo->gss_target_name[proxy],
+				     &auth_state->gss_context,
+				     auth_state->gss_target_name,
 				     (gss_OID)&gss_mech_spnego,
 				     GSS_C_MUTUAL_FLAG, GSS_C_INDEFINITE,
 				     GSS_C_NO_CHANNEL_BINDINGS, &in,
@@ -128,7 +129,7 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
 		print_gss_err(vpninfo, "gss_init_sec_context()", mech, major, minor);
 	fail_gssapi:
 		auth_state->state = AUTH_FAILED;
-		cleanup_gssapi_auth(vpninfo, proxy, auth_state);
+		cleanup_gssapi_auth(vpninfo, auth_state);
 		/* If we were *trying*, then -EAGAIN. Else -ENOENT to let another
 		   auth method try without having to reconnect first. */
 		return in.value ? -EAGAIN : -ENOENT;
@@ -145,20 +146,20 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
 }
 
 /* auth_state is NULL when called from socks_gssapi_auth() */
-void cleanup_gssapi_auth(struct openconnect_info *vpninfo, int proxy,
+void cleanup_gssapi_auth(struct openconnect_info *vpninfo,
 			 struct http_auth_state *auth_state)
 {
 	OM_uint32 minor;
 
-	if (vpninfo->gss_target_name[proxy] != GSS_C_NO_NAME)
-		gss_release_name(&minor, &vpninfo->gss_target_name[proxy]);
+	if (auth_state->gss_target_name != GSS_C_NO_NAME)
+		gss_release_name(&minor, &auth_state->gss_target_name);
 
-	if (vpninfo->gss_context[proxy] != GSS_C_NO_CONTEXT)
-		gss_delete_sec_context(&minor, &vpninfo->gss_context[proxy], GSS_C_NO_BUFFER);
+	if (auth_state->gss_context != GSS_C_NO_CONTEXT)
+		gss_delete_sec_context(&minor, &auth_state->gss_context, GSS_C_NO_BUFFER);
 
 	/* Shouldn't be necessary, but make sure... */
-	vpninfo->gss_target_name[proxy] = GSS_C_NO_NAME;
-	vpninfo->gss_context[proxy] = GSS_C_NO_CONTEXT;
+	auth_state->gss_target_name = GSS_C_NO_NAME;
+	auth_state->gss_context = GSS_C_NO_CONTEXT;
 }
 
 int socks_gssapi_auth(struct openconnect_info *vpninfo)
@@ -170,16 +171,17 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 	unsigned char *pktbuf;
 	int i;
 	int ret = -EIO;
+	struct http_auth_state *auth_state = &vpninfo->proxy_auth[AUTH_TYPE_GSSAPI];
 
-	if (gssapi_setup(vpninfo, "rcmd", 1))
+	if (gssapi_setup(vpninfo, auth_state, "rcmd", 1))
 		return -EIO;
 
 	pktbuf = malloc(65538);
 	if (!pktbuf)
 		return -ENOMEM;
 	while (1) {
-		major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &vpninfo->gss_context[1],
-					     vpninfo->gss_target_name[1], (gss_OID)&gss_mech_spnego,
+		major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &auth_state->gss_context,
+					     auth_state->gss_target_name, (gss_OID)&gss_mech_spnego,
 					     GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_DELEG_FLAG | GSS_C_SEQUENCE_FLAG,
 					     GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &in, &mech,
 					     &out, NULL, NULL);
@@ -267,7 +269,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 		in.value = pktbuf;
 		in.length = 1;
 
-		major = gss_wrap(&minor, vpninfo->gss_context[1], 0,
+		major = gss_wrap(&minor, auth_state->gss_context, 0,
 				 GSS_C_QOP_DEFAULT, &in, NULL, &out);
 		if (major != GSS_S_COMPLETE) {
 			print_gss_err(vpninfo, "gss_wrap()", mech, major, minor);
@@ -313,7 +315,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 			     _("Got GSSAPI protection response of %zu bytes: %02x %02x %02x %02x\n"),
 			     in.length, pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3]);
 
-		major = gss_unwrap(&minor, vpninfo->gss_context[1], &in, &out, NULL, GSS_C_QOP_DEFAULT);
+		major = gss_unwrap(&minor, auth_state->gss_context, &in, &out, NULL, GSS_C_QOP_DEFAULT);
 		if (major != GSS_S_COMPLETE) {
 			print_gss_err(vpninfo, "gss_unwrap()", mech, major, minor);
 			goto err;
@@ -344,7 +346,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 		ret = 0;
 	}
  err:
-	cleanup_gssapi_auth(vpninfo, 1, NULL);
+	cleanup_gssapi_auth(vpninfo, NULL);
 	free(pktbuf);
 
 	return ret;
diff --git a/http.c b/http.c
index 8a3a4a4..9f947c0 100644
--- a/http.c
+++ b/http.c
@@ -34,7 +34,7 @@ struct auth_method {
 	int state_index;
 	const char *name;
 	int (*authorization)(struct openconnect_info *, int, struct http_auth_state *, struct oc_text_buf *);
-	void (*cleanup)(struct openconnect_info *, int, struct http_auth_state *);
+	void (*cleanup)(struct openconnect_info *, struct http_auth_state *);
 };
 
 static int proxy_write(struct openconnect_info *vpninfo, char *buf, size_t len);
@@ -43,7 +43,7 @@ static int http_auth_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val
 static int basic_authorization(struct openconnect_info *vpninfo, int proxy,
 			       struct http_auth_state *auth_state,
 			       struct oc_text_buf *hdrbuf);
-static void clear_auth_state(struct openconnect_info *vpninfo, int proxy,
+static void clear_auth_state(struct openconnect_info *vpninfo, struct http_auth_state *auth_states,
 			     struct auth_method *method, int reset);
 #if !defined(HAVE_GSSAPI) && !defined(_WIN32)
 static int no_gssapi_authorization(struct openconnect_info *vpninfo,
@@ -395,7 +395,7 @@ int process_auth(struct openconnect_info *vpninfo)
 		}
 		/* Forget existing challenges */
 		for (i = 0; i < sizeof(auth_methods) / sizeof(auth_methods[0]); i++) {
-			clear_auth_state(vpninfo, 0, &auth_methods[i], 0);
+			clear_auth_state(vpninfo, vpninfo->http_auth, &auth_methods[i], 0);
 		}
 		buf_append(reqbuf, "\r\n");
 
@@ -1674,21 +1674,16 @@ static int proxy_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val)
 	return 0;
 }
 
-static void clear_auth_state(struct openconnect_info *vpninfo, int proxy,
+static void clear_auth_state(struct openconnect_info *vpninfo, struct http_auth_state *auth_states,
 			     struct auth_method *method, int reset)
 {
-	struct http_auth_state *auth;
-	if (proxy)
-		auth = &vpninfo->proxy_auth[method->state_index];
-	else
-		auth = &vpninfo->http_auth[method->state_index];
-
+	struct http_auth_state *auth = &auth_states[method->state_index];
 	/* The 'reset' argument is set when we're connected successfully,
 	   to fully reset the state to allow another connection to start
 	   again. Otherwise, we need to remember which auth methods have
 	   been tried and should not be attempted again. */
 	if (reset && method->cleanup)
-		method->cleanup(vpninfo, proxy, auth);
+		method->cleanup(vpninfo, auth);
 
 	free(auth->challenge);
 	auth->challenge = NULL;
@@ -1730,7 +1725,7 @@ static int process_http_proxy(struct openconnect_info *vpninfo)
 		}
 		/* Forget existing challenges */
 		for (i = 0; i < sizeof(auth_methods) / sizeof(auth_methods[0]); i++)
-			clear_auth_state(vpninfo, 1, &auth_methods[i], 0);
+			clear_auth_state(vpninfo, vpninfo->proxy_auth, &auth_methods[i], 0);
 	}
 	buf_append(reqbuf, "\r\n");
 
@@ -1776,7 +1771,7 @@ void cleanup_proxy_auth(struct openconnect_info *vpninfo)
 	int i;
 
 	for (i = 0; i < sizeof(auth_methods) / sizeof(auth_methods[0]); i++)
-		clear_auth_state(vpninfo, 1, &auth_methods[i], 1);
+		clear_auth_state(vpninfo, vpninfo->proxy_auth, &auth_methods[i], 1);
 }
 
 int process_proxy(struct openconnect_info *vpninfo, int ssl_sock)
diff --git a/ntlm.c b/ntlm.c
index 4095053..8d436b9 100644
--- a/ntlm.c
+++ b/ntlm.c
@@ -96,7 +96,7 @@ static int ntlm_sspi(struct openconnect_info *vpninfo, struct oc_text_buf *buf,
 	return 0;
 }
 
-static int ntlm_helper_spawn(struct openconnect_info *vpninfo, struct oc_text_buf *buf)
+static int ntlm_helper_spawn(struct openconnect_info *vpninfo, struct http_auth_state *auth_state, struct oc_text_buf *buf)
 {
         SECURITY_STATUS status;
 	int ret;
@@ -104,7 +104,7 @@ static int ntlm_helper_spawn(struct openconnect_info *vpninfo, struct oc_text_bu
 	status = AcquireCredentialsHandleW(NULL, (SEC_WCHAR *)L"NTLM",
 					   SECPKG_CRED_OUTBOUND, NULL, NULL,
 					   NULL, NULL,
-					   &vpninfo->ntlm_sspi_cred, NULL);
+					   &auth_state->ntlm_sspi_cred, NULL);
 	if (status != SEC_E_OK) {
 		vpn_progress(vpninfo, PRG_ERR,
 			     _("AcquireCredentialsHandle() failed: %lx\n"), status);
@@ -113,7 +113,7 @@ static int ntlm_helper_spawn(struct openconnect_info *vpninfo, struct oc_text_bu
 
 	ret = ntlm_sspi(vpninfo, buf, NULL);
 	if (ret)
-		FreeCredentialsHandle(&vpninfo->ntlm_sspi_cred);
+		FreeCredentialsHandle(&auth_state->ntlm_sspi_cred);
 
 	return ret;
 }
@@ -129,14 +129,14 @@ void cleanup_ntlm_auth(struct openconnect_info *vpninfo, int proxy,
 		       struct http_auth_state *auth_state)
 {
 	if (auth_state->state == NTLM_SSO_REQ) {
-		FreeCredentialsHandle(&vpninfo->ntlm_sspi_cred);
-		DeleteSecurityContext(&vpninfo->ntlm_sspi_ctx);
+		FreeCredentialsHandle(&auth_state->ntlm_sspi_cred);
+		DeleteSecurityContext(&auth_state->ntlm_sspi_ctx);
 	}
 }
 
 #else /* !_WIN32 */
 
-static int ntlm_helper_spawn(struct openconnect_info *vpninfo, struct oc_text_buf *buf)
+static int ntlm_helper_spawn(struct openconnect_info *vpninfo, struct http_auth_state *auth_state, struct oc_text_buf *buf)
 {
 	char *username;
 	int pipefd[2];
@@ -220,7 +220,7 @@ static int ntlm_helper_spawn(struct openconnect_info *vpninfo, struct oc_text_bu
 	}
 	helperbuf[len - 1] = 0;
 	buf_append(buf, "Proxy-Authorization: NTLM %s\r\n", helperbuf + 3);
-	vpninfo->ntlm_helper_fd = pipefd[1];
+	auth_state->ntlm_helper_fd = pipefd[1];
 	return 0;
 }
 
@@ -232,17 +232,17 @@ static int ntlm_helper_challenge(struct openconnect_info *vpninfo,
 	int len;
 
 	if (!auth_state->challenge ||
-	    write(vpninfo->ntlm_helper_fd, "TT ", 3) != 3 ||
-	    write(vpninfo->ntlm_helper_fd, auth_state->challenge,
+	    write(auth_state->ntlm_helper_fd, "TT ", 3) != 3 ||
+	    write(auth_state->ntlm_helper_fd, auth_state->challenge,
 		  strlen(auth_state->challenge)) != strlen(auth_state->challenge) ||
-	    write(vpninfo->ntlm_helper_fd, "\n", 1) != 1) {
+	    write(auth_state->ntlm_helper_fd, "\n", 1) != 1) {
 	err:
 		vpn_progress(vpninfo, PRG_ERR, _("Error communicating with ntlm_auth helper\n"));
-		close(vpninfo->ntlm_helper_fd);
-		vpninfo->ntlm_helper_fd = -1;
+		close(auth_state->ntlm_helper_fd);
+		auth_state->ntlm_helper_fd = -1;
 		return -EAGAIN;
 	}
-	len = read(vpninfo->ntlm_helper_fd, helperbuf, sizeof(helperbuf));
+	len = read(auth_state->ntlm_helper_fd, helperbuf, sizeof(helperbuf));
 	/* Accept both 'KK' and 'AF'. It should be the latter but see
 	   https://bugzilla.samba.org/show_bug.cgi?id=10691 */
 	if (len < 4 || (!(helperbuf[0] == 'K' && helperbuf[1] == 'K') &&
@@ -258,12 +258,12 @@ static int ntlm_helper_challenge(struct openconnect_info *vpninfo,
 
 }
 
-void cleanup_ntlm_auth(struct openconnect_info *vpninfo, int proxy,
+void cleanup_ntlm_auth(struct openconnect_info *vpninfo,
 		       struct http_auth_state *auth_state)
 {
-	if (vpninfo->ntlm_helper_fd != -1) {
-		close(vpninfo->ntlm_helper_fd);
-		vpninfo->ntlm_helper_fd = -1;
+	if (auth_state->ntlm_helper_fd != -1) {
+		close(auth_state->ntlm_helper_fd);
+		auth_state->ntlm_helper_fd = -1;
 	}
 }
 #endif /* !_WIN32 */
@@ -986,7 +986,7 @@ int ntlm_authorization(struct openconnect_info *vpninfo, int proxy,
 	if (auth_state->state == AUTH_AVAILABLE) {
 		auth_state->state = NTLM_MANUAL;
 		/* Don't attempt automatic NTLM auth if we were given a password */
-		if (!pass && !ntlm_helper_spawn(vpninfo, buf)) {
+		if (!pass && !ntlm_helper_spawn(vpninfo, auth_state, buf)) {
 			auth_state->state = NTLM_SSO_REQ;
 			return 0;
 		}
@@ -995,7 +995,7 @@ int ntlm_authorization(struct openconnect_info *vpninfo, int proxy,
 		int ret;
 		ret = ntlm_helper_challenge(vpninfo, auth_state, buf);
 		/* Clean up after it. We're done here, whether it worked or not */
-		cleanup_ntlm_auth(vpninfo, proxy, auth_state);
+		cleanup_ntlm_auth(vpninfo, auth_state);
 		auth_state->state = NTLM_MANUAL;
 		if (ret == -EAGAIN) {
 			/* Don't let it reset our state when it reconnects */
diff --git a/openconnect-internal.h b/openconnect-internal.h
index 1d9bd54..5de23de 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -216,6 +216,19 @@ struct oc_text_buf {
 struct http_auth_state {
 	int state;
 	char *challenge;
+#ifdef HAVE_GSSAPI
+	gss_name_t gss_target_name;
+	gss_ctx_id_t gss_context;
+#endif
+#ifdef _WIN32
+	CredHandle ntlm_sspi_cred;
+	CtxtHandle ntlm_sspi_ctx;
+	CredHandle sspi_cred[2];
+	CtxtHandle sspi_ctx[2];
+	SEC_WCHAR *sspi_target_name[2];
+#else
+	int ntlm_helper_fd;
+#endif
 };
 
 struct vpn_proto {
@@ -354,19 +367,6 @@ struct openconnect_info {
 	int http_close_during_auth;
 	struct http_auth_state http_auth[MAX_AUTH_TYPES];
 	struct http_auth_state proxy_auth[MAX_AUTH_TYPES];
-#ifdef HAVE_GSSAPI
-	gss_name_t gss_target_name[2];
-	gss_ctx_id_t gss_context[2];
-#endif
-#ifdef _WIN32
-	CredHandle ntlm_sspi_cred;
-	CtxtHandle ntlm_sspi_ctx;
-	CredHandle sspi_cred[2];
-	CtxtHandle sspi_ctx[2];
-	SEC_WCHAR *sspi_target_name[2];
-#else
-	int ntlm_helper_fd;
-#endif
 	int authmethods_set;
 
 	char *localname;
@@ -960,11 +960,11 @@ int gen_authorization_hdr(struct openconnect_info *vpninfo,
 
 /* ntlm.c */
 int ntlm_authorization(struct openconnect_info *vpninfo, int proxy, struct http_auth_state *auth_state, struct oc_text_buf *buf);
-void cleanup_ntlm_auth(struct openconnect_info *vpninfo, int proxy, struct http_auth_state *auth_state);
+void cleanup_ntlm_auth(struct openconnect_info *vpninfo, struct http_auth_state *auth_state);
 
 /* gssapi.c */
 int gssapi_authorization(struct openconnect_info *vpninfo, int proxy, struct http_auth_state *auth_state, struct oc_text_buf *buf);
-void cleanup_gssapi_auth(struct openconnect_info *vpninfo, int proxy, struct http_auth_state *auth_state);
+void cleanup_gssapi_auth(struct openconnect_info *vpninfo, struct http_auth_state *auth_state);
 int socks_gssapi_auth(struct openconnect_info *vpninfo);
 
 /* digest.c */
diff --git a/sspi.c b/sspi.c
index 97d0e76..83d924e 100644
--- a/sspi.c
+++ b/sspi.c
@@ -23,7 +23,7 @@
 #include "openconnect-internal.h"
 
 
-static int sspi_setup(struct openconnect_info *vpninfo, const char *service, int proxy)
+static int sspi_setup(struct openconnect_info *vpninfo, struct http_auth_state *auth_state, const char *service, int proxy)
 {
 	SECURITY_STATUS status;
 	struct oc_text_buf *buf = buf_alloc();
@@ -35,19 +35,19 @@ static int sspi_setup(struct openconnect_info *vpninfo, const char *service, int
 	if (buf_error(buf))
 		return buf_free(buf);
 
-	vpninfo->sspi_target_name[proxy] = (wchar_t *)buf->data;
+	auth_state->sspi_target_name = (wchar_t *)buf->data;
 	buf->data = NULL;
 	buf_free(buf);
 
 	status = AcquireCredentialsHandleW(NULL, (SEC_WCHAR *)L"Negotiate",
 					   SECPKG_CRED_OUTBOUND, NULL, NULL,
-					   NULL, NULL, &vpninfo->sspi_cred[proxy],
+					   NULL, NULL, &auth_state->sspi_cred,
 					   NULL);
 	if (status != SEC_E_OK) {
 		vpn_progress(vpninfo, PRG_ERR,
 			     _("AcquireCredentialsHandle() failed: %lx\n"), status);
-		free(vpninfo->sspi_target_name[proxy]);
-		vpninfo->sspi_target_name[proxy] = NULL;
+		free(auth_state->sspi_target_name);
+		auth_state->sspi_target_name = NULL;
 		return -EIO;
 	}
 
@@ -63,7 +63,7 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
 	ULONG ret_flags;
 	int first = 1;
 
-	if (auth_state->state == AUTH_AVAILABLE && sspi_setup(vpninfo, "HTTP", proxy)) {
+	if (auth_state->state == AUTH_AVAILABLE && sspi_setup(vpninfo, auth_state, "HTTP", proxy)) {
 		auth_state->state = AUTH_FAILED;
 		return -EIO;
 	}
@@ -101,19 +101,19 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
 	out_token.cbBuffer = 0;
 	out_token.pvBuffer = NULL;
 
-	status = InitializeSecurityContextW(&vpninfo->sspi_cred[proxy],
-					    first ? NULL : &vpninfo->sspi_ctx[proxy],
-					    vpninfo->sspi_target_name[proxy],
+	status = InitializeSecurityContextW(&auth_state->sspi_cred,
+					    first ? NULL : &auth_state->sspi_ctx,
+					    auth_state->sspi_target_name,
 					    ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
 					    0, SECURITY_NETWORK_DREP,
 					    first ? NULL : &input_desc,
-					    0, &vpninfo->sspi_ctx[proxy],
+					    0, &auth_state->sspi_ctx,
 					    &output_desc, &ret_flags, NULL);
 	if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
 		vpn_progress(vpninfo, PRG_ERR,
 			     _("InitializeSecurityContext() failed: %lx\n"), status);
 	fail_gssapi:
-		cleanup_gssapi_auth(vpninfo, proxy, auth_state);
+		cleanup_gssapi_auth(vpninfo, auth_state);
 		auth_state->state = AUTH_FAILED;
 		/* -EAGAIN to first a reconnect if we had been trying. Else -EIO */
 		return first ? -EIO : -EAGAIN;
@@ -128,15 +128,15 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
 	return 0;
 }
 
-void cleanup_gssapi_auth(struct openconnect_info *vpninfo, int proxy,
+void cleanup_gssapi_auth(struct openconnect_info *vpninfo, 
 			 struct http_auth_state *auth_state)
 
 {
 	if (auth_state->state >= AUTH_IN_PROGRESS) {
-		free(vpninfo->sspi_target_name);
-		vpninfo->sspi_target_name[proxy] = NULL;
-		FreeCredentialsHandle(&vpninfo->sspi_cred[proxy]);
-		DeleteSecurityContext(&vpninfo->sspi_ctx[proxy]);
+		free(auth_state->sspi_target_name);
+		auth_state->sspi_target_name = NULL;
+		FreeCredentialsHandle(&auth_state->sspi_cred);
+		DeleteSecurityContext(&auth_state->sspi_ctx);
 	}
 }
 
@@ -150,8 +150,9 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 	int first = 1;
 	int i;
 	int ret = -EIO;
+	struct http_auth_state *auth_state = &vpninfo->proxy_auth[AUTH_TYPE_GSSAPI];
 
-	if (sspi_setup(vpninfo, "rcmd", 1))
+	if (sspi_setup(vpninfo, auth_state, "rcmd", 1))
 		return -EIO;
 
 	vpninfo->proxy_auth[AUTH_TYPE_GSSAPI].state = AUTH_IN_PROGRESS;
@@ -175,13 +176,13 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 	out_token.pvBuffer = NULL;
 
 	while (1) {
-		status = InitializeSecurityContextW(&vpninfo->sspi_cred[1],
-						    first ? NULL : &vpninfo->sspi_ctx[1],
-						    vpninfo->sspi_target_name[1],
+		status = InitializeSecurityContextW(&auth_state->sspi_cred,
+						    first ? NULL : &auth_state->sspi_ctx,
+						    auth_state->sspi_target_name,
 						    ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
 						    0, SECURITY_NETWORK_DREP,
 						    first ? NULL : &input_desc,
-						    0, &vpninfo->sspi_ctx[1],
+						    0, &auth_state->sspi_ctx,
 						    &output_desc, &ret_flags, NULL);
 		if (status == SEC_E_OK) {
 			/* If we still have a token to send, send it. */
@@ -270,7 +271,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 
 		ret = -EIO;
 
-		status = QueryContextAttributes(&vpninfo->sspi_ctx[1], SECPKG_ATTR_SIZES, &sizes);
+		status = QueryContextAttributes(&auth_state->sspi_ctx, SECPKG_ATTR_SIZES, &sizes);
 		if (status != SEC_E_OK) {
 			vpn_progress(vpninfo, PRG_ERR,
 				     _("QueryContextAttributes() failed: %lx\n"), status);
@@ -306,7 +307,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 			goto err;
 		}
 
-		status = EncryptMessage(&vpninfo->sspi_ctx[1], SECQOP_WRAP_NO_ENCRYPT, &enc_desc, 0);
+		status = EncryptMessage(&auth_state->sspi_ctx, SECQOP_WRAP_NO_ENCRYPT, &enc_desc, 0);
 		if (status != SEC_E_OK) {
 			vpn_progress(vpninfo, PRG_ERR,
 				     _("EncryptMessage() failed: %lx\n"), status);
@@ -387,7 +388,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 		enc_bufs[1].cbBuffer = 0;
 		enc_bufs[1].pvBuffer = NULL;
 
-		status = DecryptMessage(&vpninfo->sspi_ctx[1], &enc_desc, 0, NULL);
+		status = DecryptMessage(&auth_state->sspi_ctx, &enc_desc, 0, NULL);
 		if (status != SEC_E_OK) {
 			vpn_progress(vpninfo, PRG_ERR,
 				     _("DecryptMessage failed: %lx\n"), status);
@@ -421,7 +422,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
 	}
 
  err:
-	cleanup_gssapi_auth(vpninfo, 1, &vpninfo->proxy_auth[AUTH_TYPE_GSSAPI]);
+	cleanup_gssapi_auth(vpninfo, &vpninfo->proxy_auth[AUTH_TYPE_GSSAPI]);
 	vpninfo->proxy_auth[AUTH_TYPE_GSSAPI].state = AUTH_UNSEEN;
 	free(pktbuf);
 
-- 
2.1.0




More information about the openconnect-devel mailing list