diff --git a/Sources/Shared/Keychain.swift b/Sources/Shared/Keychain.swift index 2e0e7f01e..91493c57f 100644 --- a/Sources/Shared/Keychain.swift +++ b/Sources/Shared/Keychain.swift @@ -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 { diff --git a/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift b/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift index 0a303f4a2..f17370dbe 100644 --- a/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift +++ b/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift @@ -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) diff --git a/Sources/WireGuardKit/WireGuardAdapter.swift b/Sources/WireGuardKit/WireGuardAdapter.swift index f7be19b15..58a28a142 100644 --- a/Sources/WireGuardKit/WireGuardAdapter.swift +++ b/Sources/WireGuardKit/WireGuardAdapter.swift @@ -56,6 +56,9 @@ public class WireGuardAdapter { /// Adapter state. private var state: State = .stopped + /// File that will contain the real interface name (called .name) + private var wgTunNameFile: URL? = nil + /// Tunnel device file descriptor. private var tunnelFileDescriptor: Int32? { var ctlInfo = ctl_info() @@ -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) } } @@ -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()) @@ -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: diff --git a/Sources/WireGuardKitGo/api-apple.go b/Sources/WireGuardKitGo/api-apple.go index 5d24982ac..003a77edd 100644 --- a/Sources/WireGuardKitGo/api-apple.go +++ b/Sources/WireGuardKitGo/api-apple.go @@ -16,6 +16,7 @@ import "C" import ( "fmt" "math" + "net" "os" "os/signal" "runtime" @@ -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" ) @@ -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) @@ -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) @@ -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") @@ -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 diff --git a/Sources/WireGuardKitGo/go.mod b/Sources/WireGuardKitGo/go.mod index 789358e64..2df568e5d 100644 --- a/Sources/WireGuardKitGo/go.mod +++ b/Sources/WireGuardKitGo/go.mod @@ -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 ) diff --git a/Sources/WireGuardKitGo/go.sum b/Sources/WireGuardKitGo/go.sum index 278aef8f1..9bafe751b 100644 --- a/Sources/WireGuardKitGo/go.sum +++ b/Sources/WireGuardKitGo/go.sum @@ -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= @@ -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= @@ -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= @@ -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= @@ -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= @@ -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= @@ -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=