Also allow authentication by sending SID via HEADER
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
parent
948ed62f72
commit
fcbe840804
|
@ -45,7 +45,7 @@ int api_ftl_client(struct ftl_conn *api);
|
|||
int api_ftl_logs_dns(struct ftl_conn *api);
|
||||
int api_ftl_dbinfo(struct ftl_conn *api);
|
||||
int api_ftl_sysinfo(struct ftl_conn *api);
|
||||
int get_ftl_obj(struct ftl_conn *api, cJSON *ftl);
|
||||
int get_ftl_obj(struct ftl_conn *api, cJSON *ftl, const bool is_locked);
|
||||
int get_system_obj(struct ftl_conn *api, cJSON *system);
|
||||
|
||||
// Network methods
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include "../config.h"
|
||||
// read_setupVarsconf()
|
||||
#include "../setupVars.h"
|
||||
// (un)lock_shm()
|
||||
#include "../shmem.h"
|
||||
|
||||
// crypto library
|
||||
#include <nettle/sha2.h>
|
||||
|
@ -126,6 +128,19 @@ int check_client_auth(struct ftl_conn *api)
|
|||
}
|
||||
}
|
||||
|
||||
// If not, does the client provide a session ID via HEADER?
|
||||
if(!sid_avail)
|
||||
{
|
||||
const char *sid_header = NULL;
|
||||
if((sid_header = mg_get_header(api->conn, "sid")) != NULL)
|
||||
{
|
||||
strncpy(sid, sid_header, SID_SIZE - 1u);
|
||||
sid[SID_SIZE-1] = '\0';
|
||||
sid_source = "header";
|
||||
sid_avail = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!sid_avail)
|
||||
{
|
||||
if(config.debug & DEBUG_API)
|
||||
|
@ -336,7 +351,7 @@ static void generateChallenge(const unsigned int idx, const time_t now)
|
|||
challenges[idx].valid_until = now + API_CHALLENGE_TIMEOUT;
|
||||
}
|
||||
|
||||
static void generateResponse(const unsigned int idx)
|
||||
static void generateResponse(const unsigned int idx, const char *password_hash)
|
||||
{
|
||||
uint8_t raw_response[SHA256_DIGEST_SIZE];
|
||||
struct sha256_ctx ctx;
|
||||
|
@ -351,12 +366,9 @@ static void generateResponse(const unsigned int idx)
|
|||
sha256_update(&ctx, 1, (uint8_t*)":");
|
||||
|
||||
// Get and add password hash from setupVars.conf
|
||||
char *password_hash = get_password_hash();
|
||||
sha256_update(&ctx,
|
||||
strlen(password_hash),
|
||||
(uint8_t*)password_hash);
|
||||
free(password_hash);
|
||||
password_hash = NULL;
|
||||
strlen(password_hash),
|
||||
(uint8_t*)password_hash);
|
||||
|
||||
sha256_digest(&ctx, SHA256_DIGEST_SIZE, raw_response);
|
||||
sha256_hex(raw_response, challenges[idx].response);
|
||||
|
@ -386,7 +398,9 @@ int api_auth(struct ftl_conn *api)
|
|||
// Check HTTP method
|
||||
const time_t now = time(NULL);
|
||||
|
||||
lock_shm();
|
||||
char *password_hash = get_password_hash();
|
||||
unlock_shm();
|
||||
const bool empty_password = (strlen(password_hash) == 0u);
|
||||
|
||||
int user_id = API_AUTH_UNAUTHORIZED;
|
||||
|
@ -548,7 +562,7 @@ int api_auth(struct ftl_conn *api)
|
|||
generateChallenge(i, now);
|
||||
|
||||
// Compute and store expected response for this challenge (SHA-256)
|
||||
generateResponse(i);
|
||||
generateResponse(i, password_hash);
|
||||
|
||||
// Free allocated memory
|
||||
free(password_hash);
|
||||
|
|
|
@ -27,13 +27,6 @@ components:
|
|||
$ref: '#/components/examples/no_login_required'
|
||||
login_required:
|
||||
$ref: '#/components/examples/login_required'
|
||||
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: 'common.yaml#/components/errors/unauthorized'
|
||||
post:
|
||||
summary: Submit response for login
|
||||
tags:
|
||||
|
@ -116,6 +109,9 @@ components:
|
|||
schemas:
|
||||
session:
|
||||
type: object
|
||||
required:
|
||||
- challenge
|
||||
- session
|
||||
properties:
|
||||
challenge:
|
||||
type: string
|
||||
|
@ -124,6 +120,10 @@ components:
|
|||
session:
|
||||
type: object
|
||||
description: Session object
|
||||
required:
|
||||
- valid
|
||||
- sid
|
||||
- validity
|
||||
properties:
|
||||
valid:
|
||||
type: boolean
|
||||
|
|
|
@ -387,12 +387,13 @@ int get_system_obj(struct ftl_conn *api, cJSON *system)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int get_ftl_obj(struct ftl_conn *api, cJSON *ftl)
|
||||
int get_ftl_obj(struct ftl_conn *api, cJSON *ftl, const bool is_locked)
|
||||
{
|
||||
cJSON *database = JSON_NEW_OBJ();
|
||||
|
||||
// Source from shared objects within lock
|
||||
lock_shm();
|
||||
if(!is_locked)
|
||||
lock_shm();
|
||||
const int db_gravity = counters->database.gravity;
|
||||
const int db_groups = counters->database.groups;
|
||||
const int db_lists = counters->database.lists;
|
||||
|
@ -414,7 +415,8 @@ int get_ftl_obj(struct ftl_conn *api, cJSON *ftl)
|
|||
if(client->count > 0)
|
||||
activeclients++;
|
||||
}
|
||||
unlock_shm();
|
||||
if(!is_locked)
|
||||
unlock_shm();
|
||||
|
||||
JSON_OBJ_ADD_NUMBER(database, "gravity", db_gravity);
|
||||
JSON_OBJ_ADD_NUMBER(database, "groups", db_groups);
|
||||
|
@ -451,7 +453,7 @@ int api_ftl_sysinfo(struct ftl_conn *api)
|
|||
|
||||
// Get FTL object
|
||||
cJSON *ftl = JSON_NEW_OBJ();
|
||||
ret = get_ftl_obj(api, ftl);
|
||||
ret = get_ftl_obj(api, ftl, false);
|
||||
if(ret != 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ int api_stats_summary(struct ftl_conn *api)
|
|||
JSON_OBJ_ADD_ITEM(queries, "types", types);
|
||||
|
||||
JSON_OBJ_ADD_NUMBER(queries, "sum", counters->queries);
|
||||
|
||||
|
||||
cJSON *replies = JSON_NEW_OBJ();
|
||||
JSON_OBJ_ADD_NUMBER(replies, "NODATA", counters->reply_NODATA);
|
||||
JSON_OBJ_ADD_NUMBER(replies, "NXDOMAIN", counters->reply_NXDOMAIN);
|
||||
|
@ -118,7 +118,7 @@ int api_stats_summary(struct ftl_conn *api)
|
|||
|
||||
// Get FTL object
|
||||
cJSON *ftl = JSON_NEW_OBJ();
|
||||
ret = get_ftl_obj(api, ftl);
|
||||
ret = get_ftl_obj(api, ftl, true);
|
||||
if(ret != 0)
|
||||
return ret;
|
||||
JSON_OBJ_ADD_ITEM(json, "ftl", ftl);
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
// Pi-hole: A black hole for Internet advertisements
|
||||
// (c) 2021 Pi-hole, LLC (https://pi-hole.net)
|
||||
// Network-wide ad blocking via your own hardware.
|
||||
//
|
||||
// FTL - API test file
|
||||
//
|
||||
// This is a node script
|
||||
//
|
||||
// This file is copyright under the latest version of the EUPL.
|
||||
// Please see LICENSE file for your rights under this license.
|
||||
|
||||
const Enforcer = require('openapi-enforcer');
|
||||
|
||||
// JSON and YAML files accepted
|
||||
|
|
Loading…
Reference in New Issue