Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Honour Proxy-Connection: close during authentication
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jul 21, 2014
1 parent 4af7910 commit 091cd79
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 14 deletions.
29 changes: 25 additions & 4 deletions http.c
Expand Up @@ -1879,6 +1879,12 @@ static int proxy_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val)
{
int i;

if (!strcasecmp(hdr, "Proxy-Connection")) {
if (!strcasecmp(val, "close"))
vpninfo->proxy_close_during_auth = 1;
return 0;
}

if (strcasecmp(hdr, "Proxy-Authenticate"))
return 0;

Expand Down Expand Up @@ -1919,7 +1925,9 @@ static int process_http_proxy(struct openconnect_info *vpninfo)
int resplen;
struct oc_text_buf *reqbuf;
int result;
int auth = 0;
int auth = vpninfo->proxy_close_during_auth;

vpninfo->proxy_close_during_auth = 0;

vpn_progress(vpninfo, PRG_INFO,
_("Requesting HTTP proxy connection to %s:%d\n"),
Expand Down Expand Up @@ -1973,6 +1981,10 @@ static int process_http_proxy(struct openconnect_info *vpninfo)
}

if (result == 407) {
/* If the proxy asked us to close the connection, do so */
if (vpninfo->proxy_close_during_auth)
return -EAGAIN;

auth = 1;
goto retry;
}
Expand All @@ -1985,9 +1997,17 @@ static int process_http_proxy(struct openconnect_info *vpninfo)
return -EIO;
}

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);
}

int process_proxy(struct openconnect_info *vpninfo, int ssl_sock)
{
int ret, i;
int ret;

vpninfo->proxy_fd = ssl_sock;
vpninfo->ssl_read = proxy_read;
Expand All @@ -2006,8 +2026,9 @@ int process_proxy(struct openconnect_info *vpninfo, int ssl_sock)
}

vpninfo->proxy_fd = -1;
for (i = 0; i < sizeof(auth_methods) / sizeof(auth_methods[0]); i++)
clear_auth_state(vpninfo, &auth_methods[i], 1);
if (!vpninfo->proxy_close_during_auth)
cleanup_proxy_auth(vpninfo);

return ret;
}

Expand Down
2 changes: 2 additions & 0 deletions openconnect-internal.h
Expand Up @@ -206,6 +206,7 @@ struct openconnect_info {
int proxy_fd;
char *proxy_user;
char *proxy_pass;
int proxy_close_during_auth;
struct proxy_auth_state auth[MAX_AUTH_TYPES];
#ifdef HAVE_GSSAPI
gss_name_t gss_target_name;
Expand Down Expand Up @@ -610,6 +611,7 @@ void *openconnect_base64_decode(int *len, const char *in);
int buf_error(struct oc_text_buf *buf);
int buf_free(struct oc_text_buf *buf);
char *openconnect_create_useragent(const char *base);
void cleanup_proxy_auth(struct openconnect_info *vpninfo);
int process_proxy(struct openconnect_info *vpninfo, int ssl_sock);
int internal_parse_url(char *url, char **res_proto, char **res_host,
int *res_port, char **res_path, int default_port);
Expand Down
31 changes: 21 additions & 10 deletions ssl.c
Expand Up @@ -139,7 +139,8 @@ int connect_https_socket(struct openconnect_info *vpninfo)
}
if (ssl_sock >= 0)
closesocket(ssl_sock);
return -EINVAL;
ssl_sock = -EINVAL;
goto out;
}
} else {
struct addrinfo hints, *result, *rp;
Expand Down Expand Up @@ -176,8 +177,10 @@ int connect_https_socket(struct openconnect_info *vpninfo)
else
i = asprintf(&url, "https://%s:%d/%s", vpninfo->hostname,
vpninfo->port, vpninfo->urlpath?:"");
if (i == -1)
return -ENOMEM;
if (i == -1) {
ssl_sock = -ENOMEM;
goto out;
}

proxies = px_proxy_factory_get_proxies(vpninfo->proxy_factory,
url);
Expand Down Expand Up @@ -211,8 +214,10 @@ int connect_https_socket(struct openconnect_info *vpninfo)

if (hostname[0] == '[' && hostname[strlen(hostname)-1] == ']') {
hostname = strndup(hostname + 1, strlen(hostname) - 2);
if (!hostname)
return -ENOMEM;
if (!hostname) {
ssl_sock = -ENOMEM;
goto out;
}
hints.ai_flags |= AI_NUMERICHOST;
}

Expand All @@ -224,7 +229,8 @@ int connect_https_socket(struct openconnect_info *vpninfo)
hostname, gai_strerror(err));
if (hints.ai_flags & AI_NUMERICHOST)
free(hostname);
return -EINVAL;
ssl_sock = -EINVAL;
goto out;
}
if (hints.ai_flags & AI_NUMERICHOST)
free(hostname);
Expand Down Expand Up @@ -256,7 +262,8 @@ int connect_https_socket(struct openconnect_info *vpninfo)
vpn_progress(vpninfo, PRG_ERR,
_("Failed to allocate sockaddr storage\n"));
closesocket(ssl_sock);
return -ENOMEM;
ssl_sock = -ENOMEM;
goto out;
}
vpninfo->peer_addrlen = rp->ai_addrlen;
memcpy(vpninfo->peer_addr, rp->ai_addr, rp->ai_addrlen);
Expand Down Expand Up @@ -288,7 +295,8 @@ int connect_https_socket(struct openconnect_info *vpninfo)
vpn_progress(vpninfo, PRG_ERR,
_("Failed to connect to host %s\n"),
vpninfo->proxy?:vpninfo->hostname);
return -EINVAL;
ssl_sock = -EINVAL;
goto out;
}
}

Expand All @@ -302,10 +310,13 @@ int connect_https_socket(struct openconnect_info *vpninfo)
_("Reconnecting to proxy %s\n"), vpninfo->proxy);
goto reconnect;
}
return err;
ssl_sock = err;
}
}

out:
/* If proxy processing returned -EAGAIN to reconnect before attempting
further auth, and we failed to reconnect, we have to clean up here. */
cleanup_proxy_auth(vpninfo);
return ssl_sock;
}

Expand Down

0 comments on commit 091cd79

Please sign in to comment.