Update user cookie when session is still running.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER 2019-11-30 10:50:15 +00:00
parent 76bcef3771
commit 8742e140c0
No known key found for this signature in database
GPG Key ID: 00135ACBD90B28DD
11 changed files with 96 additions and 86 deletions

View File

@ -73,6 +73,17 @@ int check_client_auth(struct mg_connection *conn)
// the validity of their API authentication
auth_data[num].valid_until = now;
// Update user cookie
char *buffer = NULL;
if(asprintf(&buffer,
"Set-Cookie: user_id=%u; Path=/; Max-Age=%u\r\n",
num, API_SESSION_EXPIRE) < 0)
{
return send_json_error(conn, 500, "internal_error", "Internal server error", NULL);
}
my_set_cookie_header(conn, buffer);
free(buffer);
if(config.debug & DEBUG_API)
{
char timestr[128];
@ -172,13 +183,15 @@ int api_auth(struct mg_connection *conn)
if(config.debug & DEBUG_API)
logg("Authentification: OK, localhost does not need auth.");
// We still have to send a cookie for the web interface to be happy
char *additional_headers = NULL;
if(asprintf(&additional_headers,
char *buffer = NULL;
if(asprintf(&buffer,
"Set-Cookie: user_id=%u; Path=/; Max-Age=%u\r\n",
API_MAX_CLIENTS, API_SESSION_EXPIRE) < 0)
{
return send_json_error(conn, 500, "internal_error", "Internal server error", NULL, NULL);
return send_json_error(conn, 500, "internal_error", "Internal server error", NULL);
}
my_set_cookie_header(conn, buffer);
free(buffer);
}
if(user_id > -1 && method == HTTP_GET)
{
@ -188,15 +201,17 @@ int api_auth(struct mg_connection *conn)
cJSON *json = JSON_NEW_OBJ();
JSON_OBJ_REF_STR(json, "status", "success");
// Ten minutes validity
char *additional_headers = NULL;
if(asprintf(&additional_headers,
char *buffer = NULL;
if(asprintf(&buffer,
"Set-Cookie: user_id=%u; Path=/; Max-Age=%u\r\n",
user_id, API_SESSION_EXPIRE) < 0)
{
return send_json_error(conn, 500, "internal_error", "Internal server error", NULL, NULL);
return send_json_error(conn, 500, "internal_error", "Internal server error", NULL);
}
my_set_cookie_header(conn, buffer);
free(buffer);
return send_json_success(conn, additional_headers);
return send_json_success(conn);
}
else if(user_id > -1 && method == HTTP_DELETE)
{
@ -209,13 +224,15 @@ int api_auth(struct mg_connection *conn)
free(auth_data[user_id].remote_addr);
auth_data[user_id].remote_addr = NULL;
char *additional_headers = strdup("Set-Cookie: user_id=deleted; Path=/; Max-Age=-1\r\n");
return send_json_success(conn, additional_headers);
const char *buffer = "Set-Cookie: user_id=deleted; Path=/; Max-Age=-1\r\n";
my_set_cookie_header(conn, buffer);
return send_json_success(conn);
}
else
{
char *additional_headers = strdup("Set-Cookie: user_id=deleted; Path=/; Max-Age=-1\r\n");
return send_json_unauthorized(conn, additional_headers);
const char *buffer = "Set-Cookie: user_id=deleted; Path=/; Max-Age=-1\r\n";
my_set_cookie_header(conn, buffer);
return send_json_unauthorized(conn);
}
}

View File

@ -39,7 +39,7 @@ int api_dns_status(struct mg_connection *conn)
// Verify requesting client is allowed to access this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
char buffer[1024];
@ -47,7 +47,7 @@ int api_dns_status(struct mg_connection *conn)
if ((data_len < 1) || (data_len >= (int)sizeof(buffer))) {
return send_json_error(conn, 400,
"bad_request", "No request body data",
NULL, NULL);
NULL);
}
buffer[data_len] = '\0';
@ -56,7 +56,7 @@ int api_dns_status(struct mg_connection *conn)
return send_json_error(conn, 400,
"bad_request",
"Invalid request body data",
NULL, NULL);
NULL);
}
cJSON *elem1 = cJSON_GetObjectItemCaseSensitive(obj, "action");
@ -65,7 +65,7 @@ int api_dns_status(struct mg_connection *conn)
return send_json_error(conn, 400,
"bad_request",
"No \"action\" string in body data",
NULL, NULL);
NULL);
}
const char *action = elem1->valuestring;
@ -101,7 +101,7 @@ int api_dns_status(struct mg_connection *conn)
return send_json_error(conn, 400,
"bad_request",
"Invalid \"action\" requested",
NULL, NULL);
NULL);
}
JSON_SEND_OBJECT(json);
}
@ -149,7 +149,7 @@ static int api_dns_somelist_POST(struct mg_connection *conn,
if ((data_len < 1) || (data_len >= (int)sizeof(buffer))) {
return send_json_error(conn, 400,
"bad_request", "No request body data",
NULL, NULL);
NULL);
}
buffer[data_len] = '\0';
@ -158,7 +158,7 @@ static int api_dns_somelist_POST(struct mg_connection *conn,
return send_json_error(conn, 400,
"bad_request",
"Invalid request body data",
NULL, NULL);
NULL);
}
cJSON *elem = cJSON_GetObjectItemCaseSensitive(obj, "domain");
@ -168,7 +168,7 @@ static int api_dns_somelist_POST(struct mg_connection *conn,
return send_json_error(conn, 400,
"bad_request",
"No \"domain\" string in body data",
NULL, NULL);
NULL);
}
const char *domain = elem->valuestring;
@ -199,7 +199,7 @@ static int api_dns_somelist_POST(struct mg_connection *conn,
return send_json_error(conn, 500,
"database_error",
"Could not add domain to database table",
json, NULL);
json);
}
}
@ -240,7 +240,7 @@ static int api_dns_somelist_DELETE(struct mg_connection *conn,
return send_json_error(conn, 500,
"database_error",
"Could not remove domain from database table",
json, NULL);
json);
}
}
@ -249,7 +249,7 @@ int api_dns_somelist(struct mg_connection *conn, bool exact, bool whitelist)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
int method = http_method(conn);

