uapi_windows.go raw
1 /* SPDX-License-Identifier: MIT
2 *
3 * Copyright (C) 2017-2025 WireGuard LLC. All Rights Reserved.
4 */
5
6 package ipc
7
8 import (
9 "net"
10
11 "golang.org/x/sys/windows"
12 "golang.zx2c4.com/wireguard/ipc/namedpipe"
13 )
14
15 // TODO: replace these with actual standard windows error numbers from the win package
16 const (
17 IpcErrorIO = -int64(5)
18 IpcErrorProtocol = -int64(71)
19 IpcErrorInvalid = -int64(22)
20 IpcErrorPortInUse = -int64(98)
21 IpcErrorUnknown = -int64(55)
22 )
23
24 type UAPIListener struct {
25 listener net.Listener // unix socket listener
26 connNew chan net.Conn
27 connErr chan error
28 kqueueFd int
29 keventFd int
30 }
31
32 func (l *UAPIListener) Accept() (net.Conn, error) {
33 for {
34 select {
35 case conn := <-l.connNew:
36 return conn, nil
37
38 case err := <-l.connErr:
39 return nil, err
40 }
41 }
42 }
43
44 func (l *UAPIListener) Close() error {
45 return l.listener.Close()
46 }
47
48 func (l *UAPIListener) Addr() net.Addr {
49 return l.listener.Addr()
50 }
51
52 var UAPISecurityDescriptor *windows.SECURITY_DESCRIPTOR
53
54 func init() {
55 var err error
56 UAPISecurityDescriptor, err = windows.SecurityDescriptorFromString("O:SYD:P(A;;GA;;;SY)(A;;GA;;;BA)S:(ML;;NWNRNX;;;HI)")
57 if err != nil {
58 panic(err)
59 }
60 }
61
62 func UAPIListen(name string) (net.Listener, error) {
63 listener, err := (&namedpipe.ListenConfig{
64 SecurityDescriptor: UAPISecurityDescriptor,
65 }).Listen(`\\.\pipe\ProtectedPrefix\Administrators\WireGuard\` + name)
66 if err != nil {
67 return nil, err
68 }
69
70 uapi := &UAPIListener{
71 listener: listener,
72 connNew: make(chan net.Conn, 1),
73 connErr: make(chan error, 1),
74 }
75
76 go func(l *UAPIListener) {
77 for {
78 conn, err := l.listener.Accept()
79 if err != nil {
80 l.connErr <- err
81 break
82 }
83 l.connNew <- conn
84 }
85 }(uapi)
86
87 return uapi, nil
88 }
89