Prior to sending profile files, perform cookie authentication

That allows to read the per-user config file, and prevent
a null pointer dereference. Reported by Yick Xie.
This commit is contained in:
Nikos Mavrogiannopoulos
2015-12-21 23:56:35 +02:00
parent 97a49138e6
commit 3e82a965a8
5 changed files with 49 additions and 27 deletions

View File

@@ -792,6 +792,45 @@ int get_cert_info(worker_st * ws)
return 0;
}
/* This makes sure that the provided cookie is valid,
* and fills in the ws->user_config.
*/
void cookie_authenticate_or_exit(worker_st *ws)
{
int ret;
if (ws->auth_state == S_AUTH_COMPLETE)
return;
/* we must be in S_AUTH_COOKIE state */
if (ws->auth_state != S_AUTH_COOKIE || ws->cookie_set == 0) {
oclog(ws, LOG_WARNING, "no cookie found");
cstp_puts(ws,
"HTTP/1.1 503 Service Unavailable\r\n\r\n");
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
exit_worker(ws);
}
/* we have authenticated against sec-mod, we need to complete
* our authentication by forwarding our cookie to main. */
ret = auth_cookie(ws, ws->cookie, ws->cookie_size);
if (ret < 0) {
oclog(ws, LOG_WARNING, "failed cookie authentication attempt");
if (ret == ERR_AUTH_FAIL) {
cstp_puts(ws,
"HTTP/1.1 401 Unauthorized\r\n\r\n");
cstp_puts(ws,
"X-Reason: Cookie is not acceptable\r\n\r\n");
} else {
cstp_puts(ws,
"HTTP/1.1 503 Service Unavailable\r\n\r\n");
}
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
exit_worker(ws);
}
ws->auth_state = S_AUTH_COMPLETE;
}
/* sends a cookie authentication request to main thread and waits for
* a reply.
* Returns 0 on success.

View File

@@ -48,6 +48,9 @@ int ret;
struct stat st;
oclog(ws, LOG_HTTP_DEBUG, "requested config: %s", ws->req.url);
cookie_authenticate_or_exit(ws);
if (ws->user_config->xml_config_file == NULL) {
oclog(ws, LOG_INFO, "requested config but no config file is set");
cstp_printf(ws, "HTTP/1.%u 404 Not found\r\n", http_ver);

View File

@@ -345,6 +345,9 @@ void header_value_check(struct worker_st *ws, struct http_req_st *req)
ws->full_ipv6 = 1;
break;
case HEADER_COOKIE:
/* don't bother parsing cookies if we are already authenticated */
if (ws->auth_state > S_AUTH_COOKIE)
break;
str = (char *)value;
while ((token = strtok(str, ";")) != NULL) {

View File

@@ -1312,6 +1312,7 @@ static int send_routes(worker_st *ws, struct http_req_st *req,
return 0;
}
/* connect_handler:
* @ws: an initialized worker structure
*
@@ -1350,33 +1351,7 @@ static int connect_handler(worker_st * ws)
ws->buffer_size = sizeof(ws->buffer);
/* we must be in S_AUTH_COOKIE state */
if (ws->auth_state != S_AUTH_COOKIE || ws->cookie_set == 0) {
oclog(ws, LOG_WARNING, "no cookie found");
cstp_puts(ws,
"HTTP/1.1 503 Service Unavailable\r\n\r\n");
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
exit_worker(ws);
}
/* we have authenticated against sec-mod, we need to complete
* our authentication by forwarding our cookie to main. */
ret = auth_cookie(ws, ws->cookie, ws->cookie_size);
if (ret < 0) {
oclog(ws, LOG_WARNING, "failed cookie authentication attempt");
if (ret == ERR_AUTH_FAIL) {
cstp_puts(ws,
"HTTP/1.1 401 Unauthorized\r\n\r\n");
cstp_puts(ws,
"X-Reason: Cookie is not acceptable\r\n\r\n");
} else {
cstp_puts(ws,
"HTTP/1.1 503 Service Unavailable\r\n\r\n");
}
cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
exit_worker(ws);
}
ws->auth_state = S_AUTH_COMPLETE;
cookie_authenticate_or_exit(ws);
if (strcmp(req->url, "/CSCOSSLC/tunnel") != 0) {
oclog(ws, LOG_INFO, "bad connect request: '%s'\n", req->url);

View File

@@ -359,6 +359,8 @@ int send_msg_to_main(worker_st *ws, uint8_t cmd,
int parse_proxy_proto_header(struct worker_st *ws, int fd);
void cookie_authenticate_or_exit(worker_st *ws);
/* after that time (secs) of inactivity in the UDP part, connection switches to
* TCP (if activity occurs there).
*/