mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
595ab259ca
Adjusted tests to fit the current lack of output on the unix socket. Added TELNET enum and used it in place of the old SOCKET to better fit with the rest of the code base. Signed-off-by: Mcat12 <newtoncat12@yahoo.com>
253 lines
5.9 KiB
C
253 lines
5.9 KiB
C
/* Pi-hole: A black hole for Internet advertisements
|
|
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
* Network-wide ad blocking via your own hardware.
|
|
*
|
|
* FTL Engine
|
|
* API /dns/
|
|
*
|
|
* This file is copyright under the latest version of the EUPL.
|
|
* Please see LICENSE file for your rights under this license. */
|
|
|
|
#include "FTL.h"
|
|
#include "api.h"
|
|
#include "cJSON.h"
|
|
|
|
void getList(int *sock, char type, char list_type) {
|
|
FILE *fp;
|
|
char *line = NULL;
|
|
size_t size = 0;
|
|
const char *file;
|
|
const char *name;
|
|
|
|
if(list_type == WHITELIST) {
|
|
file = files.whitelist;
|
|
name = "whitelist";
|
|
}
|
|
else if(list_type == BLACKLIST) {
|
|
file = files.blacklist;
|
|
name = "blacklist";
|
|
}
|
|
else {
|
|
file = files.wildcards;
|
|
name = "wildlist";
|
|
}
|
|
|
|
// sendAPIResponse(*sock, type, OK);
|
|
ssend(*sock, "\"%s\":[", name);
|
|
|
|
if((fp = fopen(file, "r")) != NULL)
|
|
{
|
|
bool first = true;
|
|
bool skipEveryOther = false;
|
|
bool skip = true;
|
|
char *parsedLine;
|
|
|
|
// Check if both IPv4 and IPv6 are used. If so, skip every other line in if we're getting wildcard domains
|
|
if(list_type == WILDLIST) {
|
|
char *ipv4 = read_setupVarsconf("IPV4_ADDRESS");
|
|
size_t ipv4_len = strlen(ipv4);
|
|
char *ipv6 = read_setupVarsconf("IPV6_ADDRESS");
|
|
size_t ipv6_len = strlen(ipv6);
|
|
|
|
if(ipv4_len > 0 && ipv6_len > 0)
|
|
skipEveryOther = true;
|
|
}
|
|
|
|
while(getline(&line, &size, fp) != -1) {
|
|
// Skip empty lines
|
|
if(line[0] == '\n')
|
|
continue;
|
|
|
|
// If applicable, skip every other line
|
|
if(skipEveryOther) {
|
|
skip = !skip;
|
|
|
|
if(skip)
|
|
continue;
|
|
}
|
|
|
|
if(!first) ssend(*sock, ",");
|
|
first = false;
|
|
|
|
// Trim off the newline, if it exists
|
|
line[strcspn(line, "\r\n")] = 0;
|
|
|
|
// Do more parsing if it's the wildcard list
|
|
if(list_type == WILDLIST) {
|
|
char *firstSlash = strstr(line, "/");
|
|
|
|
if(firstSlash == NULL) {
|
|
logg("Failed to parse wildcard line: %s", line);
|
|
continue;
|
|
}
|
|
|
|
char *secondSlash = strstr(firstSlash+1, "/");
|
|
|
|
if(secondSlash == NULL) {
|
|
logg("Failed to parse wildcard line: %s", line);
|
|
continue;
|
|
}
|
|
|
|
secondSlash[0] = 0;
|
|
parsedLine = firstSlash+1;
|
|
}
|
|
else
|
|
parsedLine = line;
|
|
|
|
ssend(*sock, "\"%s\"", parsedLine);
|
|
}
|
|
// Free allocated memory
|
|
if(line != NULL)
|
|
{
|
|
free(line);
|
|
line = NULL;
|
|
}
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
ssend(*sock, "]");
|
|
}
|
|
|
|
void getPiholeStatus(int *sock, char type) {
|
|
int status = countlineswith("#addn-hosts=/etc/pihole/gravity.list", files.dnsmasqconf);
|
|
// sendAPIResponse(*sock, type, OK);
|
|
ssend(*sock, "\"status\":%i", status == 1 ? 0 : 1);
|
|
}
|
|
|
|
void addList(int *sock, char type, char list_type, char *data) {
|
|
// cJSON *input_root = cJSON_Parse(data);
|
|
// cJSON *domain_json = cJSON_GetObjectItemCaseSensitive(input_root, "domain");
|
|
char *domain;
|
|
|
|
// Validate domain
|
|
// if(!cJSON_IsString(domain_json)) {
|
|
// // No domain found
|
|
// sendAPIResponse(*sock, type, BAD_REQUEST);
|
|
// ssend(*sock, "\"status\":\"no_domain\"");
|
|
// return;
|
|
// }
|
|
|
|
// domain = domain_json->valuestring;
|
|
|
|
if(!isValidDomain(domain)) {
|
|
// Invalid domain
|
|
// sendAPIResponse(*sock, type, BAD_REQUEST);
|
|
ssend(*sock, "\"status\":\"invalid_domain\"");
|
|
return;
|
|
}
|
|
|
|
// Get command
|
|
char *partial_command;
|
|
|
|
if(list_type == WHITELIST)
|
|
partial_command = "sudo pihole -w -q ";
|
|
else if(list_type == BLACKLIST)
|
|
partial_command = "sudo pihole -b -q ";
|
|
else if(list_type == WILDLIST)
|
|
partial_command = "sudo pihole -wild -q ";
|
|
else {
|
|
logg("Invalid list type in addList");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Run command
|
|
char *command = malloc((strlen(domain) + strlen(partial_command) + 1) * sizeof(char));
|
|
strcpy(command, partial_command);
|
|
strcat(command, domain);
|
|
int return_code = system(command);
|
|
free(command);
|
|
|
|
if(return_code == 0) {
|
|
// Successfully added to list
|
|
// sendAPIResponse(*sock, type, OK);
|
|
ssend(*sock, "\"status\":\"success\"");
|
|
}
|
|
else {
|
|
// Failed to add to list
|
|
// sendAPIResponse(*sock, type, INTERNAL_ERROR);
|
|
ssend(*sock, "\"status\":\"unknown_error\"");
|
|
}
|
|
|
|
// cJSON_Delete(input_root);
|
|
}
|
|
|
|
void removeList(int *sock, char type, char list_type, char *client_message) {
|
|
char *domain = strrchr(client_message, '/');
|
|
|
|
// Validate domain
|
|
if(domain == NULL) {
|
|
// No domain found
|
|
// sendAPIResponse(*sock, type, NOT_FOUND);
|
|
ssend(*sock, "\"status\":\"not_found\"");
|
|
return;
|
|
}
|
|
|
|
// Remove leading '/'
|
|
domain++;
|
|
|
|
// Validate route
|
|
char *expected_route_start;
|
|
char *expected_route;
|
|
|
|
if(list_type == WHITELIST)
|
|
expected_route_start = "/dns/whitelist/";
|
|
else if(list_type == BLACKLIST)
|
|
expected_route_start = "/dns/blacklist/";
|
|
else if(list_type == WILDLIST)
|
|
expected_route_start = "/dns/wildlist/";
|
|
else {
|
|
logg("Invalid list type in removeList");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
expected_route = malloc((strlen(expected_route_start) + strlen(domain) + 1) * sizeof(char));
|
|
strcpy(expected_route, expected_route_start);
|
|
strcat(expected_route, domain);
|
|
|
|
if(!strstr(client_message, expected_route)) {
|
|
// Invalid route
|
|
free(expected_route);
|
|
// sendAPIResponse(*sock, type, NOT_FOUND);
|
|
ssend(*sock, "\"status\":\"not_found\"");
|
|
return;
|
|
}
|
|
|
|
free(expected_route);
|
|
|
|
if(!isValidDomain(domain)) {
|
|
// Invalid domain
|
|
// sendAPIResponse(*sock, type, BAD_REQUEST);
|
|
ssend(*sock, "\"status\":\"invalid_domain\"");
|
|
return;
|
|
}
|
|
|
|
// Get command
|
|
char *partial_command;
|
|
|
|
if(list_type == WHITELIST)
|
|
partial_command = "sudo pihole -w -q -d ";
|
|
else if(list_type == BLACKLIST)
|
|
partial_command = "sudo pihole -b -q -d ";
|
|
else
|
|
partial_command = "sudo pihole -wild -q -d ";
|
|
|
|
// Run command
|
|
char *command = malloc((strlen(domain) + strlen(partial_command) + 1) * sizeof(char));
|
|
strcpy(command, partial_command);
|
|
strcat(command, domain);
|
|
int return_code = system(command);
|
|
free(command);
|
|
|
|
if(return_code == 0) {
|
|
// Successfully removed from list
|
|
// sendAPIResponse(*sock, type, OK);
|
|
ssend(*sock, "\"status\":\"success\"");
|
|
}
|
|
else {
|
|
// Failed to remove from list
|
|
// sendAPIResponse(*sock, type, INTERNAL_ERROR);
|
|
ssend(*sock, "\"status\":\"unknown_error\"");
|
|
}
|
|
}
|