Skip to content

Commit

Permalink
Support fallback from X-Support-HTTP-Auth
Browse files Browse the repository at this point in the history
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: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Feb 24, 2015
1 parent 7e81ac6 commit 32c08c5
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 3 deletions.
1 change: 1 addition & 0 deletions cstp.c
Expand Up @@ -1148,6 +1148,7 @@ void cstp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *b
buf_append(buf, "X-AnyConnect-Platform: %s\r\n",
vpninfo->platname);
}
if (vpninfo->try_http_auth)
buf_append(buf, "X-Support-HTTP-Auth: true\r\n");

append_mobile_headers(vpninfo, buf);
Expand Down
12 changes: 12 additions & 0 deletions http-auth.c
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;

Expand Down
8 changes: 5 additions & 3 deletions http.c
Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions library.c
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions openconnect-internal.h
Expand Up @@ -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;
Expand Down

0 comments on commit 32c08c5

Please sign in to comment.