Skip to content

Commit

Permalink
UAPI for macOS
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Noha <[email protected]>
  • Loading branch information
nohajc committed Sep 10, 2023
1 parent 2fec12a commit b544fb9
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 13 deletions.
16 changes: 16 additions & 0 deletions Sources/Shared/Keychain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@ class Keychain {
return String(data: data, encoding: String.Encoding.utf8)
}

static func getReferenceName(called ref: Data) -> String? {
var result: CFTypeRef?
let ret = SecItemCopyMatching([kSecValuePersistentRef: ref,
kSecReturnAttributes: true] as CFDictionary,
&result)
if ret != errSecSuccess || result == nil {
wg_log(.error, message: "Unable to get config attributes from keychain: \(ret)")
return nil
}
guard let attrs = result as? [CFString: AnyObject] else { return nil }

guard let secAttrAccount = attrs[kSecAttrAccount] as? String else { return nil }
let name = secAttrAccount.split(separator: ":", maxSplits: 1)[0]
return String(name)
}

static func makeReference(containing value: String, called name: String, previouslyReferencedBy oldRef: Data? = nil) -> Data? {
var ret: OSStatus
guard var bundleIdentifier = Bundle.main.bundleIdentifier else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ extension NETunnelProviderProtocol {
func asTunnelConfiguration(called name: String? = nil) -> TunnelConfiguration? {
if let passwordReference = passwordReference,
let config = Keychain.openReference(called: passwordReference) {
return try? TunnelConfiguration(fromWgQuickConfig: config, called: name)
var tunnelName = name
if tunnelName == nil {
tunnelName = Keychain.getReferenceName(called: passwordReference)
}
return try? TunnelConfiguration(fromWgQuickConfig: config, called: tunnelName)
}
if let oldConfig = providerConfiguration?["WgQuickConfig"] as? String {
return try? TunnelConfiguration(fromWgQuickConfig: oldConfig, called: name)
Expand Down
21 changes: 21 additions & 0 deletions Sources/WireGuardKit/WireGuardAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public class WireGuardAdapter {
/// Adapter state.
private var state: State = .stopped

/// File that will contain the real interface name (called <name-of-tunnel>.name)
private var wgTunNameFile: URL? = nil

/// Tunnel device file descriptor.
private var tunnelFileDescriptor: Int32? {
var ctlInfo = ctl_info()
Expand Down Expand Up @@ -146,6 +149,9 @@ public class WireGuardAdapter {

// Shutdown the tunnel
if case .started(let handle, _) = self.state {
if let wgTunNameFile = self.wgTunNameFile {
_ = FileManager.deleteFile(at: wgTunNameFile)
}
wgTurnOff(handle)
}
}
Expand Down Expand Up @@ -187,6 +193,18 @@ public class WireGuardAdapter {
}
networkMonitor.start(queue: self.workQueue)

if let tunnelName = tunnelConfiguration.name, let ifaceName = self.interfaceName {
let wgTunNameFile = NSHomeDirectory() + "/" + tunnelName + ".name"
self.wgTunNameFile = URL(fileURLWithPath: wgTunNameFile, isDirectory: false)

let ifaceNameData = "\(ifaceName)\n".data(using: .utf8)
if !FileManager.default.createFile(atPath: wgTunNameFile,
contents: ifaceNameData,
attributes: [.posixPermissions: 0o400]) {
self.logHandler(.error, "Failed to write wg tun name file")
}
}

do {
let settingsGenerator = try self.makeSettingsGenerator(with: tunnelConfiguration)
try self.setNetworkSettings(settingsGenerator.generateNetworkSettings())
Expand Down Expand Up @@ -215,6 +233,9 @@ public class WireGuardAdapter {
workQueue.async {
switch self.state {
case .started(let handle, _):
if let wgTunNameFile = self.wgTunNameFile {
_ = FileManager.deleteFile(at: wgTunNameFile)
}
wgTurnOff(handle)

case .temporaryShutdown:
Expand Down
61 changes: 60 additions & 1 deletion Sources/WireGuardKitGo/api-apple.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import "C"
import (
"fmt"
"math"
"net"
"os"
"os/signal"
"runtime"
Expand All @@ -27,6 +28,7 @@ import (
"golang.org/x/sys/unix"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/ipc"
"golang.zx2c4.com/wireguard/tun"
)

Expand Down Expand Up @@ -54,6 +56,7 @@ func (l CLogger) Printf(format string, args ...interface{}) {
type tunnelHandle struct {
*device.Device
*device.Logger
uapi net.Listener
}

var tunnelHandles = make(map[int32]tunnelHandle)
Expand Down Expand Up @@ -100,6 +103,7 @@ func wgTurnOn(settings *C.char, tunFd int32) int32 {
unix.Close(dupTunFd)
return -1
}

tun, err := tun.CreateTUNFromFile(os.NewFile(uintptr(dupTunFd), "/dev/tun"), 0)
if err != nil {
logger.Errorf("Unable to create new tun device from fd: %v", err)
Expand All @@ -116,6 +120,21 @@ func wgTurnOn(settings *C.char, tunFd int32) int32 {
return -1
}

var uapi net.Listener
if runtime.GOOS != "ios" {
ifaceName, err := tun.Name()
if err != nil {
logger.Errorf("Unable to get interface name: %v", err)
return -1
}

uapi, err = openUapiSocket(logger, ifaceName, dev)
if err != nil {
logger.Errorf("Unable to listen on UAPI socket: %v", err)
return -1
}
}

dev.Up()
logger.Verbosef("Device started")

Expand All @@ -129,18 +148,58 @@ func wgTurnOn(settings *C.char, tunFd int32) int32 {
unix.Close(dupTunFd)
return -1
}
tunnelHandles[i] = tunnelHandle{dev, logger}

tunnelHandles[i] = tunnelHandle{dev, logger, uapi}

return i
}

func openUapiSocket(logger *device.Logger, ifaceName string, device *device.Device) (net.Listener, error) {
fileUAPI, err := ipc.UAPIOpen(ifaceName)
if err != nil {
return nil, err
}
uapi, err := ipc.UAPIListen(ifaceName, fileUAPI)
if err != nil {
return nil, err
}

go func() {
for {
conn, err := uapi.Accept()
if err != nil {
logger.Errorf("UAPI error: %v", err)
return
}
go device.IpcHandle(conn)
}
}()

logger.Verbosef("UAPI listener started")

return uapi, nil
}

//export wgTurnOff
func wgTurnOff(tunnelHandle int32) {
logger := &device.Logger{
Verbosef: CLogger(0).Printf,
Errorf: CLogger(1).Printf,
}

dev, ok := tunnelHandles[tunnelHandle]
if !ok {
return
}
delete(tunnelHandles, tunnelHandle)
dev.Close()

if dev.uapi != nil {
err := dev.uapi.Close()
if err != nil {
logger.Errorf("Unable to close UAPI socket: %v", err)
}
}
}

//export wgSetConfig
Expand Down
4 changes: 2 additions & 2 deletions Sources/WireGuardKitGo/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ module golang.zx2c4.com/wireguard/apple
go 1.17

require (
golang.org/x/sys v0.5.0
golang.org/x/sys v0.5.1-0.20230222185716-a3b23cc77e89
golang.zx2c4.com/wireguard v0.0.0-20230209153558-1e2c3e5a3c14
)

require (
golang.org/x/crypto v0.6.0 // indirect
golang.org/x/net v0.6.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
)
16 changes: 7 additions & 9 deletions Sources/WireGuardKitGo/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
Expand Down Expand Up @@ -350,7 +351,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand Down Expand Up @@ -425,11 +425,10 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -500,12 +499,12 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.1-0.20230222185716-a3b23cc77e89 h1:260HNjMTPDya+jq5AM1zZLgG9pv9GASPAGiEEJUbRg4=
golang.org/x/sys v0.5.1-0.20230222185716-a3b23cc77e89/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
Expand All @@ -521,6 +520,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down Expand Up @@ -575,11 +575,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20230209153558-1e2c3e5a3c14 h1:HVTnb30bngAvlUMb5VRy4jELMvWL5VIapumjqzFXMZc=
golang.zx2c4.com/wireguard v0.0.0-20230209153558-1e2c3e5a3c14/go.mod h1:whfbyDBt09xhCYQWtO2+3UVjlaq6/9hDZrjg2ZE6SyA=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
Expand Down Expand Up @@ -683,6 +680,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
gvisor.dev/gvisor v0.0.0-20221203005347-703fd9b7fbc0 h1:Wobr37noukisGxpKo5jAsLREcpj61RxrWYzD8uwveOY=
gvisor.dev/gvisor v0.0.0-20221203005347-703fd9b7fbc0/go.mod h1:Dn5idtptoW1dIos9U6A2rpebLs/MtTwFacjKb8jLdQA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down

0 comments on commit b544fb9

Please sign in to comment.