From 0c1c2b0bc3d5fc6feb57d231af2815bdba83649d Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 16 Jan 2023 21:33:01 +0100 Subject: [PATCH] Add /api/config:dnsmasq.cnames Signed-off-by: DL6ER --- src/api/docs/content/specs/config.yaml | 7 +++ src/config/config.c | 8 +++ src/config/config.h | 1 + src/config/dnsmasq_config.c | 76 ++++++++++++++++++++++++++ src/config/dnsmasq_config.h | 2 + src/dnsmasq_interface.c | 2 +- test/pihole-FTL.toml | 6 ++ 7 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/api/docs/content/specs/config.yaml b/src/api/docs/content/specs/config.yaml index 9374a27d..7f9cd091 100644 --- a/src/api/docs/content/specs/config.yaml +++ b/src/api/docs/content/specs/config.yaml @@ -168,6 +168,10 @@ components: type: integer logging: type: boolean + cnames: + type: array + items: + type: string rev_server: type: object properties: @@ -424,6 +428,9 @@ components: listening_mode: "local" cache_size: 10000 logging: true + cnames: + - "*.example.com,default.example.com" + - "hourly.yetanother.com,yetanother.com,3600" rev_server: active: false cidr: "192.168.0.0/24" diff --git a/src/config/config.c b/src/config/config.c index f2d96da0..fa3bef07 100644 --- a/src/config/config.c +++ b/src/config/config.c @@ -339,6 +339,13 @@ void initConfig(void) config.dnsmasq.logging.d.b = true; config.dnsmasq.logging.restart_dnsmasq = true; + config.dnsmasq.cnames.k = "dnsmasq.cnames"; + config.dnsmasq.cnames.h = "List of CNAME records which indicate that is really . If the is given, it overwrites the value of local-ttl"; + config.dnsmasq.cnames.a = "Array of static leases each on in one of the following forms: \",[,]\""; + config.dnsmasq.cnames.t = CONF_JSON_STRING_ARRAY; + config.dnsmasq.cnames.d.json = cJSON_CreateArray(); + config.dnsmasq.cnames.restart_dnsmasq = true; + // sub-struct rev_server config.dnsmasq.rev_server.active.k = "dnsmasq.rev_server.active"; config.dnsmasq.rev_server.active.h = "Is the reverse server (former also called \"conditional forwarding\") feature enabled?"; @@ -859,6 +866,7 @@ void readFTLconf(const bool rewrite) write_dnsmasq_config(false); } read_legacy_dhcp_static_config(); + read_legacy_cnames_config(); return; } diff --git a/src/config/config.h b/src/config/config.h index e41bbfb1..d2ff5e81 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -156,6 +156,7 @@ struct config { struct conf_item listening_mode; struct conf_item cache_size; struct conf_item logging; + struct conf_item cnames; struct { struct conf_item active; struct conf_item cidr; diff --git a/src/config/dnsmasq_config.c b/src/config/dnsmasq_config.c index d974f1f4..3f6c1222 100644 --- a/src/config/dnsmasq_config.c +++ b/src/config/dnsmasq_config.c @@ -283,6 +283,19 @@ bool __attribute__((const)) write_dnsmasq_config(bool test_config) } } + if(cJSON_GetArraySize(config.dnsmasq.cnames.v.json) > 0) + { + fputs("# User-defined custom CNAMEs\n", pihole_conf); + const int n = cJSON_GetArraySize(config.dnsmasq.cnames.v.json); + for(int i = 0; i < n; i++) + { + cJSON *server = cJSON_GetArrayItem(config.dnsmasq.cnames.v.json, i); + if(server != NULL && cJSON_IsString(server)) + fprintf(pihole_conf, "cname=%s\n", server->valuestring); + } + fputs("\n", pihole_conf); + } + fputs("# RFC 6761: Caching DNS servers SHOULD recognize\n", pihole_conf); fputs("# test, localhost, invalid\n", pihole_conf); fputs("# names as special and SHOULD NOT attempt to look up NS records for them, or\n", pihole_conf); @@ -411,3 +424,66 @@ bool read_legacy_dhcp_static_config(void) return true; } + + +bool read_legacy_cnames_config(void) +{ + // Check if file exists, if not, there is nothing to do + const char *path = DNSMASQ_CNAMES; + const char *target = DNSMASQ_CNAMES".bck"; + if(!file_exists(path)) + return true; + + FILE *fp = fopen(path, "r"); + if(!fp) + { + log_err("Cannot read %s for reading, unable to import list of custom cnames: %s", + path, strerror(errno)); + return false; + } + + char *linebuffer = NULL; + size_t size = 0u; + errno = 0; + unsigned int j = 0; + while(getline(&linebuffer, &size, fp) != -1) + { + // Check if memory allocation failed + if(linebuffer == NULL) + break; + + // Skip lines with other keys + if((strstr(linebuffer, "cname=")) == NULL) + continue; + + // Note: value is still a pointer into the linebuffer + char *value = find_equals(linebuffer) + 1; + // Trim whitespace at beginning and end, this function + // modifies the string inplace + trim_whitespace(value); + + // Add entry to config.dnsmasq.cnames + cJSON *item = cJSON_CreateString(value); + cJSON_AddItemToArray(config.dnsmasq.cnames.v.json, item); + + log_debug(DEBUG_CONFIG, DNSMASQ_CNAMES": Setting %s[%d] = %s\n", + config.dnsmasq.cnames.k, j++, item->valuestring); + } + + // Free allocated memory + free(linebuffer); + + // Close file + if(fclose(fp) != 0) + { + log_err("Cannot close %s: %s", path, strerror(errno)); + return false; + } + + // Move file to backup location + log_info("Moving %s to %s", path, target); + if(rename(path, target) != 0) + log_warn("Unable to move %s to %s: %s", path, target, strerror(errno)); + + return true; +} diff --git a/src/config/dnsmasq_config.h b/src/config/dnsmasq_config.h index daee497f..21e46728 100644 --- a/src/config/dnsmasq_config.h +++ b/src/config/dnsmasq_config.h @@ -12,10 +12,12 @@ bool write_dnsmasq_config(bool test_config); bool read_legacy_dhcp_static_config(void); +bool read_legacy_cnames_config(void); #define DNSMASQ_PH_CONFIG "/etc/pihole/dnsmasq.conf" #define DNSMASQ_TEMP_CONF "/etc/pihole/dnsmasq.conf.temp" #define DNSMASQ_STATIC_LEASES "/etc/pihole/04-pihole-static-dhcp.conf" +#define DNSMASQ_CNAMES "/etc/pihole/05-pihole-custom-cname.conf" #define DNSMASQ_CUSTOM_LIST "/etc/pihole/custom.list" #endif //DNSMASQ_CONFIG_H diff --git a/src/dnsmasq_interface.c b/src/dnsmasq_interface.c index 85d74689..ca96cae0 100644 --- a/src/dnsmasq_interface.c +++ b/src/dnsmasq_interface.c @@ -3306,7 +3306,7 @@ int check_struct_sizes(void) int result = 0; // sizeof(struct conf_item) is 72 on x86_64 and 52 on x86_32 // number of config elements: CONFIG_ELEMENTS - result += check_one_struct("struct config", sizeof(struct config), 8136, 5876); + result += check_one_struct("struct config", sizeof(struct config), 8208, 5928); result += check_one_struct("queriesData", sizeof(queriesData), 72, 64); result += check_one_struct("upstreamsData", sizeof(upstreamsData), 640, 628); result += check_one_struct("clientsData", sizeof(clientsData), 672, 652); diff --git a/test/pihole-FTL.toml b/test/pihole-FTL.toml index 5a857287..0bc43132 100644 --- a/test/pihole-FTL.toml +++ b/test/pihole-FTL.toml @@ -139,6 +139,12 @@ # Log DNS queries and replies to pihole.log logging = true + # List of CNAME records which indicate that is really . If the is + # given, it overwrites the value of local-ttl + # Possible values are: Array of static leases each on in one of the following forms: + # ",[,]" + cnames = [ ] + [dnsmasq.rev_server] # Is the reverse server (former also called "conditional forwarding") feature enabled? active = false