View File

@ -37,7 +37,7 @@ int api_ftl_dnsmasq_log(struct mg_connection *conn)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
unsigned int start = 0u;

View File

@ -20,35 +20,36 @@
static struct mg_context *ctx = NULL;
int send_http(struct mg_connection *conn, const char *mime_type,
const char *additional_headers, const char *msg)
const char *msg)
{
mg_send_http_ok(conn, mime_type, additional_headers, strlen(msg));
mg_send_http_ok(conn, mime_type, NULL, strlen(msg));
return mg_write(conn, msg, strlen(msg));
}
int send_http_code(struct mg_connection *conn, const char *mime_type,
const char *additional_headers, int code, const char *msg)
int code, const char *msg)
{
// Payload will be sent with text/plain encoding due to
// the first line being "Error <code>" by definition
//return mg_send_http_error(conn, code, "%s", msg);
my_send_http_error_headers(conn, code, mime_type,
additional_headers, strlen(msg));
my_send_http_error_headers(conn, code,
mime_type,
strlen(msg));
return mg_write(conn, msg, strlen(msg));
}
int send_json_unauthorized(struct mg_connection *conn,
char *additional_headers)
int send_json_unauthorized(struct mg_connection *conn)
{
return send_json_error(conn, 401,
"unauthorized",
"Unauthorized",
NULL, additional_headers);
NULL);
}
int send_json_error(struct mg_connection *conn, const int code,
const char *key, const char* message,
cJSON *data, char *additional_headers)
cJSON *data)
{
cJSON *json = JSON_NEW_OBJ();
cJSON *error = JSON_NEW_OBJ();
@ -67,32 +68,14 @@ int send_json_error(struct mg_connection *conn, const int code,
JSON_OBJ_ADD_ITEM(json, "error", error);
// Send additional headers if supplied
if(additional_headers == NULL)
{
JSON_SEND_OBJECT_CODE(json, code);
}
else
{
JSON_SEND_OBJECT_AND_HEADERS_CODE(json, code, additional_headers);
}
JSON_SEND_OBJECT_CODE(json, code);
}
int send_json_success(struct mg_connection *conn,
char * additional_headers)
int send_json_success(struct mg_connection *conn)
{
cJSON *json = JSON_NEW_OBJ();
JSON_OBJ_REF_STR(json, "status", "success");
// Send additional headers if supplied
if(additional_headers == NULL)
{
JSON_SEND_OBJECT(json);
}
else
{
JSON_SEND_OBJECT_AND_HEADERS(json, additional_headers);
}
JSON_SEND_OBJECT(json);
}
int send_http_internal_error(struct mg_connection *conn)
@ -148,7 +131,7 @@ bool __attribute__((pure)) startsWith(const char *path, const char *uri)
// Print passed string directly
static int print_simple(struct mg_connection *conn, void *input)
{
return send_http(conn, "text/plain", NULL, input);
return send_http(conn, "text/plain", input);
}
static char *indexfile_content = NULL;

View File

@ -23,18 +23,14 @@
void http_init(void);
void http_terminate(void);
int send_http(struct mg_connection *conn, const char *mime_type,
const char *additional_headers, const char *msg);
int send_http_code(struct mg_connection *conn, const char *mime_type,
const char *additional_headers, int code, const char *msg);
int send_http(struct mg_connection *conn, const char *mime_type, const char *msg);
int send_http_code(struct mg_connection *conn, const char *mime_type, int code, const char *msg);
int send_http_internal_error(struct mg_connection *conn);
int send_json_unauthorized(struct mg_connection *conn,
char *additional_headers);
int send_json_unauthorized(struct mg_connection *conn);
int send_json_error(struct mg_connection *conn, const int code,
const char *key, const char* message,
cJSON *data, char *additional_headers);
int send_json_success(struct mg_connection *conn,
char * additional_headers);
cJSON *data);
int send_json_success(struct mg_connection *conn);
void http_reread_index_html(void);

