Commit 32c08c5a authored by David Woodhouse's avatar David Woodhouse

Support fallback from X-Support-HTTP-Auth

If HTTP authentication fails against ocserv, it can offer us a form to try
authentication the standard way. It can indicate that such is available by
sending 'X-Support-HTTP-Auth: fallback' along with the 401 response. That
way, we retry without 'X-Support-HTTP-Auth: true' in the request and we'll
get the standard form.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 7e81ac64
......@@ -1148,7 +1148,8 @@ void cstp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *b
buf_append(buf, "X-AnyConnect-Platform: %s\r\n",
vpninfo->platname);
}
buf_append(buf, "X-Support-HTTP-Auth: true\r\n");
if (vpninfo->try_http_auth)
buf_append(buf, "X-Support-HTTP-Auth: true\r\n");
append_mobile_headers(vpninfo, buf);
}
......@@ -247,6 +247,12 @@ int gen_authorization_hdr(struct openconnect_info *vpninfo, int proxy,
}
}
vpn_progress(vpninfo, PRG_INFO, _("No more authentication methods to try\n"));
if (vpninfo->retry_on_auth_fail) {
/* Try again without the X-Support-HTTP-Auth: header */
vpninfo->try_http_auth = 0;
return 0;
}
return -ENOENT;
}
......@@ -305,6 +311,12 @@ int http_auth_hdrs(struct openconnect_info *vpninfo, char *hdr, char *val)
{
int i;
if (!strcasecmp(hdr, "X-HTTP-Auth-Support") &&
!strcasecmp(val, "fallback")) {
vpninfo->retry_on_auth_fail = 1;
return 0;
}
if (strcasecmp(hdr, "WWW-Authenticate"))
return 0;
......
......@@ -820,8 +820,6 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
*/
buf = buf_alloc();
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)
......@@ -830,6 +828,8 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
/* Forget existing challenges */
clear_auth_states(vpninfo, vpninfo->http_auth, 0);
}
if (vpninfo->proto.add_http_headers)
vpninfo->proto.add_http_headers(vpninfo, buf);
if (request_body_type) {
rlen = request_body->pos;
......@@ -859,6 +859,8 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
if (buf_error(buf))
return buf_free(buf);
vpninfo->retry_on_auth_fail = 0;
retry:
if (openconnect_https_connected(vpninfo)) {
/* The session is already connected. If we get a failure on
......@@ -899,7 +901,7 @@ 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) {
if (result == 401 && vpninfo->try_http_auth) {
auth = 1;
goto redirected;
}
......
......@@ -83,6 +83,7 @@ struct openconnect_info *openconnect_vpninfo_new(const char *useragent,
vpninfo->cbdata = privdata ? : vpninfo;
vpninfo->xmlpost = 1;
vpninfo->verbose = PRG_TRACE;
vpninfo->try_http_auth = 1;
openconnect_set_reported_os(vpninfo, NULL);
if (!vpninfo->localname || !vpninfo->useragent)
......
......@@ -374,6 +374,8 @@ struct openconnect_info {
char *proxy_user;
char *proxy_pass;
int proxy_close_during_auth;
int retry_on_auth_fail;
int try_http_auth;
struct http_auth_state http_auth[MAX_AUTH_TYPES];
struct http_auth_state proxy_auth[MAX_AUTH_TYPES];
int authmethods_set;
......
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