From 8924f946ddcb66ceb965e960aa62bb6ec9de173b Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 7 Feb 2021 16:10:37 -0800 Subject: [PATCH] safari: merge XPC service to run tabfs process. it builds but haven't hooked it in yet --- .../TabFS/TabFS.xcodeproj/project.pbxproj | 135 ++++++++++++++++++ .../UserInterfaceState.xcuserstate | Bin 40591 -> 57443 bytes .../xcschemes/xcschememanagement.plist | 5 + .../safari/TabFS/TabFSService/Info.plist | 29 ++++ .../TabFS/TabFSService/TabFSService.swift | 69 +++++++++ .../TabFSService/TabFSServiceProtocols.swift | 17 +++ .../safari/TabFS/TabFSService/main.swift | 13 ++ 7 files changed, 268 insertions(+) create mode 100644 extension/safari/TabFS/TabFSService/Info.plist create mode 100644 extension/safari/TabFS/TabFSService/TabFSService.swift create mode 100644 extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift create mode 100644 extension/safari/TabFS/TabFSService/main.swift diff --git a/extension/safari/TabFS/TabFS.xcodeproj/project.pbxproj b/extension/safari/TabFS/TabFS.xcodeproj/project.pbxproj index 4b063e1..d8f6003 100644 --- a/extension/safari/TabFS/TabFS.xcodeproj/project.pbxproj +++ b/extension/safari/TabFS/TabFS.xcodeproj/project.pbxproj @@ -7,6 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + F028D2B625D0B7370095C2D5 /* TabFSService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F028D2B525D0B7370095C2D5 /* TabFSService.swift */; }; + F028D2B825D0B7370095C2D5 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = F028D2B725D0B7370095C2D5 /* main.swift */; }; + F028D2BC25D0B7370095C2D5 /* TabFSService.xpc in Embed XPC Services */ = {isa = PBXBuildFile; fileRef = F028D2B125D0B7370095C2D5 /* TabFSService.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F028D2D725D0B8500095C2D5 /* TabFSServiceProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F028D2B325D0B7370095C2D5 /* TabFSServiceProtocols.swift */; }; + F028D2DE25D0B8590095C2D5 /* TabFSServiceProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F028D2B325D0B7370095C2D5 /* TabFSServiceProtocols.swift */; }; F04429F625C7507200D998A5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04429F525C7507200D998A5 /* AppDelegate.swift */; }; F04429F925C7507200D998A5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F04429F725C7507200D998A5 /* Main.storyboard */; }; F04429FB25C7507200D998A5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04429FA25C7507200D998A5 /* ViewController.swift */; }; @@ -22,6 +27,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + F028D2BA25D0B7370095C2D5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F04429E925C7507200D998A5 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F028D2B025D0B7370095C2D5; + remoteInfo = TabFSService; + }; F0442A0525C7507400D998A5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = F04429E925C7507200D998A5 /* Project object */; @@ -32,6 +44,17 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + F028D2BD25D0B7370095C2D5 /* Embed XPC Services */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; + dstSubfolderSpec = 16; + files = ( + F028D2BC25D0B7370095C2D5 /* TabFSService.xpc in Embed XPC Services */, + ); + name = "Embed XPC Services"; + runOnlyForDeploymentPostprocessing = 0; + }; F0442A1425C7507400D998A5 /* Embed App Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -46,6 +69,11 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + F028D2B125D0B7370095C2D5 /* TabFSService.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = TabFSService.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; + F028D2B325D0B7370095C2D5 /* TabFSServiceProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabFSServiceProtocols.swift; sourceTree = ""; }; + F028D2B525D0B7370095C2D5 /* TabFSService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabFSService.swift; sourceTree = ""; }; + F028D2B725D0B7370095C2D5 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + F028D2B925D0B7370095C2D5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F04429F125C7507200D998A5 /* TabFS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TabFS.app; sourceTree = BUILT_PRODUCTS_DIR; }; F04429F425C7507200D998A5 /* TabFS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TabFS.entitlements; sourceTree = ""; }; F04429F525C7507200D998A5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -66,6 +94,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + F028D2AE25D0B7370095C2D5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; F04429EE25C7507200D998A5 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -84,11 +119,23 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + F028D2B225D0B7370095C2D5 /* TabFSService */ = { + isa = PBXGroup; + children = ( + F028D2B325D0B7370095C2D5 /* TabFSServiceProtocols.swift */, + F028D2B525D0B7370095C2D5 /* TabFSService.swift */, + F028D2B725D0B7370095C2D5 /* main.swift */, + F028D2B925D0B7370095C2D5 /* Info.plist */, + ); + path = TabFSService; + sourceTree = ""; + }; F04429E825C7507200D998A5 = { isa = PBXGroup; children = ( F04429F325C7507200D998A5 /* TabFS */, F0442A0A25C7507400D998A5 /* TabFS Extension */, + F028D2B225D0B7370095C2D5 /* TabFSService */, F0442A0725C7507400D998A5 /* Frameworks */, F04429F225C7507200D998A5 /* Products */, ); @@ -99,6 +146,7 @@ children = ( F04429F125C7507200D998A5 /* TabFS.app */, F0442A0325C7507400D998A5 /* TabFS Extension.appex */, + F028D2B125D0B7370095C2D5 /* TabFSService.xpc */, ); name = Products; sourceTree = ""; @@ -151,6 +199,23 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + F028D2B025D0B7370095C2D5 /* TabFSService */ = { + isa = PBXNativeTarget; + buildConfigurationList = F028D2C025D0B7370095C2D5 /* Build configuration list for PBXNativeTarget "TabFSService" */; + buildPhases = ( + F028D2AD25D0B7370095C2D5 /* Sources */, + F028D2AE25D0B7370095C2D5 /* Frameworks */, + F028D2AF25D0B7370095C2D5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TabFSService; + productName = TabFSService; + productReference = F028D2B125D0B7370095C2D5 /* TabFSService.xpc */; + productType = "com.apple.product-type.xpc-service"; + }; F04429F025C7507200D998A5 /* TabFS */ = { isa = PBXNativeTarget; buildConfigurationList = F0442A1525C7507400D998A5 /* Build configuration list for PBXNativeTarget "TabFS" */; @@ -159,11 +224,13 @@ F04429EE25C7507200D998A5 /* Frameworks */, F04429EF25C7507200D998A5 /* Resources */, F0442A1425C7507400D998A5 /* Embed App Extensions */, + F028D2BD25D0B7370095C2D5 /* Embed XPC Services */, ); buildRules = ( ); dependencies = ( F0442A0625C7507400D998A5 /* PBXTargetDependency */, + F028D2BB25D0B7370095C2D5 /* PBXTargetDependency */, ); name = TabFS; productName = TabFS; @@ -196,6 +263,9 @@ LastSwiftUpdateCheck = 1210; LastUpgradeCheck = 1210; TargetAttributes = { + F028D2B025D0B7370095C2D5 = { + CreatedOnToolsVersion = 12.1; + }; F04429F025C7507200D998A5 = { CreatedOnToolsVersion = 12.1; }; @@ -219,11 +289,19 @@ targets = ( F04429F025C7507200D998A5 /* TabFS */, F0442A0225C7507400D998A5 /* TabFS Extension */, + F028D2B025D0B7370095C2D5 /* TabFSService */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + F028D2AF25D0B7370095C2D5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; F04429EF25C7507200D998A5 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -247,6 +325,16 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + F028D2AD25D0B7370095C2D5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F028D2B825D0B7370095C2D5 /* main.swift in Sources */, + F028D2B625D0B7370095C2D5 /* TabFSService.swift in Sources */, + F028D2D725D0B8500095C2D5 /* TabFSServiceProtocols.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F04429ED25C7507200D998A5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -260,6 +348,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F028D2DE25D0B8590095C2D5 /* TabFSServiceProtocols.swift in Sources */, F068D65625C7C66700DB3AB5 /* FSProcessManager.swift in Sources */, F0442A0C25C7507400D998A5 /* SafariWebExtensionHandler.swift in Sources */, ); @@ -268,6 +357,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + F028D2BB25D0B7370095C2D5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F028D2B025D0B7370095C2D5 /* TabFSService */; + targetProxy = F028D2BA25D0B7370095C2D5 /* PBXContainerItemProxy */; + }; F0442A0625C7507400D998A5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = F0442A0225C7507400D998A5 /* TabFS Extension */; @@ -287,6 +381,38 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + F028D2BE25D0B7370095C2D5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + ENABLE_HARDENED_RUNTIME = YES; + INFOPLIST_FILE = TabFSService/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = com.rsnous.TabFSService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; + SWIFT_VERSION = 4.2; + }; + name = Debug; + }; + F028D2BF25D0B7370095C2D5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + ENABLE_HARDENED_RUNTIME = YES; + INFOPLIST_FILE = TabFSService/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = com.rsnous.TabFSService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; + SWIFT_VERSION = 4.2; + }; + name = Release; + }; F0442A0F25C7507400D998A5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -485,6 +611,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + F028D2C025D0B7370095C2D5 /* Build configuration list for PBXNativeTarget "TabFSService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F028D2BE25D0B7370095C2D5 /* Debug */, + F028D2BF25D0B7370095C2D5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; F04429EC25C7507200D998A5 /* Build configuration list for PBXProject "TabFS" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate b/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate index 90dd5fe6e0c1302bb59001b590c788681c1bb0bf..0ed33c6b977d690b04f4aef7517264e48a610b72 100644 GIT binary patch delta 29481 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 delta 18312 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 0 + TabFSService.xcscheme_^#shared#^_ + + orderHint + 1 + diff --git a/extension/safari/TabFS/TabFSService/Info.plist b/extension/safari/TabFS/TabFSService/Info.plist new file mode 100644 index 0000000..8b1c3aa --- /dev/null +++ b/extension/safari/TabFS/TabFSService/Info.plist @@ -0,0 +1,29 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + TabFSService + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + XPCService + + ServiceType + Application + + + diff --git a/extension/safari/TabFS/TabFSService/TabFSService.swift b/extension/safari/TabFS/TabFSService/TabFSService.swift new file mode 100644 index 0000000..f91a4b4 --- /dev/null +++ b/extension/safari/TabFS/TabFSService/TabFSService.swift @@ -0,0 +1,69 @@ +// +// TabFSService.swift +// TabFSService +// +// Created by Omar Rizwan on 2/7/21. +// + +import Foundation + +class TabFSService: NSObject, TabFSServiceProtocol { + var fs: Process! + var fsInput: FileHandle! + var fsOutput: FileHandle! + + init(app: TabFSServiceConsumerProtocol) { + super.init() + + fs = Process() + fs.executableURL = URL(fileURLWithPath: "/Users/osnr/Code/tabfs/fs/tabfs") + fs.currentDirectoryURL = fs.executableURL?.deletingLastPathComponent() + + fs.arguments = [] + + let inputPipe = Pipe(), outputPipe = Pipe() + fs.standardInput = inputPipe + fs.standardOutput = outputPipe + + fsInput = inputPipe.fileHandleForWriting + fsOutput = outputPipe.fileHandleForReading + + try! fs.run() + + // split new thread + DispatchQueue.global(qos: .default).async { + while true { + // read from them + let length = self.fsOutput.readData(ofLength: 4).withUnsafeBytes { $0.load(as: UInt32.self) } + let req = self.fsOutput.readData(ofLength: Int(length)) + // send to other side of XPC conn + app.request(req) + } + } + + // FIXME: disable auto termination + } + + func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) { + let response = string.uppercased() + reply(response) + } + + func response(_ resp: Data) { + fsInput.write(withUnsafeBytes(of: UInt32(resp.count)) { Data($0) }) + fsInput.write(resp) + } +} + +class TabFSServiceDelegate: NSObject, NSXPCListenerDelegate { + func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { + newConnection.remoteObjectInterface = NSXPCInterface(with: TabFSServiceConsumerProtocol.self) + + let exportedObject = TabFSService(app: newConnection.remoteObjectProxy as! TabFSServiceConsumerProtocol) + newConnection.exportedInterface = NSXPCInterface(with: TabFSServiceProtocol.self) + newConnection.exportedObject = exportedObject + + newConnection.resume() + return true + } +} diff --git a/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift b/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift new file mode 100644 index 0000000..298015a --- /dev/null +++ b/extension/safari/TabFS/TabFSService/TabFSServiceProtocols.swift @@ -0,0 +1,17 @@ +// +// TabFSServiceProtocols.swift +// app-sandbox-xpc-test +// +// Created by Omar Rizwan on 2/7/21. +// + +import Foundation + +@objc public protocol TabFSServiceConsumerProtocol { + func request(_ req: Data) +} +@objc public protocol TabFSServiceProtocol { + func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) + + func response(_ resp: Data) +} diff --git a/extension/safari/TabFS/TabFSService/main.swift b/extension/safari/TabFS/TabFSService/main.swift new file mode 100644 index 0000000..39c5a75 --- /dev/null +++ b/extension/safari/TabFS/TabFSService/main.swift @@ -0,0 +1,13 @@ +// +// main.m +// TabFSService +// +// Created by Omar Rizwan on 2/7/21. +// + +import Foundation + +let delegate = TabFSServiceDelegate() +let listener = NSXPCListener.service() +listener.delegate = delegate +listener.resume()