View File

@ -129,7 +129,7 @@
send_http_internal_error(conn); \
return 500; \
} \
send_http(conn, "application/json; charset=utf-8", NULL, msg); \
send_http(conn, "application/json; charset=utf-8", msg); \
cJSON_Delete(object); \
return 200; \
}
@ -142,11 +142,11 @@
send_http_internal_error(conn); \
return 500; \
} \
send_http_code(conn, "application/json; charset=utf-8", NULL, code, msg); \
send_http_code(conn, "application/json; charset=utf-8", code, msg); \
cJSON_Delete(object); \
return 200; \
}
/*
#define JSON_SEND_OBJECT_AND_HEADERS(object, additional_headers){ \
const char* msg = JSON_FORMATTER(object); \
if(msg == NULL) \
@ -174,3 +174,4 @@
free(additional_headers); \
return code; \
}
*/

View File

@ -130,7 +130,7 @@ int api_handler(struct mg_connection *conn, void *ignored)
ret = send_json_error(conn, 404,
"not_found",
"Not found",
json, NULL);
json);
}
// Unlock after API access

View File

@ -32,7 +32,7 @@ int api_settings_ftldb(struct mg_connection *conn)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
send_json_unauthorized(conn, NULL);
send_json_unauthorized(conn);
}
cJSON *json = JSON_NEW_OBJ();

View File

@ -169,7 +169,7 @@ int api_stats_top_domains(bool blocked, struct mg_connection *conn)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
// Exit before processing any data if requested via config setting
@ -326,7 +326,7 @@ int api_stats_top_clients(bool blocked, struct mg_connection *conn)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
// Exit before processing any data if requested via config setting
@ -448,7 +448,7 @@ int api_stats_upstreams(struct mg_connection *conn)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
for(int upstreamID = 0; upstreamID < counters->forwarded; upstreamID++)
{
@ -560,7 +560,7 @@ int api_stats_history(struct mg_connection *conn)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
// Do we want a more specific version of this command (domain/client/time interval filtered)?
@ -658,7 +658,7 @@ int api_stats_history(struct mg_connection *conn)
return send_json_error(conn, 400,
"bad_request",
"Requested upstream not found",
json, NULL);
json);
}
}
}
@ -701,7 +701,7 @@ int api_stats_history(struct mg_connection *conn)
return send_json_error(conn, 400,
"bad_request",
"Requested domain not found",
json, NULL);
json);
}
}
@ -746,7 +746,7 @@ int api_stats_history(struct mg_connection *conn)
return send_json_error(conn, 400,
"bad_request",
"Requested client not found",
json, NULL);
json);
}
}
@ -771,7 +771,7 @@ int api_stats_history(struct mg_connection *conn)
return send_json_error(conn, 400,
"bad_request",
"Requested cursor larger than number of queries",
json, NULL);
json);
}
}
@ -938,7 +938,7 @@ int api_stats_recentblocked(struct mg_connection *conn)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
// Exit before processing any data if requested via config setting
@ -1011,7 +1011,7 @@ int api_stats_overTime_clients(struct mg_connection *conn)
// Verify requesting client is allowed to see this ressource
if(check_client_auth(conn) < 0)
{
return send_json_unauthorized(conn, NULL);
return send_json_unauthorized(conn);
}
// Exit before processing any data if requested via config setting

View File

@ -2812,6 +2812,8 @@ struct mg_connection {
void *tls_user_ptr; /* User defined pointer in thread local storage,
* for quick access */
char *cookie_header; // <---- Pi-hole modification
};
@ -4390,6 +4392,16 @@ send_additional_header(struct mg_connection *conn)
}
#endif
/**************** Pi-hole modification ****************/
if(conn->cookie_header != NULL &&
conn->cookie_header[0])
{
i += mg_printf(conn, "%s", conn->cookie_header);
mg_free(conn->cookie_header);
conn->cookie_header = NULL;
}
/******************************************************/
if (header && header[0]) {
i += mg_printf(conn, "%s\r\n", header);
}
@ -4788,7 +4800,6 @@ mg_send_http_error_impl(struct mg_connection *conn,
/************************************** Pi-hole method **************************************/
void my_send_http_error_headers(struct mg_connection *conn,
int status, const char* mime_type,
const char *additional_headers,
long long content_length)
{
/* Set status (for log) */
@ -4809,15 +4820,15 @@ void my_send_http_error_headers(struct mg_connection *conn,
mime_type,
date);
// We may use additional headers to set or clear cookies
if(additional_headers != NULL && strlen(additional_headers) > 0)
{
mg_write(conn, additional_headers, strlen(additional_headers));
}
mg_printf(conn, "Content-Length: %" UINT64_FMT "\r\n\r\n",
(uint64_t)content_length);
}
void my_set_cookie_header(struct mg_connection *conn,
const char *cookie_header)
{
conn->cookie_header = mg_strdup(cookie_header);
}
/********************************************************************************************/
int
@ -17994,6 +18005,7 @@ worker_thread_run(struct mg_connection *conn)
#if defined(USE_SERVER_STATS)
conn->conn_state = 1; /* not consumed */
#endif
conn->cookie_header = NULL; // <--- Pi-hole modification
/* Call consume_socket() even when ctx->stop_flag > 0, to let it
* signal sq_empty condvar to wake up the master waiting in

View File

@ -935,8 +935,9 @@ CIVETWEB_API int mg_send_http_error(struct mg_connection *conn,
/************************************** Pi-hole method **************************************/
void my_send_http_error_headers(struct mg_connection *conn,
int status, const char* mime_type,
const char *additional_headers,
// const char *additional_headers,
long long content_length);
void my_set_cookie_header(struct mg_connection *conn, const char *cookie_header);
/********************************************************************************************/