From patchwork Tue May 20 10:51:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4263 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:a599:b0:662:a395:de2b with SMTP id hj25csp361988mab; Tue, 20 May 2025 03:51:40 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUWE8VEA2n9IWZJa3RmGZHo88VUF7rkdyjUyF9WT2gbv22q8XS0GFaK+9mBNcdDD+ZFhkS/QQLVjpg=@openvpn.net X-Google-Smtp-Source: AGHT+IHIUPV2/dnmHlHmL9s9taewPtn2vN+xY4CyvIWD6j/kcna8IDiLwc0jt1KDEpFO1b96OoOA X-Received: by 2002:a05:6602:3891:b0:85b:538e:1faf with SMTP id ca18e2360f4ac-86a231c01b0mr2443811139f.7.1747738300477; Tue, 20 May 2025 03:51:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1747738300; cv=none; d=google.com; s=arc-20240605; b=Y2OG6pQCap3EjPmmnad2aIIzz5nQ2or+81TgCSSlK5JYIkEOM9Ba7UdwVTxvELU0oF WPLo+x8qnGcRO2qMW/Acw8q96pMgROJGYFfbZgUOoVVqYvKZPWaolvvDepSQMZObmZ0J XP5XL9Yw8u+LYkEQyMj8WewG5mb3iwLEk3amWc8PTMWhHo+zqEwnMBQgxccjrA+O9Lnx 9GQZJPzb7XAynRmbggcKvk5Vfv2aPYbZazLApUVNAKQalpQEQWeBJUOPbo/fNVOomv7O h7wkGjECd/Y2nDTGXgrekpbw+wxp2QD6SLvHzYil9Xh+ht5af/+UwjtIeWdbDYawClg+ h2WQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=tTMeCkO9TOf7xBd7v48ZRb70WlYP7L+V93mtedoKsYc=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=S5m2aPym1uyIrr8iII/4DxeFXYOmci3Z7rUVr5jP0+7bXfcQMn4RKToNMzMlTSNIbt LyYsBktVkaPwcLehgZgHL757pmn02OnNzrF/Nf/+FnOhBFMGITGNgy2qY6/59qd4RwiL 3fjFfSXbkETBsoM/oHZeUl7iTNWGY7jUZXZpxjS/6g2DtcMYSG4MBnBnpBZK1VYv+CWh 29BxirBOSwn+w/mpVErr9pv25g3bdxUaJGPyC2TbdlXfUXquFuKS9+nB/CYkbhbj0PzN ogxJFcq3jh//gyuJp40EogOh3uYvnPjUJHwkv47SIq9Kcmiy0abEfuMhX5morL8U5qBK bIGA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=J+GTSZbC; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=duMHeAxq; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Xbvx7y7C; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 8926c6da1cb9f-4fbcc4ec9eesi6062879173.153.2025.05.20.03.51.40 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 May 2025 03:51:40 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=J+GTSZbC; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=duMHeAxq; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Xbvx7y7C; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=tTMeCkO9TOf7xBd7v48ZRb70WlYP7L+V93mtedoKsYc=; b=J+GTSZbCwIlG39gS77REGAIMB0 ZcXaXpo9Ag9p8Co2OFrExU/b8AzJFKBHhrbzEbD3GBo4JZwgsrMwg3qYQIjqOovAv3cmcr3O/hwke LnsN0EBZQ2xDZIUSkIi/ZsFPya0NGy0FWCrmP3L+xbstYIEZZbzLvg5TmJoa7vxAyRWw=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1uHKZM-0001sQ-Gk; Tue, 20 May 2025 10:51:36 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1uHKZK-0001sJ-Ju for openvpn-devel@lists.sourceforge.net; Tue, 20 May 2025 10:51:34 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=KsFcnHItz+3liI+y/sdd26xV1lMvTDgfCRZdjN/6rPo=; b=duMHeAxq8SPDaMzmyo+YYGSloS rdc7hwphhn5s593CKGlmvAZjfeaVeRJpikUtLjeANjW15JdJN2EV+b+xmLyRm/SHn03nIr/e/qLIp O971HXA9DTAJNRUzAN90PER1rMfX6t1GOXqTNUi1noyvunW79KkgvuqGluvT7oA4T5AQ=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=KsFcnHItz+3liI+y/sdd26xV1lMvTDgfCRZdjN/6rPo=; b=Xbvx7y7CFYI1df/acpHnkIBmVQ xacZ1m4AFl4k4IkTX5mmqWCx3/MH7uHHJPCY+tDA/EXreY+58sq+xFwTjFLZzM4q4MQL3fV0rntFZ Q8crKBGd59K3XTt4gaiLR3NWgUh/w86YHYNjh6cYIqjCx0QqpmBGG0Ajhiabj4yS2deI=; Received: from [193.149.48.143] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1uHKZI-0008FT-9H for openvpn-devel@lists.sourceforge.net; Tue, 20 May 2025 10:51:34 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.17.1.9/8.17.1.9) with ESMTP id 54KApKcS010451 for ; Tue, 20 May 2025 12:51:20 +0200 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 54KApKYr010450 for openvpn-devel@lists.sourceforge.net; Tue, 20 May 2025 12:51:20 +0200 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Tue, 20 May 2025 12:51:12 +0200 Message-ID: <20250520105119.10431-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.7 (+) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Heiko Hund Compare local domains for exclude rules to search domains and skip matching ones. This prevents the creation of exclude rules when the server indicates that the domain should be resolved via the VPN, [...] Content analysis details: (1.7 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: openvpn.net] 0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [193.149.48.143 listed in sa-accredit.habeas.com] 0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [193.149.48.143 listed in bl.score.senderscore.com] 0.4 NO_DNS_FOR_FROM DNS: Envelope sender has no MX or A DNS records 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_FAIL SPF: HELO does not match SPF record (fail) [SPF failed: Rejected by SPF record] 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1uHKZI-0008FT-9H Subject: [Openvpn-devel] [PATCH v20] win: match search domains when creating exclude rules X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1832636436481381577?= X-GMAIL-MSGID: =?utf-8?q?1832636436481381577?= From: Heiko Hund Compare local domains for exclude rules to search domains and skip matching ones. This prevents the creation of exclude rules when the server indicates that the domain should be resolved via the VPN, by pushing the search domain. Change-Id: I4919af2b845a47787c08f454b108ef376ea5c0f6 Signed-off-by: Heiko Hund Acked-by: Lev Stipakov --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/905 This mail reflects revision 20 of this Change. Acked-by according to Gerrit (reflected above): Lev Stipakov diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c index 5f842bd..a1581a6 100644 --- a/src/openvpnserv/interactive.c +++ b/src/openvpnserv/interactive.c @@ -2126,18 +2126,52 @@ } /** + * Check if a domain is contained in a comma separated list of domains + * + * @param list Comma separated list of domains + * @param domain Domain string to search for + * @param len Length of the domain string, excluding the '\0' + * + * @return TRUE when the domain was found in the list, FALSE otherwise. + */ +static BOOL +ListContainsDomain(PCWSTR list, PCWSTR domain, size_t len) +{ + PCWSTR match = list; + while (TRUE) + { + match = wcsstr(match, domain); + if (!match) + { + /* Domain has not matched */ + break; + } + if ((match == list || *(match - 1) == ',') + && (*(match + len) == ',' || *(match + len) == '\0')) + { + /* Domain has matched fully */ + return TRUE; + } + match += len; + } + return FALSE; +} + +/** * Return interface specific domain suffix(es) * * The \p domains paramter will be set to a MULTI_SZ domains string. * In case of an error or if no domains are found for the interface * \p size is set to 0 and the contents of \p domains are invalid. * Note that the domains could have been set by DHCP or manually. + * Note that domains are ignored if they match a pushed search domain. * - * @param itf HKEY of the interface to read from - * @param domains PWSTR buffer to return the domain(s) in - * @param size pointer to size of the domains buffer in bytes. Will be - * set to the size of the string returned, including - * the terminating zeros or 0. + * @param itf HKEY of the interface to read from + * @param search_domains optional list of search domains + * @param domains PWSTR buffer to return the domain(s) in + * @param size pointer to size of the domains buffer in bytes. Will be + * set to the size of the string returned, including + * the terminating zeros or 0. * * @return LSTATUS NO_ERROR if the domain suffix(es) were read successfully, * ERROR_FILE_NOT_FOUND if no domain was found for the interface, @@ -2145,7 +2179,7 @@ * any other error indicates an error while reading from the registry. */ static LSTATUS -GetItfDnsDomains(HKEY itf, PWSTR domains, PDWORD size) +GetItfDnsDomains(HKEY itf, PCWSTR search_domains, PWSTR domains, PDWORD size) { if (domains == NULL || size == 0) { @@ -2179,9 +2213,27 @@ *comma = '\0'; } + /* Ignore itf domains which match a pushed search domain */ + size_t domain_len = wcslen(pos); + if (ListContainsDomain(search_domains, pos, domain_len)) + { + if (comma) + { + pos = comma + 1; + continue; + } + else + { + /* This was the last domain */ + *pos = '\0'; + *size += 1; + return wcslen(domains) ? NO_ERROR : ERROR_FILE_NOT_FOUND; + } + } + /* Check for enough space to convert this domain */ + domain_len += 1; /* leading dot */ size_t converted_size = pos - domains; - size_t domain_len = wcslen(pos) + 1; size_t domain_size = domain_len * one_glyph; size_t extra_size = 2 * one_glyph; if (converted_size + domain_size + extra_size > buf_size) @@ -2265,11 +2317,12 @@ * needed so that local DNS keeps working even when a catch all NRPT rule is * installed by a VPN connection. * - * @param data pointer to the data structures the values are returned in - * @param data_size number of exclude data structures pointed to + * @param search_domains optional list of search domains + * @param data pointer to the data structures the values are returned in + * @param data_size number of exclude data structures pointed to */ static void -GetNrptExcludeData(nrpt_exclude_data_t *data, size_t data_size) +GetNrptExcludeData(PCWSTR search_domains, nrpt_exclude_data_t *data, size_t data_size) { HKEY v4_itfs = INVALID_HANDLE_VALUE; HKEY v6_itfs = INVALID_HANDLE_VALUE; @@ -2313,7 +2366,7 @@ /* Get the DNS domain(s) for exclude routing */ data[i].domains_size = sizeof(data[0].domains); memset(data[i].domains, 0, data[i].domains_size); - err = GetItfDnsDomains(v4_itf, data[i].domains, &data[i].domains_size); + err = GetItfDnsDomains(v4_itf, search_domains, data[i].domains, &data[i].domains_size); if (err) { if (err != ERROR_FILE_NOT_FOUND) @@ -2471,15 +2524,16 @@ * local resolution of names is not interfered with in case the VPN resolves * all names. * - * @param nrpt_key the registry key to set the rules under - * @param ovpn_pid the PID of the openvpn process + * @param nrpt_key the registry key to set the rules under + * @param ovpn_pid the PID of the openvpn process + * @param search_domains optional list of search domains */ static void -SetNrptExcludeRules(HKEY nrpt_key, DWORD ovpn_pid) +SetNrptExcludeRules(HKEY nrpt_key, DWORD ovpn_pid, PCWSTR search_domains) { nrpt_exclude_data_t data[8]; /* data from up to 8 interfaces */ memset(data, 0, sizeof(data)); - GetNrptExcludeData(data, _countof(data)); + GetNrptExcludeData(search_domains, data, _countof(data)); unsigned n = 0; for (int i = 0; i < _countof(data); ++i) @@ -2504,17 +2558,18 @@ /** * Set NRPT rules for a openvpn process * - * @param nrpt_key the registry key to set the rules under - * @param addresses name server addresses - * @param domains optional list of split routing domains - * @param dnssec boolean whether DNSSEC is to be used - * @param ovpn_pid the PID of the openvpn process + * @param nrpt_key the registry key to set the rules under + * @param addresses name server addresses + * @param domains optional list of split routing domains + * @param search_domains optional list of search domains + * @param dnssec boolean whether DNSSEC is to be used + * @param ovpn_pid the PID of the openvpn process * * @return NO_ERROR on success, or a Windows error code */ static DWORD -SetNrptRules(HKEY nrpt_key, const nrpt_address_t *addresses, - const char *domains, BOOL dnssec, DWORD ovpn_pid) +SetNrptRules(HKEY nrpt_key, const nrpt_address_t *addresses, const char *domains, + const char *search_domains, BOOL dnssec, DWORD ovpn_pid) { DWORD err = NO_ERROR; PWSTR wide_domains = L".\0"; /* DNS route everything by default */ @@ -2543,7 +2598,14 @@ } else { - SetNrptExcludeRules(nrpt_key, ovpn_pid); + PWSTR wide_search_domains; + wide_search_domains = utf8to16(search_domains); + if (!wide_search_domains) + { + return ERROR_OUTOFMEMORY; + } + SetNrptExcludeRules(nrpt_key, ovpn_pid, wide_search_domains); + free(wide_search_domains); } /* Create address string list */ @@ -2803,7 +2865,7 @@ /* Set NRPT rules */ BOOL dnssec = (msg->flags & nrpt_dnssec) != 0; - err = SetNrptRules(key, msg->addresses, msg->resolve_domains, dnssec, ovpn_pid); + err = SetNrptRules(key, msg->addresses, msg->resolve_domains, msg->search_domains, dnssec, ovpn_pid); if (err) { goto out;