Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UAPI socket for the sandboxed Wireguard app #27

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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