Commit c26d4590 authored by David Woodhouse's avatar David Woodhouse

Finally add (non-proxy) HTTP authentication support

This is what a lot of the previous changes from Nikos and myself were
working towards.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent df80b806
......@@ -253,9 +253,10 @@ int gen_authorization_hdr(struct openconnect_info *vpninfo, int proxy,
/* Returns non-zero if it matched */
static int handle_auth_proto(struct openconnect_info *vpninfo,
struct http_auth_state *auth_states,
struct auth_method *method, char *hdr)
{
struct http_auth_state *auth = &vpninfo->proxy_auth[method->state_index];
struct http_auth_state *auth = &auth_states[method->state_index];
int l = strlen(method->name);
if (auth->state <= AUTH_FAILED)
......@@ -294,7 +295,23 @@ int proxy_auth_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val)
for (i = 0; i < sizeof(auth_methods) / sizeof(auth_methods[0]); i++) {
/* Return once we've found a match */
if (handle_auth_proto(vpninfo, &auth_methods[i], val))
if (handle_auth_proto(vpninfo, vpninfo->proxy_auth, &auth_methods[i], val))
return 0;
}
return 0;
}
int http_auth_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val)
{
int i;
if (strcasecmp(hdr, "WWW-Authenticate"))
return 0;
for (i = 0; i < sizeof(auth_methods) / sizeof(auth_methods[0]); i++) {
/* Return once we've found a match */
if (handle_auth_proto(vpninfo, vpninfo->http_auth, &auth_methods[i], val))
return 0;
}
......
......@@ -790,6 +790,7 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
int result;
int rq_retry;
int rlen, pad;
int auth = 0;
if (request_body_type && buf_error(request_body))
return buf_error(request_body);
......@@ -815,6 +816,14 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
buf_append(buf, "%s /%s HTTP/1.1\r\n", method, vpninfo->urlpath ?: "");
if (vpninfo->proto.add_http_headers)
vpninfo->proto.add_http_headers(vpninfo, buf);
if (auth) {
result = gen_authorization_hdr(vpninfo, 0, buf);
if (result)
goto out;
/* Forget existing challenges */
clear_auth_states(vpninfo, vpninfo->http_auth, 0);
}
if (request_body_type) {
rlen = request_body->pos;
......@@ -856,12 +865,12 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
vpn_progress(vpninfo, PRG_ERR,
_("Failed to open HTTPS connection to %s\n"),
vpninfo->hostname);
buf_free(buf);
/* We really don't want to return -EINVAL if we have
failed to even connect to the server, because if
we do that openconnect_obtain_cookie() might try
again without XMLPOST... with the same result. */
return -EIO;
result = -EIO;
goto out;
}
}
......@@ -876,7 +885,7 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
if (result < 0)
goto out;
result = process_http_response(vpninfo, 0, NULL, buf);
result = process_http_response(vpninfo, 0, http_auth_hdrs, buf);
if (result < 0) {
/* We'll already have complained about whatever offended us */
goto out;
......@@ -884,6 +893,10 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
if (vpninfo->dump_http_traffic && buf->pos)
dump_buf(vpninfo, '<', buf->data);
if (result == 401) {
auth = 1;
goto redirected;
}
if (result != 200 && vpninfo->redirect_url) {
result = handle_redirect(vpninfo);
if (result == 0) {
......@@ -894,6 +907,8 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
method = "GET";
request_body_type = NULL;
}
if (vpninfo->redirect_type == REDIR_TYPE_NEWHOST)
clear_auth_states(vpninfo, vpninfo->http_auth, 1);
goto redirected;
}
goto out;
......@@ -912,6 +927,8 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
out:
buf_free(buf);
/* On success, clear out all authentication state for the next request */
clear_auth_states(vpninfo, vpninfo->http_auth, 1);
return result;
}
......
......@@ -1014,8 +1014,6 @@ int ntlm_authorization(struct openconnect_info *vpninfo, int proxy,
/* Don't let it reset our state when it reconnects */
if (proxy)
vpninfo->proxy_close_during_auth = 1;
else
vpninfo->http_close_during_auth = 1;
return ret;
}
if (!ret)
......
......@@ -374,7 +374,6 @@ struct openconnect_info {
char *proxy_user;
char *proxy_pass;
int proxy_close_during_auth;
int http_close_during_auth;
struct http_auth_state http_auth[MAX_AUTH_TYPES];
struct http_auth_state proxy_auth[MAX_AUTH_TYPES];
int authmethods_set;
......@@ -960,6 +959,7 @@ void *openconnect_base64_decode(int *len, const char *in);
void clear_auth_states(struct openconnect_info *vpninfo,
struct http_auth_state *auth_states, int reset);
int proxy_auth_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val);
int http_auth_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val);
int gen_authorization_hdr(struct openconnect_info *vpninfo, int proxy,
struct oc_text_buf *buf);
/* ntlm.c */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment