worker: if a client retries a POST/GET request without the X-Support-HTTP header switch method

That allows openconnect to retry using password authentication if it
has no ticket or so. To advertize that behavior we set the header
X-HTTP-Auth-Support: fallback
in our 401 response.
This commit is contained in:
Nikos Mavrogiannopoulos
2015-02-24 16:01:22 +01:00
parent ca9b7e6e7d
commit cb52dd943e
3 changed files with 19 additions and 1 deletions

View File

@@ -1108,6 +1108,12 @@ int basic_auth_handler(worker_st * ws, unsigned http_ver, const char *msg)
if (ret < 0)
return -1;
if (ws->config->auth_methods > 1) {
ret = cstp_puts(ws, "X-HTTP-Auth-Support: fallback\r\n");
if (ret < 0)
return -1;
}
if (msg == NULL) {
oclog(ws, LOG_HTTP_DEBUG, "HTTP sending: WWW-Authenticate: Negotiate");
ret = cstp_puts(ws, "WWW-Authenticate: Negotiate\r\n");

View File

@@ -206,6 +206,7 @@ void header_value_check(struct worker_st *ws, struct http_req_st *req)
break;
case HEADER_SUPPORT_SPNEGO:
ws_switch_auth_to(ws, AUTH_TYPE_GSSAPI);
req->spnego_set = 1;
break;
case HEADER_AUTHORIZATION:
if (req->authorization != NULL)
@@ -508,6 +509,14 @@ int http_header_complete_cb(http_parser * parser)
/* handle header value */
header_value_check(ws, req);
if (ws->selected_auth->type & AUTH_TYPE_GSSAPI && ws->auth_state == S_AUTH_INACTIVE &&
req->spnego_set == 0) {
/* client retried getting the form without the SPNEGO header, probably
* wants a fallback authentication method */
if (ws_switch_auth_to(ws, AUTH_TYPE_USERNAME_PASS) == 0)
oclog(ws, LOG_INFO, "no fallback to gssapi authentication");
}
req->headers_complete = 1;
return 0;
}
@@ -550,6 +559,7 @@ void http_req_reset(worker_st * ws)
ws->req.headers_complete = 0;
ws->req.message_complete = 0;
ws->req.body_length = 0;
ws->req.spnego_set = 0;
ws->req.url[0] = 0;
ws->req.header_state = HTTP_HEADER_INIT;

View File

@@ -34,6 +34,7 @@
#include <common.h>
#include <str.h>
#include <worker-bandwidth.h>
#include <stdbool.h>
#include <sys/un.h>
#include <sys/uio.h>
@@ -122,7 +123,8 @@ struct http_req_st {
unsigned int next_header;
unsigned int is_mobile;
bool is_mobile;
bool spnego_set;
unsigned char master_secret[TLS_MASTER_SIZE];
unsigned int master_secret_set;