tls_mgm: match SNI / SIP domain filters case-insensitively#3983
Open
kvwake wants to merge 1 commit into
Open
Conversation
SNI hostnames are DNS names, which compare case-insensitively (RFC 6066). Pass FNM_CASEFOLD to fnmatch() in tls_find_domain_by_filters().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make the matching of the TLS SNI (Server Name Indication) hostname against the configured
SIP DOMAIN FILTERScase-insensitive, as required by RFC 6066 for DNS hostnames.Details
This is a bug fix.
When
tls_mgmselects a server TLS domain based on the SNI hostname from the TLS ClientHello, it matches that hostname against the configuredmatch_sip_domainfilters intls_find_domain_by_filters()(
modules/tls_mgm/tls_domain.c). The match was done with:fnmatch()is case-sensitive unlessFNM_CASEFOLDis passed, and the SNI hostname is taken verbatim from the ClientHello (viaSSL_get_servername()intls_openssl, forwarded unchanged throughtls_sni_cb()), with nocase normalization on either side.
RFC 6066 §3 defines
server_nameas a DNS hostname, and DNS hostname comparison is case-insensitive (RFC 4343). The consequence of the current behavior is that a client presenting SNIExample.COMfails to match afilter configured as
example.com, making it effectively impossible to reliably match TLS certificates with SIP domain filters whenever the casing differs. This affects both thetls_opensslandtls_wolfsslbackends,since the matching code is shared in
tls_mgm.Solution
Pass
FNM_CASEFOLDto thefnmatch()call so the SNI hostname is matched case-insensitively. This matches the existing in-tree precedent in theidentity(identity.c:1877) andsipmsgops(sipmsgops.c:435) modules,which already use
FNM_CASEFOLDfor hostname/header matching.FNM_CASEFOLDis a GNU extension only exposed by glibc when_GNU_SOURCEis defined, so_GNU_SOURCEis defined at the top oftls_domain.cbefore any include (this is more correct thanidentity.c, which defines itafter
<fnmatch.h>). On BSD/macOS the flag is available by default.The
match_sip_domaindocumentation is updated to note the case-insensitive behavior.I deliberately left the config-load de-duplication comparison (
str_strcmpattls_domain.c:802) case-sensitive: making it case-insensitive would silently merge filter entries that look distinct in the configuration(e.g.
foo.comandFOO.com), which is a separate behavioral decision and not required to fix this bug.Verified by building the full tree (all modules except the un-vendored
tls_wolfsslsubmodule) under-Werrorwith gcc 13 on Ubuntu 24.04, and running the unit test suite — both pass. A standalone check confirmsfnmatch("example.com", "Example.COM", FNM_CASEFOLD)matches while the old flag0does not.Compatibility
No configuration migration is required. The change only makes matching more permissive (case-insensitive), so all filters that matched before continue to match; additionally, SNI hostnames that differ only in case now
match as intended. No API or database schema changes.
Closing issues
closes #3982