Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store subnet warnings in the message table #756

Merged
merged 1 commit into from May 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 57 additions & 7 deletions src/database/gravity-db.c
Expand Up @@ -10,18 +10,17 @@

#include "FTL.h"
#include "sqlite3.h"
#include "datastructure.h"
#include "gravity-db.h"
#include "config.h"
#include "log.h"
// global variable counters
#include "memory.h"
// match_regex()
#include "regex_r.h"
// getstr()
#include "shmem.h"
// SQLite3 prepared statement vectors
#include "../vector.h"
// log_subnet_warning()
#include "database/message-table.h"

// Process-private prepared statements are used to support multiple forks (might
// be TCP workers) to use the database simultaneously without corrupting the
Expand Down Expand Up @@ -289,10 +288,7 @@ static bool get_client_groupids(clientsData* client)
// Device 10.8.0.22
// Client 1: 10.8.0.0/24
// Client 2: 10.8.1.0/24
logg("CLIENT GROUPS WARNING: Client %s is managed by %i groups (IDs %s), all describing /%i subnets. "
"FTL chose the most recent entry %s (ID %i) for this client.",
ip, matching_count, matching_ids, matching_bits,
chosen_match_text, chosen_match_id);
logg_subnet_warning(ip, matching_count, matching_ids, matching_bits, chosen_match_text, chosen_match_id);
}
free(matching_ids);
matching_ids = NULL;
Expand Down Expand Up @@ -357,6 +353,60 @@ static bool get_client_groupids(clientsData* client)
return true;
}

char* __attribute__ ((malloc)) get_group_names(const char *group_ids)
{
// Build query string to get concatenated groups
char *querystr = NULL;
if(asprintf(&querystr, "SELECT GROUP_CONCAT(ip) FROM client "
"WHERE id IN (%s);", group_ids) < 1)
{
logg("group_names(%s) - asprintf() error", group_ids);
return false;
}

if(config.debug & DEBUG_DATABASE)
logg("Querying group names for IDs (%s)", group_ids);

// Prepare query
int rc = sqlite3_prepare_v2(gravity_db, querystr, -1, &table_stmt, NULL);
if(rc != SQLITE_OK){
logg("get_client_groupids(%s) - SQL error prepare: %s",
querystr, sqlite3_errstr(rc));
sqlite3_finalize(table_stmt);
free(querystr);
return strdup("N/A");
}

// Perform query
char *result = NULL;
rc = sqlite3_step(table_stmt);
if(rc == SQLITE_ROW)
{
// There is a record for this client in the database
result = strdup((const char*)sqlite3_column_text(table_stmt, 0));
if(result == NULL)
result = strdup("N/A");
}
else if(rc == SQLITE_DONE)
{
// Found no record for this client in the database
// -> No associated groups
result = strdup("N/A");
}
else
{
logg("group_names(%s) - SQL error step: %s",
querystr, sqlite3_errstr(rc));
gravityDB_finalizeTable();
free(querystr);
return strdup("N/A");
}
// Finalize statement
gravityDB_finalizeTable();
free(querystr);
return result;
}

// Prepare statements for scanning white- and blacklist as well as gravit for one client
bool gravityDB_prepare_client_statements(const int clientID, clientsData *client)
{
Expand Down
6 changes: 6 additions & 0 deletions src/database/gravity-db.h
Expand Up @@ -10,6 +10,11 @@
#ifndef GRAVITY_H
#define GRAVITY_H

// global variable counters
#include "memory.h"
// clients data structure
#include "datastructure.h"

// Table indices
enum { GRAVITY_TABLE, EXACT_BLACKLIST_TABLE, EXACT_WHITELIST_TABLE, REGEX_BLACKLIST_TABLE, REGEX_WHITELIST_TABLE, UNKNOWN_TABLE };

Expand All @@ -18,6 +23,7 @@ bool gravityDB_prepare_client_statements(const int clientID, clientsData* client
void gravityDB_close(void);
bool gravityDB_getTable(unsigned char list);
const char* gravityDB_getDomain(int *rowid);
char* get_group_names(const char *group_ids) __attribute__ ((malloc));
void gravityDB_finalizeTable(void);
int gravityDB_count(unsigned char list);
bool in_auditlist(const char *domain);
Expand Down
28 changes: 26 additions & 2 deletions src/database/message-table.c
Expand Up @@ -12,9 +12,11 @@
#include "database/message-table.h"
#include "database/common.h"
#include "log.h"
// get_group_names()
#include "database/gravity-db.h"

static const char *message_types[MAX_MESSAGE] =
{ "REGEX" };
{ "REGEX", "SUBNET" };

static unsigned char message_blob_types[MAX_MESSAGE][5] =
{
Expand All @@ -24,9 +26,15 @@ static unsigned char message_blob_types[MAX_MESSAGE][5] =
SQLITE_INTEGER, // database index of regex (so the dashboard can show a link)
SQLITE_NULL, // not used
SQLITE_NULL // not used
},
{ // SUBNET_MESSAGE: The message column contains the IP address of the client in question
SQLITE_INTEGER, // number of matching
SQLITE_TEXT, // comma-separated list of matching subnets (text representation)
SQLITE_TEXT, // comma-separated list of matching subnets (database IDs)
SQLITE_TEXT, // chosen subnet (text representation)
SQLITE_INTEGER // chosen subnet (database ID)
}
};

// Create message table in the database
bool create_message_table(void)
{
Expand Down Expand Up @@ -163,3 +171,19 @@ void logg_regex_warning(const char *type, const char *warning, const int dbindex
// Log to database
add_message(REGEX_MESSAGE, warning, 3, type, regex, dbindex);
}

void logg_subnet_warning(const char *ip, const int matching_count, const char *matching_ids,
const int matching_bits, const char *chosen_match_text,
const int chosen_match_id)
{
// Log to pihole-FTL.log
logg("SUBNET WARNING: Client %s is managed by %i groups (IDs %s), all describing /%i subnets. "
"FTL chose the most recent entry %s (ID %i) for this client.",
ip, matching_count, matching_ids, matching_bits,
chosen_match_text, chosen_match_id);

// Log to database
char *names = get_group_names(matching_ids);
add_message(SUBNET_MESSAGE, ip, 5, matching_count, names, matching_ids, chosen_match_text, chosen_match_id);
free(names);
}
5 changes: 4 additions & 1 deletion src/database/message-table.h
Expand Up @@ -13,7 +13,10 @@
bool create_message_table(void);
bool flush_message_table(void);
void logg_regex_warning(const char *type, const char *warning, const int dbindex, const char *regex);
void logg_subnet_warning(const char *ip, const int matching_count, const char *matching_ids,
const int matching_bits, const char *chosen_match_text,
const int chosen_match_id);

enum message_type { REGEX_MESSAGE, MAX_MESSAGE };
enum message_type { REGEX_MESSAGE, SUBNET_MESSAGE, MAX_MESSAGE };

#endif //MESSAGETABLE_H