diff --git a/src/api/docs/content/specs/config.yaml b/src/api/docs/content/specs/config.yaml index 66a48f5b..46577c5f 100644 --- a/src/api/docs/content/specs/config.yaml +++ b/src/api/docs/content/specs/config.yaml @@ -311,10 +311,6 @@ components: netmask: type: string x-format: ipv4 - domain: - type: string - description: | - *Note:* This setting is deprecated and will be removed in a future release. Use dns.domain instead. leaseTime: type: string ipv6: @@ -645,7 +641,6 @@ components: start: "192.168.0.10" end: "192.168.0.250" router: "192.168.0.1" - domain: "lan" netmask: "0.0.0.0" leaseTime: "24h" ipv6: true diff --git a/src/config/config.c b/src/config/config.c index 345bee06..f85dfc34 100644 --- a/src/config/config.c +++ b/src/config/config.c @@ -681,8 +681,8 @@ void initConfig(struct config *conf) conf->dns.revServer.target.f = FLAG_RESTART_FTL; conf->dns.revServer.domain.k = "dns.revServer.domain"; - conf->dns.revServer.domain.h = "Domain used for the reverse server feature"; - conf->dns.revServer.domain.a = cJSON_CreateStringReference(", typically set to the same value as dhcp.domain"); + conf->dns.revServer.domain.h = "Domain used for the reverse server feature (e.g., \"fritz.box\")"; + conf->dns.revServer.domain.a = cJSON_CreateStringReference(""); conf->dns.revServer.domain.t = CONF_STRING; conf->dns.revServer.domain.d.s = (char*)""; conf->dns.revServer.domain.f = FLAG_RESTART_FTL; @@ -715,13 +715,6 @@ void initConfig(struct config *conf) conf->dhcp.router.f = FLAG_RESTART_FTL; memset(&conf->dhcp.router.d.in_addr, 0, sizeof(struct in_addr)); - conf->dhcp.domain.k = "dhcp.domain"; - conf->dhcp.domain.h = "The DNS domain used by your Pi-hole (*** DEPRECATED ***)\n This setting is deprecated and will be removed in a future version. Please use dns.domain instead. Setting it to any non-default value will overwrite the value of dns.domain if it is still set to its default value."; - conf->dhcp.domain.a = cJSON_CreateStringReference(""); - conf->dhcp.domain.t = CONF_STRING; - conf->dhcp.domain.f = FLAG_RESTART_FTL | FLAG_ADVANCED_SETTING; - conf->dhcp.domain.d.s = (char*)"lan"; - conf->dhcp.netmask.k = "dhcp.netmask"; conf->dhcp.netmask.h = "The netmask used by your Pi-hole. For directly connected networks (i.e., networks on which the machine running Pi-hole has an interface) the netmask is optional and may be set to an empty string (\"\"): it will then be determined from the interface configuration itself. For networks which receive DHCP service via a relay agent, we cannot determine the netmask itself, so it should explicitly be specified, otherwise Pi-hole guesses based on the class (A, B or C) of the network address."; conf->dhcp.netmask.a = cJSON_CreateStringReference(" (e.g., \"255.255.255.0\") or empty string (\"\") for auto-discovery"); @@ -970,7 +963,7 @@ void initConfig(struct config *conf) conf->webserver.api.excludeDomains.k = "webserver.api.excludeDomains"; conf->webserver.api.excludeDomains.h = "Array of domains to be excluded from certain API responses\n Example: [ \"google.de\", \"pi-hole.net\" ]"; - conf->webserver.api.excludeDomains.a = cJSON_CreateStringReference("array of IP addresses and/or hostnames"); + conf->webserver.api.excludeDomains.a = cJSON_CreateStringReference("array of domains"); conf->webserver.api.excludeDomains.t = CONF_JSON_STRING_ARRAY; conf->webserver.api.excludeDomains.d.json = cJSON_CreateArray(); diff --git a/src/config/config.h b/src/config/config.h index cdacdbe3..12dd5194 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -183,7 +183,6 @@ struct config { struct conf_item start; struct conf_item end; struct conf_item router; - struct conf_item domain; struct conf_item netmask; struct conf_item leaseTime; struct conf_item ipv6; diff --git a/src/config/toml_writer.c b/src/config/toml_writer.c index 5f892daf..34090096 100644 --- a/src/config/toml_writer.c +++ b/src/config/toml_writer.c @@ -25,25 +25,6 @@ // defined in config/config.c extern uint8_t last_checksum[SHA256_DIGEST_SIZE]; -static void migrate_config(void) -{ - // Migrating dhcp.domain -> dns.domain - if(strcmp(config.dns.domain.v.s, config.dns.domain.d.s) == 0) - { - // If the domain is the same as the default, check if the dhcp domain - // is different from the default. If so, migrate it - if(strcmp(config.dhcp.domain.v.s, config.dhcp.domain.d.s) != 0) - { - // Migrate dhcp.domain -> dns.domain - log_info("Migrating dhcp.domain = \"%s\" -> dns.domain", config.dhcp.domain.v.s); - if(config.dns.domain.t == CONF_STRING_ALLOCATED) - free(config.dns.domain.v.s); - config.dns.domain.v.s = strdup(config.dhcp.domain.v.s); - config.dns.domain.t = CONF_STRING_ALLOCATED; - } - } -} - bool writeFTLtoml(const bool verbose) { // Try to open a temporary config file for writing @@ -68,9 +49,6 @@ bool writeFTLtoml(const bool verbose) fputs(timestring, fp); fputs("\n\n", fp); - // Perform possible config migration - migrate_config(); - // Iterate over configuration and store it into the file char *last_path = (char*)""; for(unsigned int i = 0; i < CONFIG_ELEMENTS; i++) diff --git a/src/database/shell.c b/src/database/shell.c index 8b63b854..6704b7b1 100644 --- a/src/database/shell.c +++ b/src/database/shell.c @@ -896,8 +896,8 @@ static PerStreamTags * getDesignatedEmitStream(FILE *pf, unsigned chix, ** chix equals 1 or 2, or for an arbitrary stream when chix == 0. ** In either case, ppst references a caller-owned PerStreamTags ** struct which may be filled in if none of the known writable -** streams is being held by consoleInfo. The ppf parameter is an -** output when chix!=0 and an input when chix==0. +** streams is being held by consoleInfo. The ppf parameter is a +** byref output when chix!=0 and a byref input when chix==0. */ static PerStreamTags * getEmitStreamInfo(unsigned chix, PerStreamTags *ppst, @@ -910,7 +910,7 @@ getEmitStreamInfo(unsigned chix, PerStreamTags *ppst, ppstTry = &consoleInfo.pstSetup[chix]; pfEmit = ppst->pf; }else pfEmit = ppstTry->pf; - if( !isValidStreamInfo(ppst) ){ + if( !isValidStreamInfo(ppstTry) ){ pfEmit = (chix > 1)? stderr : stdout; ppstTry = ppst; streamOfConsole(pfEmit, ppstTry); diff --git a/src/database/sqlite3.c b/src/database/sqlite3.c index 592320ff..a28b3a7b 100644 --- a/src/database/sqlite3.c +++ b/src/database/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.44.1. By combining all the individual C code files into this +** version 3.44.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** d295f48e8f367b066b881780c98bdf980a1d. +** ebead0e7230cd33bcec9f95d2183069565b9. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.1" -#define SQLITE_VERSION_NUMBER 3044001 -#define SQLITE_SOURCE_ID "2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4" +#define SQLITE_VERSION "3.44.2" +#define SQLITE_VERSION_NUMBER 3044002 +#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -84183,10 +84183,11 @@ static int growOpArray(Vdbe *v, int nOp){ ** sqlite3CantopenError(lineno) */ static void test_addop_breakpoint(int pc, Op *pOp){ - static int n = 0; + static u64 n = 0; (void)pc; (void)pOp; n++; + if( n==LARGEST_UINT64 ) abort(); /* so that n is used, preventing a warning */ } #endif @@ -92330,11 +92331,12 @@ SQLITE_API int sqlite3_found_count = 0; ** sqlite3CantopenError(lineno) */ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ - static int n = 0; + static u64 n = 0; (void)pc; (void)pOp; (void)v; n++; + if( n==LARGEST_UINT64 ) abort(); /* So that n is used, preventing a warning */ } #endif @@ -143612,7 +143614,8 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( NameContext sNC; assert( pSelect!=0 ); - assert( (pSelect->selFlags & SF_Resolved)!=0 ); + testcase( (pSelect->selFlags & SF_Resolved)==0 ); + assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT ); assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); if( db->mallocFailed || IN_RENAME_OBJECT ) return; @@ -241504,18 +241507,24 @@ static void fts5DoSecureDelete( iOff = iStart; - /* Set variable bLastInDoclist to true if this entry happens to be - ** the last rowid in the doclist for its term. */ + /* If the position-list for the entry being removed flows over past + ** the end of this page, delete the portion of the position-list on the + ** next page and beyond. + ** + ** Set variable bLastInDoclist to true if this entry happens + ** to be the last rowid in the doclist for its term. */ + if( iNextOff>=iPgIdx ){ + int pgno = pSeg->iLeafPgno+1; + fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); + iNextOff = iPgIdx; + } + if( pSeg->bDel==0 ){ - if( iNextOff>=iPgIdx ){ - int pgno = pSeg->iLeafPgno+1; - fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); - iNextOff = iPgIdx; - }else{ + if( iNextOff!=iPgIdx ){ /* Loop through the page-footer. If iNextOff (offset of the ** entry following the one we are removing) is equal to the ** offset of a key on this page, then the entry is the last - ** in its doclist. */ + ** in its doclist. */ int iKeyOff = 0; for(iIdx=0; iIdx 1 && san[0] == '*'; + if(!is_wild) + return false; + + // The domain must be at least as long as the wildcard domain + const size_t domain_len = strlen(domain); + if(domain_len < san_len - 1) + return false; + + // Check if the domain ends with the wildcard domain + // Attention: The SAN is not NUL-terminated, so we need to + // use the length field + const char *wild_domain = domain + domain_len - san_len + 1; + return strncasecmp(wild_domain, san + 1, san_len) == 0; +} + // This function reads a X.509 certificate from a file and prints a // human-readable representation of the certificate to stdout. If a domain is // specified, we only check if this domain is present in the certificate. @@ -358,26 +378,55 @@ enum cert_check read_certificate(const char* certfile, const char *domain, const goto next_san; // Check if the SAN matches the domain + // Attention: The SAN is not NUL-terminated, so we need to + // use the length field if(strncasecmp(domain, (char*)san.san.unstructured_name.p, san.san.unstructured_name.len) == 0) { found = true; + // Free resources + mbedtls_x509_free_subject_alt_name(&san); + break; + } + + // Also check if the SAN is a wildcard domain and if the domain + // matches the wildcard + if(check_wildcard_domain(domain, (char*)san.san.unstructured_name.p, san.san.unstructured_name.len)) + { + found = true; + // Free resources + mbedtls_x509_free_subject_alt_name(&san); break; } next_san: + // Free resources + mbedtls_x509_free_subject_alt_name(&san); + // Go to next SAN sans = sans->next; } // Also check against the common name (CN) field char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE]; - if(mbedtls_x509_dn_gets(subject, sizeof(subject), &crt.subject) > 0) + const size_t subject_len = mbedtls_x509_dn_gets(subject, sizeof(subject), &crt.subject); + if(subject_len > 0) { - // Check subject == "CN=" - if(strlen(subject) > 3 && strncasecmp(subject, "CN=", 3) == 0 && strcasecmp(domain, subject + 3) == 0) - found = true; + // Check subjects prefixed with "CN=" + if(subject_len > 3 && strncasecmp(subject, "CN=", 3) == 0) + { + // Check subject + 3 to skip the prefix + if(strncasecmp(domain, subject + 3, subject_len - 3) == 0) + found = true; + // Also check if the subject is a wildcard domain + else if(check_wildcard_domain(domain, subject + 3, subject_len - 3)) + found = true; + } // Check subject == "" else if(strcasecmp(domain, subject) == 0) found = true; + // Also check if the subject is a wildcard domain and if the domain + // matches the wildcard + else if(check_wildcard_domain(domain, subject, subject_len)) + found = true; } diff --git a/test/pihole.toml b/test/pihole.toml index 3aaa217d..46909b67 100644 --- a/test/pihole.toml +++ b/test/pihole.toml @@ -370,7 +370,7 @@ # Domain used for the reverse server feature # # Possible values are: - # , typically set to the same value as dhcp.domain + # (e.g., "fritz.box") domain = "" [dhcp] @@ -396,15 +396,6 @@ # , e.g., "192.168.0.1" router = "" - # The DNS domain used by your Pi-hole (*** DEPRECATED ***) - # This setting is deprecated and will be removed in a future version. Please use - # dns.domain instead. Setting it to any non-default value will overwrite the value of - # dns.domain if it is still set to its default value. - # - # Possible values are: - # - domain = "lan" - # The netmask used by your Pi-hole. For directly connected networks (i.e., networks on # which the machine running Pi-hole has an interface) the netmask is optional and may # be set to "0.0.0.0": it will then be determined from the interface configuration @@ -694,7 +685,7 @@ # Example: [ "google.de", "pi-hole.net" ] # # Possible values are: - # array of IP addresses and/or hostnames + # array of domains excludeDomains = [] # How much history should be imported from the database [seconds]? (max 24*60*60 =