Skip to content

Commit

Permalink
Let cleanup functions distinguish between proxy and http auth
Browse files Browse the repository at this point in the history
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Feb 20, 2015
1 parent 3484aeb commit 27e6c23
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 20 deletions.
10 changes: 6 additions & 4 deletions gssapi.c
Expand Up @@ -124,7 +124,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);
cleanup_gssapi_auth(vpninfo, proxy, 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;
Expand All @@ -140,13 +140,15 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
return 0;
}

void cleanup_gssapi_auth(struct openconnect_info *vpninfo)
/* auth_state is NULL when called from socks_gssapi_auth() */
void cleanup_gssapi_auth(struct openconnect_info *vpninfo, int proxy,
struct http_auth_state *auth_state)
{
OM_uint32 minor;

if (vpninfo->gss_target_name != GSS_C_NO_NAME)
gss_release_name(&minor, &vpninfo->gss_target_name);

if (vpninfo->gss_context != GSS_C_NO_CONTEXT)
gss_delete_sec_context(&minor, &vpninfo->gss_context, GSS_C_NO_BUFFER);

Expand Down Expand Up @@ -338,7 +340,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
ret = 0;
}
err:
cleanup_gssapi_auth(vpninfo);
cleanup_gssapi_auth(vpninfo, 1, NULL);
free(pktbuf);

return ret;
Expand Down
16 changes: 10 additions & 6 deletions http.c
Expand Up @@ -1431,7 +1431,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 *);
void (*cleanup)(struct openconnect_info *, int, struct http_auth_state *);
} auth_methods[] = {
#if defined(HAVE_GSSAPI) || defined(_WIN32)
{ AUTH_TYPE_GSSAPI, "Negotiate", gssapi_authorization, cleanup_gssapi_auth },
Expand Down Expand Up @@ -1517,17 +1517,21 @@ static int proxy_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val)
return 0;
}

static void clear_auth_state(struct openconnect_info *vpninfo,
static void clear_auth_state(struct openconnect_info *vpninfo, int proxy,
struct auth_method *method, int reset)
{
struct http_auth_state *auth = &vpninfo->proxy_auth[method->state_index];
struct http_auth_state *auth;
if (proxy)
auth = &vpninfo->proxy_auth[method->state_index];
else
auth = &vpninfo->http_auth[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);
method->cleanup(vpninfo, proxy, auth);

free(auth->challenge);
auth->challenge = NULL;
Expand Down Expand Up @@ -1569,7 +1573,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, &auth_methods[i], 0);
clear_auth_state(vpninfo, 1, &auth_methods[i], 0);
}
buf_append(reqbuf, "\r\n");

Expand Down Expand Up @@ -1615,7 +1619,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, &auth_methods[i], 1);
clear_auth_state(vpninfo, 1, &auth_methods[i], 1);
}

int process_proxy(struct openconnect_info *vpninfo, int ssl_sock)
Expand Down
10 changes: 6 additions & 4 deletions ntlm.c
Expand Up @@ -125,9 +125,10 @@ static int ntlm_helper_challenge(struct openconnect_info *vpninfo,
return ntlm_sspi(vpninfo, buf, auth_state->challenge);
}

void cleanup_ntlm_auth(struct openconnect_info *vpninfo)
void cleanup_ntlm_auth(struct openconnect_info *vpninfo, int proxy,
struct http_auth_state *auth_state)
{
if (vpninfo->proxy_auth[AUTH_TYPE_NTLM].state == NTLM_SSO_REQ) {
if (auth_state->state == NTLM_SSO_REQ) {
FreeCredentialsHandle(&vpninfo->ntlm_sspi_cred);
DeleteSecurityContext(&vpninfo->ntlm_sspi_ctx);
}
Expand Down Expand Up @@ -257,7 +258,8 @@ static int ntlm_helper_challenge(struct openconnect_info *vpninfo,

}

void cleanup_ntlm_auth(struct openconnect_info *vpninfo)
void cleanup_ntlm_auth(struct openconnect_info *vpninfo, int proxy,
struct http_auth_state *auth_state)
{
if (vpninfo->ntlm_helper_fd != -1) {
close(vpninfo->ntlm_helper_fd);
Expand Down Expand Up @@ -977,7 +979,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);
cleanup_ntlm_auth(vpninfo, proxy, auth_state);
auth_state->state = NTLM_MANUAL;
if (ret == -EAGAIN) {
/* Don't let it reset our state when it reconnects */
Expand Down
4 changes: 2 additions & 2 deletions openconnect-internal.h
Expand Up @@ -949,11 +949,11 @@ void http_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *b

/* 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);
void cleanup_ntlm_auth(struct openconnect_info *vpninfo, int proxy, 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);
void cleanup_gssapi_auth(struct openconnect_info *vpninfo, int proxy, struct http_auth_state *auth_state);
int socks_gssapi_auth(struct openconnect_info *vpninfo);

/* digest.c */
Expand Down
10 changes: 6 additions & 4 deletions sspi.c
Expand Up @@ -113,7 +113,7 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
vpn_progress(vpninfo, PRG_ERR,
_("InitializeSecurityContext() failed: %lx\n"), status);
fail_gssapi:
cleanup_gssapi_auth(vpninfo);
cleanup_gssapi_auth(vpninfo, proxy, auth_state);
auth_state->state = AUTH_FAILED;
/* -EAGAIN to first a reconnect if we had been trying. Else -EIO */
return first ? -EIO : -EAGAIN;
Expand All @@ -128,9 +128,11 @@ int gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
return 0;
}

void cleanup_gssapi_auth(struct openconnect_info *vpninfo)
void cleanup_gssapi_auth(struct openconnect_info *vpninfo, int proxy,
struct http_auth_state *auth_state)

{
if (vpninfo->proxy_auth[AUTH_TYPE_GSSAPI].state >= AUTH_IN_PROGRESS) {
if (auth_state->state >= AUTH_IN_PROGRESS) {
free(vpninfo->sspi_target_name);
vpninfo->sspi_target_name = NULL;
FreeCredentialsHandle(&vpninfo->sspi_cred);
Expand Down Expand Up @@ -418,7 +420,7 @@ int socks_gssapi_auth(struct openconnect_info *vpninfo)
}

err:
cleanup_gssapi_auth(vpninfo);
cleanup_gssapi_auth(vpninfo, 1, &vpninfo->proxy_auth[AUTH_TYPE_GSSAPI]);
vpninfo->proxy_auth[AUTH_TYPE_GSSAPI].state = AUTH_UNSEEN;
free(pktbuf);

Expand Down

0 comments on commit 27e6c23

Please sign in to comment.