From patchwork Thu Sep 24 14:49:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1479 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.27.255.52]) by backend30.mail.ord1d.rsapps.net with LMTP id mDNKIfk+bV+CKQAAIUCqbw (envelope-from ) for ; Thu, 24 Sep 2020 20:51:05 -0400 Received: from proxy5.mail.iad3a.rsapps.net ([172.27.255.52]) by director8.mail.ord1d.rsapps.net with LMTP id WDoaIfk+bV8ceQAAfY0hYg (envelope-from ) for ; Thu, 24 Sep 2020 20:51:05 -0400 Received: from smtp20.gate.iad3a ([172.27.255.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy5.mail.iad3a.rsapps.net with LMTPS id QHjnGfk+bV9DOAAAhn5joQ (envelope-from ) for ; Thu, 24 Sep 2020 20:51:05 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp20.gate.iad3a.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=gmail.com; dmarc=fail (p=none; dis=none) header.from=gmail.com X-Suspicious-Flag: YES X-Classification-ID: 3087b844-fec9-11ea-98b0-525400aab2f3-1-1 Received: from [216.105.38.7] ([216.105.38.7:33372] helo=lists.sourceforge.net) by smtp20.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 5B/1D-31093-8FE3D6F5; Thu, 24 Sep 2020 20:51:05 -0400 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.90_1) (envelope-from ) id 1kLbvw-0007tr-Cx; Fri, 25 Sep 2020 00:49:56 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kLbvv-0007tk-2q for openvpn-devel@lists.sourceforge.net; Fri, 25 Sep 2020 00:49:55 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=MoSkZ4X4MByT3V51HwsJqUwxmakLt9arafnKIae1+gg=; b=WJsZOd8g5M3a+8PoUwdrsSPlKS IB91X/6+7gKW/D1gc9XByInPYNNxB2sDpOAYzjzZ8e+dzk5ZOzrLRhXejh48/jo/hRUPnN++fZOKJ RQGKWv7t/6qr2Adp1Dui+rYu0PsSG8aAEgLIu5mOqwzgHDqOX4J7Pe8Cc0mczubnHjI8=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version: Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=MoSkZ4X4MByT3V51HwsJqUwxmakLt9arafnKIae1+gg=; b=ErAd/GKKTCXyOaYE/gBiOwYV+1 neZNlY5tyC29WYydsZiIbkMHT9ABJAMfXWADcxezukAuxWntzwfRPXt71fDUNZ7saQHz/kROtJm10 Pxf1bY5Pp0VkAAvOLAm1Hxb2MYB3/0F+O8Jjai/rQfGuAxNNBKolHVi/HKsk07uktrCI=; Received: from mail-qt1-f179.google.com ([209.85.160.179]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.2) id 1kLbvm-0070b7-Eq for openvpn-devel@lists.sourceforge.net; Fri, 25 Sep 2020 00:49:54 +0000 Received: by mail-qt1-f179.google.com with SMTP id o21so148516qtp.2 for ; Thu, 24 Sep 2020 17:49:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=MoSkZ4X4MByT3V51HwsJqUwxmakLt9arafnKIae1+gg=; b=Pk9dmCtel3R4Z3NRJr4dVi35OgACBJPtbpQvkhjb4+HBfDrpovqsCjT3bKoTIHaCs+ viA8I2w9XBscNqr1mQNsLs7POS3jF0je1TspyFqK0F1htbF967YwLzvrsb09/T0DFTxK JCRv3ryHgZLs3AuLJIxhFKk/6X36+h713dGlA1C5c3YK3AZ6NoN5z6NwStqR0xsss9u9 9Tpyi3Sb+I1+1wCpDWhjToDGSA8Ly3hze+FCW0l835ufuxR2kMreD53lmrVe/ro1Zd84 0SqQ2kdU0DsMDR6xeDQS8Tdcym+5qD+KGIwsJiHCbDGPSIfVht2DxrDlFHsKvCLEkq15 YmsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=MoSkZ4X4MByT3V51HwsJqUwxmakLt9arafnKIae1+gg=; b=WxeLCsJJbyFc/pZYuMulnB7jz6KNErslzO+yyLgA+uE4vPQEWtG3shvIew3KcJuEVp zZeiZw2aqKiZ5XBx4Bhes+wdEf+SkpidGZjrAuuFOsm1MkqWVfFtWsTipvT7rmGWrVUN /7rrPD5/ZUfso3GL2bpzzBedP+cMzCJFI3Mz8jkdDKIHnAbt7hX5Y1kxM5V5oSeuLyAE KzmpldVYkZwxeOxZbOjsSxizzT0AN1c2fQvm9Knq2y8e7vDlKDofukLBnklxaqV/kjtV LeO5BSspqVrJE4DoZudz6GHeas5pw/7sUTbXJQ6lT6VNPQjCV+/svkhHo9/azpLZIwxM +dow== X-Gm-Message-State: AOAM530KfqMkHmDsNUpI0rfGN5Ou+dCMhGVIEEVuFl9jCJNfHmOO1eJZ YWJEBytBPKZ/nsrYhr/x94BEu6dZ93A= X-Google-Smtp-Source: ABdhPJzSNo1QUO1PzxFNUccYRL99bRoqnnPlPuEiZZqkFrOy2vcpW+p+p2OQmIC6qBo3zppsbIs+qg== X-Received: by 2002:ac8:6f24:: with SMTP id i4mr1907568qtv.329.1600994972916; Thu, 24 Sep 2020 17:49:32 -0700 (PDT) Received: from saturn.home.sansel.ca (CPE40167ea0e1c2-CM788df74daaa0.cpe.net.cable.rogers.com. [99.228.34.11]) by smtp.gmail.com with ESMTPSA id f64sm745790qkj.124.2020.09.24.17.49.32 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 Sep 2020 17:49:32 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Thu, 24 Sep 2020 20:49:29 -0400 Message-Id: <1600994969-7623-1-git-send-email-selva.nair@gmail.com> X-Mailer: git-send-email 2.1.4 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (selva.nair[at]gmail.com) -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.160.179 listed in list.dnswl.org] 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [209.85.160.179 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1kLbvm-0070b7-Eq Subject: [Openvpn-devel] [PATCH] Set DNS Domain using iservice 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: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Selva Nair Use wmic instead of directly editing the registry as the former does not take full effect unless the dns client service is restarted. Editing the registry appears to work erratically depending on whether its followed with a dchp renew or ipconfig /registerdns etc. DOMAIN-SEARCH is not handled here as wmic only supports setting the global search list which will over-ride all interface specific values. Editing the registry directly combined with a wmic command to reset the global SearchList is an option that could be considered in a separate patch. Trac # 1209, 1331 Signed-off-by: Selva Nair --- Note: this will set the domain twice if both v4 and v6 DNS servers are defined. It cant hurt, but could be avoided by making the domain setting a separate call from the DNS server setting. src/openvpn/tun.c | 21 +++++-- src/openvpnserv/interactive.c | 133 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 147 insertions(+), 7 deletions(-) diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 80ae695..b681905 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -159,7 +159,7 @@ do_dns_service(bool add, const short family, const struct tuntap *tt) int addr_len = add ? len : 0; const char *ip_proto_name = family == AF_INET6 ? "IPv6" : "IPv4"; - if (addr_len == 0 && add) /* no addresses to add */ + if (addr_len == 0 && !tt->options.domain && add) /* no addresses or domain to add */ { return true; } @@ -199,9 +199,21 @@ do_dns_service(bool add, const short family, const struct tuntap *tt) dns.addr[i].ipv4.s_addr = htonl(tt->options.dns[i]); } } + if (tt->options.domain) + { + strncpy(dns.domains, tt->options.domain, _countof(dns.domains)); + /* truncation of domain name is not checked as it cant happen + * with 512 bytes room in dns.domains. + */ + msg(D_LOW, "%s dns domain on '%s' (if_index = %d) using service", + (add ? "Setting" : "Deleting"), dns.iface.name, dns.iface.index); + } - msg(D_LOW, "%s %s dns servers on '%s' (if_index = %d) using service", - (add ? "Setting" : "Deleting"), ip_proto_name, dns.iface.name, dns.iface.index); + if (addr_len > 0 || !add) + { + msg(D_LOW, "%s %s dns servers on '%s' (if_index = %d) using service", + (add ? "Setting" : "Deleting"), ip_proto_name, dns.iface.name, dns.iface.index); + } if (!send_msg_iservice(pipe, &dns, sizeof(dns), &ack, "TUN")) { @@ -216,7 +228,8 @@ do_dns_service(bool add, const short family, const struct tuntap *tt) goto out; } - msg(M_INFO, "%s dns servers %s using service", ip_proto_name, (add ? "set" : "deleted")); + msg(M_INFO, "%s dns servers %s%s using service", ip_proto_name, + (tt->options.domain? "and domain " : ""), (add ? "set" : "deleted")); ret = true; out: diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c index 207cc4a..b7f144d 100644 --- a/src/openvpnserv/interactive.c +++ b/src/openvpnserv/interactive.c @@ -91,6 +91,7 @@ typedef enum { block_dns, undo_dns4, undo_dns6, + undo_domain, _undo_type_max } undo_type_t; typedef list_item_t *undo_lists_t[_undo_type_max]; @@ -564,6 +565,24 @@ InterfaceLuid(const char *iface_name, PNET_LUID luid) return status; } +static DWORD +ConvertInterfaceNameToIndex(const wchar_t *ifname, NET_IFINDEX *index) +{ + NET_LUID luid; + DWORD err; + + err = ConvertInterfaceAliasToLuid(ifname, &luid); + if (err == ERROR_SUCCESS) + { + err = ConvertInterfaceLuidToIndex(&luid, index); + } + if (err != ERROR_SUCCESS) + { + MsgToEventLog(M_ERR, L"Failed to find interface index for <%s>", ifname); + } + return err; +} + static BOOL CmpAddress(LPVOID item, LPVOID address) { @@ -1057,6 +1076,53 @@ out: return err; } +/** + * Run command: wmic nicconfig (InterfaceIndex=$if_index) call $action ($data) + * @param if_index "index of interface" + * @param action e.g., "SetDNSDomain" + * @param data data if required for action + * - a single word for SetDNSDomain, empty or NULL to delete + * - comma separated values for a list + */ +static DWORD +wmic_nicconfig_cmd(const wchar_t *action, const NET_IFINDEX if_index, + const wchar_t *data) +{ + DWORD err = 0; + wchar_t argv0[MAX_PATH]; + wchar_t *cmdline = NULL; + int timeout = 10000; /* in msec */ + + swprintf(argv0, _countof(argv0), L"%s\\%s", get_win_sys_path(), L"wbem\\wmic.exe"); + argv0[_countof(argv0) - 1] = L'\0'; + + const wchar_t *fmt; + /* comma separated list must be enclosed in parenthesis */ + if (data && wcschr(data, L',')) + { + fmt = L"wmic nicconfig where (InterfaceIndex=%ld) call %s (%s)"; + } + else + { + fmt = L"wmic nicconfig where (InterfaceIndex=%ld) call %s %s"; + } + + size_t ncmdline = wcslen(fmt) + 20 + wcslen(action) /* max 20 for ifindex */ + + (data ? wcslen(data) + 1 : 1); + cmdline = malloc(ncmdline*sizeof(wchar_t)); + if (!cmdline) + { + return ERROR_OUTOFMEMORY; + } + + openvpn_sntprintf(cmdline, ncmdline, fmt, if_index, action, + data? data : L""); + err = ExecCommand(argv0, cmdline, timeout); + + free(cmdline); + return err; +} + /* Delete all IPv4 or IPv6 dns servers for an interface */ static DWORD DeleteDNS(short family, wchar_t *if_name) @@ -1079,6 +1145,54 @@ CmpWString(LPVOID item, LPVOID str) return (wcscmp(item, str) == 0) ? TRUE : FALSE; } +/** + * Set interface specific DNS domain suffix + * @param if_name name of the the interface + * @param domain a single domain name + * @param lists pointer to the undo lists. If NULL + * undo lists are not altered. + * Will delete the currently set value if domain is empty. + */ +static DWORD +SetDNSDomain(const wchar_t *if_name, const char *domain, undo_lists_t *lists) +{ + NET_IFINDEX if_index; + + DWORD err = ConvertInterfaceNameToIndex(if_name, &if_index); + if (err != ERROR_SUCCESS) + { + return err; + } + + wchar_t *wdomain = utf8to16(domain); /* utf8 to wide-char */ + if (!wdomain) + { + return ERROR_OUTOFMEMORY; + } + + /* free undo list if previously set */ + if (lists) + { + free(RemoveListItem(&(*lists)[undo_domain], CmpWString, (void *)if_name)); + } + + err = wmic_nicconfig_cmd(L"SetDNSDomain", if_index, wdomain); + + /* Add to undo list if domain is non-empty */ + if (err == 0 && wdomain[0] && lists) + { + wchar_t *tmp_name = wcsdup(if_name); + if (!tmp_name || AddListItem(&(*lists)[undo_domain], tmp_name)) + { + free(tmp_name); + err = ERROR_OUTOFMEMORY; + } + } + + free(wdomain); + return err; +} + static DWORD HandleDNSConfigMessage(const dns_cfg_message_t *msg, undo_lists_t *lists) { @@ -1117,9 +1231,14 @@ HandleDNSConfigMessage(const dns_cfg_message_t *msg, undo_lists_t *lists) free(RemoveListItem(&(*lists)[undo_type], CmpWString, wide_name)); } - if (msg->header.type == msg_del_dns_cfg) /* job done */ + if (msg->header.type == msg_del_dns_cfg) { - goto out; + if (msg->domains[0]) + { + /* setting an empty domain removes any previous value */ + err = SetDNSDomain(wide_name, "", lists); + } + goto out; /* job done */ } for (int i = 0; i < addr_len; ++i) @@ -1142,6 +1261,8 @@ HandleDNSConfigMessage(const dns_cfg_message_t *msg, undo_lists_t *lists) */ } + err = 0; + if (msg->addr_len > 0) { wchar_t *tmp_name = wcsdup(wide_name); @@ -1154,7 +1275,9 @@ HandleDNSConfigMessage(const dns_cfg_message_t *msg, undo_lists_t *lists) } } - err = 0; + if (msg->domains[0]) { + err = SetDNSDomain(wide_name, msg->domains, lists); + } out: free(wide_name); @@ -1445,6 +1568,10 @@ Undo(undo_lists_t *lists) DeleteDNS(AF_INET6, item->data); break; + case undo_domain: + SetDNSDomain(item->data, "", NULL); + break; + case block_dns: interface_data = (block_dns_data_t *)(item->data); delete_block_dns_filters(interface_data->engine);