From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.8 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8EABC04AB5 for ; Thu, 6 Jun 2019 09:34:05 +0000 (UTC) Received: from krantz.zx2c4.com (krantz.zx2c4.com [192.95.5.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6D05D20868 for ; Thu, 6 Jun 2019 09:34:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IVvK4Z/S" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6D05D20868 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=wireguard-bounces@lists.zx2c4.com Received: from krantz.zx2c4.com (localhost [IPv6:::1]) by krantz.zx2c4.com (ZX2C4 Mail Server) with ESMTP id 73fa1b69; Thu, 6 Jun 2019 09:33:23 +0000 (UTC) Received: from krantz.zx2c4.com (localhost [127.0.0.1]) by krantz.zx2c4.com (ZX2C4 Mail Server) with ESMTP id 8d20d35b for ; Tue, 21 May 2019 15:59:24 +0000 (UTC) Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by krantz.zx2c4.com (ZX2C4 Mail Server) with ESMTP id 9996cfba for ; Tue, 21 May 2019 15:59:24 +0000 (UTC) Received: by mail-wm1-x32a.google.com with SMTP id j187so3448778wmj.1 for ; Tue, 21 May 2019 08:59:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=loBY+65DQxndglm8gyxH6rWA3EqL+TkoC6jWtkoNP/o=; b=IVvK4Z/SUC2a/FMrHfdh5jTed+j86SD738ir6J55Ka1yDyfFbLibKbveOwTXtKKQ4X KaCEnsfleQJvY/s2BIhYTn/LoeikRRcXAMssYkc5PV7TZn6eKOz1xRuLCIm3SzniARsp oTPtT7ymsWMQbmwpJ8MAPYrgIDuJ5pkCNOlThlu7bv0ZjCbn+Pj2Hfzw89/aCeDjz0PU /EB/4+NKNScp/2lY1xU4j9yFUxS8cZ54BHKJI2Yy8IQBKApWlv1OevEUrD2CCxoMPRjD QkNHYpjLyeGC3WZbNtD7FZHKZqj0KpGJMkq0WEnI6J70NT0NWQM/IBekHao8p8rZzqjk adRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=loBY+65DQxndglm8gyxH6rWA3EqL+TkoC6jWtkoNP/o=; b=mZ9fX96X+/IEdZbEm6Sbu7Kv8lRODOMqb2oJewZa7ITHaPjbA76Nfn0ofMMneelZjm aSivGqHSWSxDaZDwjrRX6eEJQlPthwcMORZUY615aWR/yVCygDlO0BasxOJexLAa1RV7 IshB5uFLf/OkRv5vgWTQQP4tWribMbQI1yKZQqyZF7U7SvIbaIebChA+YYbbfKGlFeSJ zHz2F0u4+Ddr6S2A+AF5wupiBuWkFsn2mScrk3UcZbcuwAIr/jqB85BeWO1WPQ2Y2HqC 75xs4bKh8CuROhNypJr5xqM9xF0dVg2HnlWjm/xQq5h+FMWokqF2PafWIvBeaEStBZf2 TRLw== X-Gm-Message-State: APjAAAWHDhBG4ry/VCIdB/uRQDfu2VpwWkYtNYej0qaYqM/S3Fp/6by3 X0ueGyGzm0qoJvb9SDJTtxPQ50PGk9F4xiPayUwidW1A X-Google-Smtp-Source: APXvYqwyC8AROhfywkvcjX+AZ2gKUnCMel0CBipUgSSymdocQmCGoKKiJcsc5+qMlsuf+nNxyx+und+7dZ8ubnKwrtk= X-Received: by 2002:a05:600c:10ca:: with SMTP id l10mr4195270wmd.23.1558454363118; Tue, 21 May 2019 08:59:23 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: "Christopher O'Connell" Date: Tue, 21 May 2019 18:59:07 +0300 Message-ID: Subject: Re: Minimal WinTUN Program Access Denied Opening Tun To: wireguard@lists.zx2c4.com X-Mailman-Approved-At: Thu, 06 Jun 2019 11:33:21 +0200 X-BeenThere: wireguard@lists.zx2c4.com X-Mailman-Version: 2.1.15 Precedence: list List-Id: Development discussion of WireGuard List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: multipart/mixed; boundary="===============8202047976691300542==" Errors-To: wireguard-bounces@lists.zx2c4.com Sender: "WireGuard" --===============8202047976691300542== Content-Type: multipart/alternative; boundary="000000000000b6613e058967eef6" --000000000000b6613e058967eef6 Content-Type: text/plain; charset="UTF-8" So I must have messed up my service installer and wasn't really running as the LocalSystem, because with some tweaking it does open now. I further confirmed this using the PSExec64 utility and calling the basic code to run as the system user and it runs correctly. So it seems that the WinTUN device does restrict itself to being opened as the system user. It might be good to add such a note to the documentation for WinTUN (I'm happy to make an edit and push a patch if others would like that). I'm also interested in the rationale for requiring the system user to open the device? All the best, ~ Christopher On Tue, May 21, 2019 at 6:17 PM Christopher O'Connell wrote: > Hello, > > I've been very intrigued by WinTUN, and the option of a small, simple TUN > driver, especially one with good golang bindings offers a lot of > opportunity to build interesting things on Windows. > > I've been building a minimal program based on the go libraries, my goal > being to just write a simple ICMP endpoint to be able to ping, as a way to > learn the WinTUN code and libraries. Unfortunately, I've run into an issue > that I'm unable to actually read from the tun device, my code always > getting errors like open \\.\Global\WINTUN32768: Access is denied. > > In a nutshell, my code does the following (error checking and some other > ancillary code is omitted, please see this gist > for > the complete code): > > func main() { > // These two functions are taken from wireguard windows, added just to > make sure that > // this code is running from the same privilege level as the WireGuard > windows code > checkForAdminGroup() > checkForWow64() > // Create a tun. This works, with the small patch to tun_windows.go > which I submitted earlier > t, err := tun.CreateTun("My Test Tun") > nt := t.(*tun.NativeTun) > // Get the interface and set IPs, etc > iface, err := winipccfg.InterfaceFromLUID(nt.LUID()) > iface.SetAddresses("172.16.16.1/24")// Omitting all the mangly code > to create an IPNet > // Listen for Reads > wg := &sync.WaitGroup{} > wg.Add(1) > go func() { > defer wg.Done() > for { > bt := make([]byte, 15000) // Lots of packets > read, err := nt.Read(bt, 0) // Offset of 0 for now, just > trying to read > if err != nil { > fmt.Printf("%#v\n", err) > return > } > fmt.Printf("Read %d bytes\n", read) > } > }() > wg.Wait() > } > > I've tried this using two different versions of the WinTUN driver, one > where I just created a simple installer using the v0.1 MSM file on > WinTun.net, and the other by installing WireGuard v0.0.8 from the main > website. In both cases, CreateTun and interface calls work, and I'm able > to see the network adapter added to Windows. However, in both cases, the > call to Read fails. Ultimately, after drilling down, the failing call is > in tun_windows.go in func (tun *NativeTun) openTUN, and the offending > line is tun.tunFileRead, err = os.OpenFile(name, os.O_RDONLY, 0). > > To test out my code, and see if I am missing some key component, I > compiled and ran golang.zx2c4.com/wireguard/main_windows.go, which > exhibits the exact same behavior as my program, ending with an error like ERROR: > (MyTunTest) 2019/05/21 18:14:17 Failed to read packet from TUN device: open > \\.\Global\WINTUN32769: Access is denied. > > At this point I was convinced that it might be some factor about my system > which was preventing this from working, but much to my surprise when I > downloaded and ran the current v0.0.8 release version of the WireGuard > client, it worked just fine, and I was able to connect to and route traffic > through a WireGuard server. > > I then considered that there was something special about opening the tun > device from a service specifically, as opposed to an elevated user space > process (although I cannot figure out a reason why this should be so). I > whipped up a very quick windows service in C# to only tries to open the > already created WinTUN device (literally, just var tunRead = > File.Open(TUN_NAME, FileMode.Open, FileAccess.Read);, plus all the usual > service boiler plate). I installed this service with the LocalSystem > permission and when starting, it similarly gets an access denied error. > > Clearly, the WireGuard windows client is executing some command which puts > the tun into an ready to open state or changes the privileges in some key > way, but I have been unable to find this key command or function. Any help > on a minimum viable program to successfully call Read on a WinTUN object is > most appreciated. > > All the best, > > ~ Christopher > --000000000000b6613e058967eef6 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
So I must have messed up my service installer and was= n't really running as the LocalSystem, because with some tweaking it do= es open now. I further confirmed this using the PSExec64 utility and callin= g the basic code to run as the system user and it runs correctly.

So it seems that the WinTUN device does restrict itself to = being opened as the system user. It might be good to add such a note to the= documentation for WinTUN (I'm happy to make an edit and push a patch i= f others would like that).

I'm also interested= in the rationale for requiring the system user to open the device?

All the best,

~ Christopher
<= /div>

On Tue, May 21, 2019 at 6:17 PM Christopher O'Connell <jwriteclub@gmail.com> wrote:
= Hello,

I've been very intrigued by WinTUN, and= the option of a small, simple TUN driver, especially one with good golang = bindings offers a lot of opportunity to build interesting things on Windows= .

I've been building a minimal program based o= n the go libraries, my goal being to just write a simple ICMP endpoint to b= e able to ping, as a way to learn the WinTUN code and libraries. Unfortunat= ely, I've run into an issue that I'm unable to actually read from t= he tun device, my code always getting errors like open \\.\Global\WINTUN32768: Access is denied.

In a nutshell, my code does the following (err= or checking and some other ancillary code is omitted, please see this gist for the complete code):

func main() {
=C2=A0=C2=A0=C2=A0= // These two functions are taken from wireguard windows, added just to mak= e sure that
=C2=A0=C2=A0=C2=A0 // this code is running from the same privilege leve= l as the WireGuard windows code
=C2=A0=C2=A0=C2=A0 checkForAdminGroup()<= /div>
=C2=A0=C2=A0=C2= =A0 checkForWow64()
=C2=A0=C2=A0=C2=A0 // Create a tun. This works, with the small = patch to tun_windows.go which I submitted earlier
=C2=A0=C2=A0=C2=A0 t, err := =3D tun.CreateTun("My Test Tun")
=C2=A0=C2=A0=C2=A0 nt :=3D t.(*tun.Nativ= eTun)
=C2=A0=C2=A0=C2=A0 i= face, err :=3D winipccfg.InterfaceFromLUID(nt.LUID())
=C2=A0=C2=A0=C2=A0 iface.SetA= ddresses("172.16.1= 6.1/24")// Omitting all the mangly code to create an IPNet<= /div>
=C2=A0=C2=A0=C2= =A0 // Listen for Reads
=C2=A0=C2=A0=C2=A0 wg :=3D &sync.WaitGroup{}=
=C2=A0=C2=A0= =C2=A0 wg.Add(1)
=C2=A0=C2=A0=C2=A0 go func() {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 = defer wg.Done()
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for {
<= span style=3D"font-family:courier new,monospace">=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bt :=3D make([]byte, 15000) // L= ots of packets
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 r= ead, err :=3D nt.Read(bt, 0) // Offset of 0 for now, just trying to read
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if err !=3D nil {=
=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 fmt.Printf("%#v\n", err)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return
=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 fmt.Printf("Read %d bytes\n&qu= ot;, read)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0 }()
=C2=A0=C2=A0= =C2=A0 wg.Wait()
}

I've tried this using tw= o different versions of the WinTUN driver, one where I just created a simpl= e installer using the v0.1 MSM file on WinTun.net, and the other by install= ing WireGuard v0.0.8 from the main website. In both cases, CreateTun and interface calls work= , and I'm able to see the network adapter added to Windows. However, in= both cases, the call to = Read fails. Ultimately, after drilling down, the failing call is in = tun_windows.go in func (t= un *NativeTun) openTUN, and the offending line is tun.tunFileRead, err =3D os.OpenFile(name, = os.O_RDONLY, 0).

To test out my code, and s= ee if I am missing some key component, I compiled and ran golang.zx2c4= .com/wireguard/main_windows.go, which exhibits the exact same behavior = as my program, ending with an error like ERROR: (MyTunTest) 2019/05/21 18:14:17 Failed to read packe= t from TUN device: open \\.\Global\WINTUN32769: Access is denied.

At this point I was convinced that it might be some = factor about my system which was preventing this from working, but much to = my surprise when I downloaded and ran the current v0.0.8 release version of= the WireGuard client, it worked just fine, and I was able to connect to an= d route traffic through a WireGuard server.

I = then considered that there was something special about opening the tun devi= ce from a service specifically, as opposed to an elevated user space proces= s (although I cannot figure out a reason why this should be so). I whipped = up a very quick windows service in C# to only tries to open the already cre= ated WinTUN device (literally, just var tunRead =3D File.Open(TUN_NAME, FileMode.Open, FileAccess.Re= ad);, plus all the usual service boiler plate). I installed this ser= vice with the LocalSystem permission and when starting, it similarly gets a= n access denied error.

Clearly, the WireGuard wind= ows client is executing some command which puts the tun into an ready to op= en state or changes the privileges in some key way, but I have been unable = to find this key command or function. Any help on a minimum viable program = to successfully call Read on a WinTUN object is most appreciated.

All the best,

~ Christopher
--000000000000b6613e058967eef6-- --===============8202047976691300542== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard --===============8202047976691300542==--