Add Wireguard support to Burrow

This commit is contained in:
Jett Chen 2023-12-17 01:20:56 +08:00 committed by Conrad Kramer
parent 60257b256a
commit d3448e2bc7
59 changed files with 3805 additions and 521 deletions

View file

@ -251,7 +251,6 @@
);
mainGroup = D05B9F6929E39EEC008CB1F9;
packageReferences = (
D0BCC6102A0B327700AD070D /* XCRemoteSwiftPackageReference "SwiftLint" */,
);
productRefGroup = D05B9F7329E39EEC008CB1F9 /* Products */;
projectDirPath = "";

View file

@ -1,77 +0,0 @@
{
"pins" : [
{
"identity" : "collectionconcurrencykit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
"state" : {
"revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
"version" : "0.2.0"
}
},
{
"identity" : "sourcekitten",
"kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/SourceKitten.git",
"state" : {
"revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56",
"version" : "0.34.1"
}
},
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a",
"version" : "1.2.2"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"revision" : "013a48e2312e57b7b355db25bd3ea75282ebf274",
"version" : "0.50900.0-swift-DEVELOPMENT-SNAPSHOT-2023-02-06-a"
}
},
{
"identity" : "swiftlint",
"kind" : "remoteSourceControl",
"location" : "https://github.com/realm/SwiftLint.git",
"state" : {
"revision" : "eb85125a5f293de3d3248af259980c98bc2b1faa",
"version" : "0.51.0"
}
},
{
"identity" : "swiftytexttable",
"kind" : "remoteSourceControl",
"location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
"state" : {
"revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
"version" : "0.9.0"
}
},
{
"identity" : "swxmlhash",
"kind" : "remoteSourceControl",
"location" : "https://github.com/drmohundro/SWXMLHash.git",
"state" : {
"revision" : "4d0f62f561458cbe1f732171e625f03195151b60",
"version" : "7.0.1"
}
},
{
"identity" : "yams",
"kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/Yams.git",
"state" : {
"revision" : "f47ba4838c30dbd59998a4e4c87ab620ff959e8a",
"version" : "5.0.5"
}
}
],
"version" : 2
}

View file

@ -113,7 +113,7 @@ final class BurrowIpc {
return data
}
func request<U: Decodable>(_ request: Request, type: U.Type) async throws -> U {
func request<U: Decodable>(_ request: any Request, type: U.Type) async throws -> U {
do {
var data: Data = try JSONEncoder().encode(request)
data.append(contentsOf: [10])

View file

@ -7,16 +7,43 @@ enum BurrowError: Error {
case resultIsNone
}
protocol Request: Codable {
protocol Request: Codable where CommandT: Codable {
associatedtype CommandT
var id: UInt { get set }
var command: String { get set }
var command: CommandT { get set }
}
struct BurrowRequest: Request {
struct BurrowSingleCommand: Request {
var id: UInt
var command: String
}
struct BurrowRequest<T>: Request where T: Codable {
var id: UInt
var command: T
}
struct BurrowStartRequest: Codable {
struct TunOptions: Codable {
let name: String?
let no_pi: Bool
let tun_excl: Bool
let tun_retrieve: Bool
let address: String?
}
struct StartOptions: Codable {
let tun: TunOptions
}
let Start: StartOptions
}
func start_req_fd(id: UInt) -> BurrowRequest<BurrowStartRequest> {
let command = BurrowStartRequest(Start: BurrowStartRequest.StartOptions(
tun: BurrowStartRequest.TunOptions(name: nil, no_pi: false, tun_excl: false, tun_retrieve: true, address: nil)
))
return BurrowRequest(id: id, command: command)
}
struct Response<T>: Decodable where T: Decodable {
var id: UInt
var result: T

View file

@ -4,6 +4,8 @@
<dict>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>packet-tunnel-provider</string>

View file

@ -6,7 +6,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
let logger = Logger(subsystem: "com.hackclub.burrow", category: "frontend")
var client: BurrowIpc?
var osInitialized = false
override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
override func startTunnel(options: [String: NSObject]? = nil) async throws {
logger.log("Starting tunnel")
if !osInitialized {
libburrow.initialize_oslog()
@ -15,28 +15,35 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
libburrow.start_srv()
client = BurrowIpc(logger: logger)
logger.info("Started server")
Task {
do {
let command = BurrowRequest(id: 0, command: "ServerConfig")
guard let data = try await client?.request(command, type: Response<BurrowResult<ServerConfigData>>.self)
else {
throw BurrowError.cantParseResult
}
let encoded = try JSONEncoder().encode(data.result)
self.logger.log("Received final data: \(String(decoding: encoded, as: UTF8.self))")
guard let serverconfig = data.result.Ok else {
throw BurrowError.resultIsError
}
guard let tunNs = self.generateTunSettings(from: serverconfig) else {
throw BurrowError.addrDoesntExist
}
try await self.setTunnelNetworkSettings(tunNs)
self.logger.info("Set remote tunnel address to \(tunNs.tunnelRemoteAddress)")
completionHandler(nil)
} catch {
self.logger.error("An error occurred: \(error)")
completionHandler(error)
do {
let command = BurrowSingleCommand(id: 0, command: "ServerConfig")
guard let data = try await client?.request(command, type: Response<BurrowResult<ServerConfigData>>.self)
else {
throw BurrowError.cantParseResult
}
let encoded = try JSONEncoder().encode(data.result)
self.logger.log("Received final data: \(String(decoding: encoded, as: UTF8.self))")
guard let serverconfig = data.result.Ok else {
throw BurrowError.resultIsError
}
guard let tunNs = self.generateTunSettings(from: serverconfig) else {
throw BurrowError.addrDoesntExist
}
try await self.setTunnelNetworkSettings(tunNs)
self.logger.info("Set remote tunnel address to \(tunNs.tunnelRemoteAddress)")
// let tunFd = self.packetFlow.value(forKeyPath: "socket.fileDescriptor") as! Int;
// self.logger.info("Found File Descriptor: \(tunFd)")
let startCommand = start_req_fd(id: 1)
guard let data = try await client?.request(startCommand, type: Response<BurrowResult<String>>.self)
else {
throw BurrowError.cantParseResult
}
let encodedStartRes = try JSONEncoder().encode(data.result)
self.logger.log("Received start server response: \(String(decoding: encodedStartRes, as: UTF8.self))")
} catch {
self.logger.error("An error occurred: \(error)")
throw error
}
}
private func generateTunSettings(from: ServerConfigData) -> NETunnelNetworkSettings? {
@ -50,16 +57,12 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
logger.log("Initialized ipv4 settings: \(nst.ipv4Settings)")
return nst
}
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
completionHandler()
override func stopTunnel(with reason: NEProviderStopReason) async {
}
override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
if let handler = completionHandler {
handler(messageData)
}
override func handleAppMessage(_ messageData: Data) async -> Data? {
messageData
}
override func sleep(completionHandler: @escaping () -> Void) {
completionHandler()
override func sleep() async {
}
override func wake() {
}