wireguard.lists.zx2c4.com archive mirror
 help / color / mirror / Atom feed
* Minimal WinTUN Program Access Denied Opening Tun
@ 2019-05-21 15:17 Christopher O'Connell
  2019-05-21 15:59 ` Christopher O'Connell
  0 siblings, 1 reply; 3+ messages in thread
From: Christopher O'Connell @ 2019-05-21 15:17 UTC (permalink / raw)
  To: wireguard


[-- Attachment #1.1: Type: text/plain, Size: 3958 bytes --]

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
<https://gist.github.com/jwriteclub/4f0fa081cb4eb39620702d7f7e212afd> 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

[-- Attachment #1.2: Type: text/html, Size: 6828 bytes --]

[-- Attachment #2: Type: text/plain, Size: 148 bytes --]

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-06-06 10:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-21 15:17 Minimal WinTUN Program Access Denied Opening Tun Christopher O'Connell
2019-05-21 15:59 ` Christopher O'Connell
2019-06-06 10:13   ` Jason A. Donenfeld

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).