Also allow authentication by sending SID via HEADER

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER 2021-02-03 09:08:23 +01:00
parent 948ed62f72
commit fcbe840804
No known key found for this signature in database
GPG Key ID: 00135ACBD90B28DD
6 changed files with 48 additions and 21 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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