mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-03-14 06:48:16 +08:00
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:
@@ -1108,6 +1108,12 @@ int basic_auth_handler(worker_st * ws, unsigned http_ver, const char *msg)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
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) {
|
if (msg == NULL) {
|
||||||
oclog(ws, LOG_HTTP_DEBUG, "HTTP sending: WWW-Authenticate: Negotiate");
|
oclog(ws, LOG_HTTP_DEBUG, "HTTP sending: WWW-Authenticate: Negotiate");
|
||||||
ret = cstp_puts(ws, "WWW-Authenticate: Negotiate\r\n");
|
ret = cstp_puts(ws, "WWW-Authenticate: Negotiate\r\n");
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ void header_value_check(struct worker_st *ws, struct http_req_st *req)
|
|||||||
break;
|
break;
|
||||||
case HEADER_SUPPORT_SPNEGO:
|
case HEADER_SUPPORT_SPNEGO:
|
||||||
ws_switch_auth_to(ws, AUTH_TYPE_GSSAPI);
|
ws_switch_auth_to(ws, AUTH_TYPE_GSSAPI);
|
||||||
|
req->spnego_set = 1;
|
||||||
break;
|
break;
|
||||||
case HEADER_AUTHORIZATION:
|
case HEADER_AUTHORIZATION:
|
||||||
if (req->authorization != NULL)
|
if (req->authorization != NULL)
|
||||||
@@ -508,6 +509,14 @@ int http_header_complete_cb(http_parser * parser)
|
|||||||
/* handle header value */
|
/* handle header value */
|
||||||
header_value_check(ws, req);
|
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;
|
req->headers_complete = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -550,6 +559,7 @@ void http_req_reset(worker_st * ws)
|
|||||||
ws->req.headers_complete = 0;
|
ws->req.headers_complete = 0;
|
||||||
ws->req.message_complete = 0;
|
ws->req.message_complete = 0;
|
||||||
ws->req.body_length = 0;
|
ws->req.body_length = 0;
|
||||||
|
ws->req.spnego_set = 0;
|
||||||
ws->req.url[0] = 0;
|
ws->req.url[0] = 0;
|
||||||
|
|
||||||
ws->req.header_state = HTTP_HEADER_INIT;
|
ws->req.header_state = HTTP_HEADER_INIT;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <str.h>
|
#include <str.h>
|
||||||
#include <worker-bandwidth.h>
|
#include <worker-bandwidth.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
|
||||||
@@ -122,7 +123,8 @@ struct http_req_st {
|
|||||||
|
|
||||||
unsigned int next_header;
|
unsigned int next_header;
|
||||||
|
|
||||||
unsigned int is_mobile;
|
bool is_mobile;
|
||||||
|
bool spnego_set;
|
||||||
|
|
||||||
unsigned char master_secret[TLS_MASTER_SIZE];
|
unsigned char master_secret[TLS_MASTER_SIZE];
|
||||||
unsigned int master_secret_set;
|
unsigned int master_secret_set;
|
||||||
|
|||||||
Reference in New Issue
Block a user