diff --git a/README.md b/README.md index 2470f85..b203491 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,15 @@ # network proxy -http、https抓包工具,支持windows、mac、linux +## http、https抓包工具,支持Windows、Mac、Android。Ios打包中。。。 + +> ios版本得需要用NetworkExtension框架,用NetworkExtension API得需要先交99$使用费,过两天准备在整开发者账号。ios第一年我先用爱发电下。 + +- mac会提示已损坏,需要到系统偏好设置-安全性与隐私-允许任何来源 +- Mac先点左上角关闭按钮退出,直接Command+q可能不会清理系统代理。如果退出上不了网,请检查系统代理设置,清除即可。 + +- [ ] 接下来会完善功能体验,JSON格式化展示,URL解码,UI优化。 +- [ ] IOS打包上架app Store,个人开发者账号已经买了,NetworkExtension API权限还在申请中。 +- [ ] 后面桌面端和手机端整合,扫码连接啥的,不用手动配置Wifi代理,包括配置同步。 +- [ ] 支持安卓微信小程序抓包,安卓分为系统证书和用户证书,下载的自签名根证书安装都是用户证书,微信不信任用户证书,不Root导致Https抓不了了, 目前市场上所有抓包软件抓不了微信的包,后面单独做个运行空间插件,动态反编译修改配置,信任用户证书来解决。 -mac会提示已损坏,需要到系统偏好设置-安全性与隐私-允许任何来源 diff --git a/ios/ProxyPin/AppProxyProvider.swift b/ios/ProxyPin/AppProxyProvider.swift deleted file mode 100644 index 6a50d14..0000000 --- a/ios/ProxyPin/AppProxyProvider.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppProxyProvider.swift -// ProxyPin -// -// Created by 汪红恩 on 2023/7/2. -// - -import NetworkExtension - -class AppProxyProvider: NEAppProxyProvider { - - override func startProxy(options: [String : Any]? = nil, completionHandler: @escaping (Error?) -> Void) { - - } - - override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { - // Add code here to start the process of stopping the tunnel. - completionHandler() - } - - override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { - // Add code here to handle the message. - if let handler = completionHandler { - handler(messageData) - } - } - - override func sleep(completionHandler: @escaping() -> Void) { - // Add code here to get ready to sleep. - completionHandler() - } - - override func wake() { - // Add code here to wake up. - } - - override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { - // Add code here to handle the incoming flow. - return false - } -} diff --git a/ios/ProxyPin/Info.plist b/ios/ProxyPin/Info.plist index dd575d7..3059459 100644 --- a/ios/ProxyPin/Info.plist +++ b/ios/ProxyPin/Info.plist @@ -5,9 +5,9 @@ NSExtension NSExtensionPointIdentifier - com.apple.networkextension.app-proxy + com.apple.networkextension.packet-tunnel NSExtensionPrincipalClass - $(PRODUCT_MODULE_NAME).AppProxyProvider + $(PRODUCT_MODULE_NAME).PacketTunnelProvider diff --git a/ios/ProxyPin/PacketTunnelProvider.swift b/ios/ProxyPin/PacketTunnelProvider.swift new file mode 100644 index 0000000..378c5d8 --- /dev/null +++ b/ios/ProxyPin/PacketTunnelProvider.swift @@ -0,0 +1,66 @@ +// +// PacketTunnelProvider.swift +// ProxyPin +// +// Created by 汪红恩 on 2023/7/4. +// + +import NetworkExtension + + +class PacketTunnelProvider: NEPacketTunnelProvider { + + override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) { + NSLog("startTunnel") + + guard let conf = (protocolConfiguration as! NETunnelProviderProtocol).providerConfiguration else{ + NSLog("[ERROR] No ProtocolConfiguration Found") + exit(EXIT_FAILURE) + } + let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "127.0.0.1") + + //http代理 + let host = conf["proxtHost"] as! String + let proxyPort = conf["proxyPort"] as! Int + let proxySettings = NEProxySettings() + proxySettings.httpEnabled = true + proxySettings.httpServer = NEProxyServer(address: host, port: proxyPort) + proxySettings.httpsEnabled = true + proxySettings.httpsServer = NEProxyServer(address: host, port: proxyPort) + proxySettings.matchDomains = [""] + networkSettings.proxySettings = proxySettings + + setTunnelNetworkSettings(networkSettings) { + error in + guard error == nil else { + NSLog(error.debugDescription) + NSLog("startTunnel Encountered an error setting up the network: \(error.debugDescription)") + completionHandler(error) + return + } + completionHandler(nil) + + } + NSLog("startTunnelend") + } + + override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { + completionHandler() + } + + override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { + // Add code here to handle the message. + if let handler = completionHandler { + handler(messageData) + } + } + + override func sleep(completionHandler: @escaping () -> Void) { + // Add code here to get ready to sleep. + completionHandler() + } + + override func wake() { + // Add code here to wake up. + } +} diff --git a/ios/ProxyPin/ProxyPin.entitlements b/ios/ProxyPin/ProxyPin.entitlements index 0c67376..de73917 100644 --- a/ios/ProxyPin/ProxyPin.entitlements +++ b/ios/ProxyPin/ProxyPin.entitlements @@ -1,5 +1,22 @@ - + + com.apple.security.application-groups + + group.com.proxy.pin + + com.apple.developer.networking.networkextension + + packet-tunnel-provider + + com.apple.developer.networking.vpn.api + + allow-vpn + + com.apple.security.network.client + + com.apple.security.network.server + + diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 3af13ab..3b21ed3 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -8,17 +8,18 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 1FBB39B834EBBDA7C793EA99 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 239046BD4495108B4DFCCCB4 /* Pods_Runner.framework */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 6908A64E6209508CAB07A9DC /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9192F2719A6F4D80ED74CAB6 /* Pods_RunnerTests.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - 9B2100D32A518E4A00C4CE6D /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B2100D22A518E4A00C4CE6D /* NetworkExtension.framework */; }; - 9B2100D62A518E4A00C4CE6D /* AppProxyProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2100D52A518E4A00C4CE6D /* AppProxyProvider.swift */; }; - 9B2100DB2A518E4A00C4CE6D /* ProxyPin.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 9B2100D12A518E4A00C4CE6D /* ProxyPin.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - CF14D8EB2E69DF99DEBCECF0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C0C774BE6189A17B45C6992 /* Pods_Runner.framework */; }; + 9B09121B2A5457B3001108B7 /* VpnManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B09121A2A5457B3001108B7 /* VpnManager.swift */; }; + 9B0912222A54593A001108B7 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B0912212A54593A001108B7 /* NetworkExtension.framework */; }; + 9B0912252A54593A001108B7 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B0912242A54593A001108B7 /* PacketTunnelProvider.swift */; }; + 9B09122A2A54593A001108B7 /* ProxyPin.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 9B0912202A54593A001108B7 /* ProxyPin.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + B375908E625E0AED772FA2C0 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D37E307095F2B3E689A68827 /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -29,11 +30,11 @@ remoteGlobalIDString = 97C146ED1CF9000F007C117D; remoteInfo = Runner; }; - 9B2100D92A518E4A00C4CE6D /* PBXContainerItemProxy */ = { + 9B0912282A54593A001108B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 97C146E61CF9000F007C117D /* Project object */; proxyType = 1; - remoteGlobalIDString = 9B2100D02A518E4A00C4CE6D; + remoteGlobalIDString = 9B09121F2A54593A001108B7; remoteInfo = ProxyPin; }; /* End PBXContainerItemProxy section */ @@ -49,13 +50,13 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; - 9B2100CC2A515B2700C4CE6D /* Embed Foundation Extensions */ = { + 9B09122B2A54593B001108B7 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 13; files = ( - 9B2100DB2A518E4A00C4CE6D /* ProxyPin.appex in Embed Foundation Extensions */, + 9B09122A2A54593A001108B7 /* ProxyPin.appex in Embed Foundation Extensions */, ); name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -63,19 +64,20 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 052BE338CBB8FB26DF009F26 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 0B67A4E592FF13260AAFD656 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 1CB0AD40A6DA00CE01584609 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 239046BD4495108B4DFCCCB4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 306514357AC94BE3DDEBC8D8 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 6FAD660D5E68D1F6486BD2B4 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 3E54CF83D4EE560125987C8A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 72900351EF1A3F028032459A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 75A084AE8EB04B039B155D53 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 9192F2719A6F4D80ED74CAB6 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8215052AB7CBF47CD3DAAF69 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -83,25 +85,23 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9B2100D12A518E4A00C4CE6D /* ProxyPin.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ProxyPin.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 9B2100D22A518E4A00C4CE6D /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; - 9B2100D52A518E4A00C4CE6D /* AppProxyProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppProxyProvider.swift; sourceTree = ""; }; - 9B2100D72A518E4A00C4CE6D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9B2100D82A518E4A00C4CE6D /* ProxyPin.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ProxyPin.entitlements; sourceTree = ""; }; - 9B21012C2A51B27B00C4CE6D /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = ""; }; - 9B21012D2A51B28C00C4CE6D /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = ""; }; - 9BD35FD22A514DE700047BE6 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; - 9C0C774BE6189A17B45C6992 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - E9A0152C624790970DB78215 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - F919791FEAC7D73B4D9592FF /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 9B0912192A545757001108B7 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + 9B09121A2A5457B3001108B7 /* VpnManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VpnManager.swift; sourceTree = ""; }; + 9B0912202A54593A001108B7 /* ProxyPin.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ProxyPin.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 9B0912212A54593A001108B7 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; + 9B0912242A54593A001108B7 /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = ""; }; + 9B0912262A54593A001108B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9B0912272A54593A001108B7 /* ProxyPin.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ProxyPin.entitlements; sourceTree = ""; }; + D37E307095F2B3E689A68827 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E328C7F89A365CDC0EAD15C6 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 3FB1D991624E9E758C7A4E6A /* Frameworks */ = { + 2C2BB3BDC059E8FD67F7FF64 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6908A64E6209508CAB07A9DC /* Pods_RunnerTests.framework in Frameworks */, + B375908E625E0AED772FA2C0 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -109,32 +109,29 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - CF14D8EB2E69DF99DEBCECF0 /* Pods_Runner.framework in Frameworks */, + 1FBB39B834EBBDA7C793EA99 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 9B2100CE2A518E4A00C4CE6D /* Frameworks */ = { + 9B09121D2A54593A001108B7 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9B2100D32A518E4A00C4CE6D /* NetworkExtension.framework in Frameworks */, + 9B0912222A54593A001108B7 /* NetworkExtension.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 28116BD5613F7CA13808AF09 /* Pods */ = { + 28892733E959FF4F4696A049 /* Frameworks */ = { isa = PBXGroup; children = ( - 1CB0AD40A6DA00CE01584609 /* Pods-Runner.debug.xcconfig */, - E9A0152C624790970DB78215 /* Pods-Runner.release.xcconfig */, - 6FAD660D5E68D1F6486BD2B4 /* Pods-Runner.profile.xcconfig */, - F919791FEAC7D73B4D9592FF /* Pods-RunnerTests.debug.xcconfig */, - 75A084AE8EB04B039B155D53 /* Pods-RunnerTests.release.xcconfig */, - 052BE338CBB8FB26DF009F26 /* Pods-RunnerTests.profile.xcconfig */, + 239046BD4495108B4DFCCCB4 /* Pods_Runner.framework */, + D37E307095F2B3E689A68827 /* Pods_RunnerTests.framework */, + 9B0912212A54593A001108B7 /* NetworkExtension.framework */, ); - path = Pods; + name = Frameworks; sourceTree = ""; }; 331C8082294A63A400263BE5 /* RunnerTests */ = { @@ -145,6 +142,19 @@ path = RunnerTests; sourceTree = ""; }; + 8A601D60E7BAF3F69F98077D /* Pods */ = { + isa = PBXGroup; + children = ( + 0B67A4E592FF13260AAFD656 /* Pods-Runner.debug.xcconfig */, + 72900351EF1A3F028032459A /* Pods-Runner.release.xcconfig */, + 3E54CF83D4EE560125987C8A /* Pods-Runner.profile.xcconfig */, + 306514357AC94BE3DDEBC8D8 /* Pods-RunnerTests.debug.xcconfig */, + E328C7F89A365CDC0EAD15C6 /* Pods-RunnerTests.release.xcconfig */, + 8215052AB7CBF47CD3DAAF69 /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -161,11 +171,11 @@ children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, - 9B2100D42A518E4A00C4CE6D /* ProxyPin */, + 9B0912232A54593A001108B7 /* ProxyPin */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, - 28116BD5613F7CA13808AF09 /* Pods */, - C5DB5B6C6A0A7F48A633BC00 /* Frameworks */, + 8A601D60E7BAF3F69F98077D /* Pods */, + 28892733E959FF4F4696A049 /* Frameworks */, ); sourceTree = ""; }; @@ -174,7 +184,7 @@ children = ( 97C146EE1CF9000F007C117D /* Runner.app */, 331C8081294A63A400263BE5 /* RunnerTests.xctest */, - 9B2100D12A518E4A00C4CE6D /* ProxyPin.appex */, + 9B0912202A54593A001108B7 /* ProxyPin.appex */, ); name = Products; sourceTree = ""; @@ -182,9 +192,8 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( - 9B21012D2A51B28C00C4CE6D /* RunnerDebug.entitlements */, - 9B21012C2A51B27B00C4CE6D /* RunnerRelease.entitlements */, - 9BD35FD22A514DE700047BE6 /* Runner.entitlements */, + 9B09121A2A5457B3001108B7 /* VpnManager.swift */, + 9B0912192A545757001108B7 /* Runner.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, @@ -197,26 +206,16 @@ path = Runner; sourceTree = ""; }; - 9B2100D42A518E4A00C4CE6D /* ProxyPin */ = { + 9B0912232A54593A001108B7 /* ProxyPin */ = { isa = PBXGroup; children = ( - 9B2100D52A518E4A00C4CE6D /* AppProxyProvider.swift */, - 9B2100D72A518E4A00C4CE6D /* Info.plist */, - 9B2100D82A518E4A00C4CE6D /* ProxyPin.entitlements */, + 9B0912242A54593A001108B7 /* PacketTunnelProvider.swift */, + 9B0912262A54593A001108B7 /* Info.plist */, + 9B0912272A54593A001108B7 /* ProxyPin.entitlements */, ); path = ProxyPin; sourceTree = ""; }; - C5DB5B6C6A0A7F48A633BC00 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 9C0C774BE6189A17B45C6992 /* Pods_Runner.framework */, - 9192F2719A6F4D80ED74CAB6 /* Pods_RunnerTests.framework */, - 9B2100D22A518E4A00C4CE6D /* NetworkExtension.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -224,10 +223,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( - 332BB1929DCB248F79EC2151 /* [CP] Check Pods Manifest.lock */, + E7E8C74F615A57D43D59596C /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, - 3FB1D991624E9E758C7A4E6A /* Frameworks */, + 2C2BB3BDC059E8FD67F7FF64 /* Frameworks */, ); buildRules = ( ); @@ -243,33 +242,33 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - BED770995353FBC43C0E1166 /* [CP] Check Pods Manifest.lock */, + 35A8CB519E229982B14B0197 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - E9D6F3D933BAF72EBFDCA603 /* [CP] Embed Pods Frameworks */, - 9B2100CC2A515B2700C4CE6D /* Embed Foundation Extensions */, + 593E01BCFF86ADFAC59E51D5 /* [CP] Embed Pods Frameworks */, + 9B09122B2A54593B001108B7 /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( - 9B2100DA2A518E4A00C4CE6D /* PBXTargetDependency */, + 9B0912292A54593A001108B7 /* PBXTargetDependency */, ); name = Runner; productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; }; - 9B2100D02A518E4A00C4CE6D /* ProxyPin */ = { + 9B09121F2A54593A001108B7 /* ProxyPin */ = { isa = PBXNativeTarget; - buildConfigurationList = 9B2100DC2A518E4A00C4CE6D /* Build configuration list for PBXNativeTarget "ProxyPin" */; + buildConfigurationList = 9B09122F2A54593B001108B7 /* Build configuration list for PBXNativeTarget "ProxyPin" */; buildPhases = ( - 9B2100CD2A518E4A00C4CE6D /* Sources */, - 9B2100CE2A518E4A00C4CE6D /* Frameworks */, - 9B2100CF2A518E4A00C4CE6D /* Resources */, + 9B09121C2A54593A001108B7 /* Sources */, + 9B09121D2A54593A001108B7 /* Frameworks */, + 9B09121E2A54593A001108B7 /* Resources */, ); buildRules = ( ); @@ -277,7 +276,7 @@ ); name = ProxyPin; productName = ProxyPin; - productReference = 9B2100D12A518E4A00C4CE6D /* ProxyPin.appex */; + productReference = 9B0912202A54593A001108B7 /* ProxyPin.appex */; productType = "com.apple.product-type.app-extension"; }; /* End PBXNativeTarget section */ @@ -298,7 +297,7 @@ CreatedOnToolsVersion = 7.3.1; LastSwiftMigration = 1100; }; - 9B2100D02A518E4A00C4CE6D = { + 9B09121F2A54593A001108B7 = { CreatedOnToolsVersion = 14.2; }; }; @@ -318,7 +317,7 @@ targets = ( 97C146ED1CF9000F007C117D /* Runner */, 331C8080294A63A400263BE5 /* RunnerTests */, - 9B2100D02A518E4A00C4CE6D /* ProxyPin */, + 9B09121F2A54593A001108B7 /* ProxyPin */, ); }; /* End PBXProject section */ @@ -342,7 +341,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 9B2100CF2A518E4A00C4CE6D /* Resources */ = { + 9B09121E2A54593A001108B7 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -352,7 +351,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 332BB1929DCB248F79EC2151 /* [CP] Check Pods Manifest.lock */ = { + 35A8CB519E229982B14B0197 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -367,7 +366,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -390,6 +389,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 593E01BCFF86ADFAC59E51D5 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -405,7 +421,7 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - BED770995353FBC43C0E1166 /* [CP] Check Pods Manifest.lock */ = { + E7E8C74F615A57D43D59596C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -420,30 +436,13 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - E9D6F3D933BAF72EBFDCA603 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -461,14 +460,15 @@ files = ( 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + 9B09121B2A5457B3001108B7 /* VpnManager.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 9B2100CD2A518E4A00C4CE6D /* Sources */ = { + 9B09121C2A54593A001108B7 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 9B2100D62A518E4A00C4CE6D /* AppProxyProvider.swift in Sources */, + 9B0912252A54593A001108B7 /* PacketTunnelProvider.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -480,10 +480,10 @@ target = 97C146ED1CF9000F007C117D /* Runner */; targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; }; - 9B2100DA2A518E4A00C4CE6D /* PBXTargetDependency */ = { + 9B0912292A54593A001108B7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 9B2100D02A518E4A00C4CE6D /* ProxyPin */; - targetProxy = 9B2100D92A518E4A00C4CE6D /* PBXContainerItemProxy */; + target = 9B09121F2A54593A001108B7 /* ProxyPin */; + targetProxy = 9B0912282A54593A001108B7 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -569,7 +569,6 @@ DEVELOPMENT_TEAM = DM3F8VR243; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = ProxyPin; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -584,14 +583,14 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F919791FEAC7D73B4D9592FF /* Pods-RunnerTests.debug.xcconfig */; + baseConfigurationReference = 306514357AC94BE3DDEBC8D8 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.network.pproxy.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.network.networkProxyFlutter.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -602,14 +601,14 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 75A084AE8EB04B039B155D53 /* Pods-RunnerTests.release.xcconfig */; + baseConfigurationReference = E328C7F89A365CDC0EAD15C6 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.network.pproxy.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.network.networkProxyFlutter.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -618,14 +617,14 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 052BE338CBB8FB26DF009F26 /* Pods-RunnerTests.profile.xcconfig */; + baseConfigurationReference = 8215052AB7CBF47CD3DAAF69 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.network.pproxy.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.network.networkProxyFlutter.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -746,21 +745,17 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = DM3F8VR243; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = ProxyPin; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.proxy.pin; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -775,12 +770,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = DM3F8VR243; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = ProxyPin; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -793,7 +787,7 @@ }; name = Release; }; - 9B2100DD2A518E4A00C4CE6D /* Debug */ = { + 9B09122C2A54593B001108B7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -831,7 +825,7 @@ }; name = Debug; }; - 9B2100DE2A518E4A00C4CE6D /* Release */ = { + 9B09122D2A54593B001108B7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -866,7 +860,7 @@ }; name = Release; }; - 9B2100DF2A518E4A00C4CE6D /* Profile */ = { + 9B09122E2A54593B001108B7 /* Profile */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -934,12 +928,12 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 9B2100DC2A518E4A00C4CE6D /* Build configuration list for PBXNativeTarget "ProxyPin" */ = { + 9B09122F2A54593B001108B7 /* Build configuration list for PBXNativeTarget "ProxyPin" */ = { isa = XCConfigurationList; buildConfigurations = ( - 9B2100DD2A518E4A00C4CE6D /* Debug */, - 9B2100DE2A518E4A00C4CE6D /* Release */, - 9B2100DF2A518E4A00C4CE6D /* Profile */, + 9B09122C2A54593B001108B7 /* Debug */, + 9B09122D2A54593B001108B7 /* Release */, + 9B09122E2A54593B001108B7 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 0d3c44d..8e1e125 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -8,26 +8,31 @@ import NetworkExtension _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - - let manager = NETunnelProviderManager() - let conf = NETunnelProviderProtocol() - conf.serverAddress = "https://127.0.0.1" -// // Include network traffic. -// let setting = NEProxySettings() -// setting.httpsEnabled = true -// setting.httpEnabled = true -// setting.httpsServer = NEProxyServer.init(address: "127.0.0.1", port: 8888) -// conf.proxySettings = setting -// - manager.protocolConfiguration = conf - manager.localizedDescription = "ProxyPin" - manager.isEnabled = true + GeneratedPluginRegistrant.register(with: self) + +// let url = URL(string: "http://www.baidu.com")! +// let task = URLSession.shared.dataTask(with: url) {(data, response, error) in +// guard let data = data else { return } +// print(String(data: data, encoding: .utf8)!) +// } +// task.resume() + + let controller: FlutterViewController = window.rootViewController as! FlutterViewController ; + let batteryChannel = FlutterMethodChannel.init(name: "com.proxy/proxyVpn", binaryMessenger: controller as! FlutterBinaryMessenger); + batteryChannel.setMethodCallHandler({ + (call: FlutterMethodCall, result: FlutterResult) -> Void in + if ("stopVpn" == call.method) { + VpnManager.shared.disconnect() + } else { + let arguments = call.arguments as? Dictionary + VpnManager.shared.connect(host: arguments?["proxyHost"] as? String ,port: arguments?["proxyPort"] as? Int) + } + }) + - manager.saveToPreferences {error in - if error != nil{print("vpn erroor" ,error);return;} - } - - return super.application(application, didFinishLaunchingWithOptions: launchOptions) + + return super.application(application, didFinishLaunchingWithOptions: launchOptions) } + + } diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index d36b1fa..728e6c3 100644 --- a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,122 +1,122 @@ { - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" + "images": [ + { + "size": "20x20", + "idiom": "iphone", + "filename": "icon-20@2x.png", + "scale": "2x" + }, + { + "size": "20x20", + "idiom": "iphone", + "filename": "icon-20@3x.png", + "scale": "3x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "icon-29.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "icon-29@2x.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "icon-29@3x.png", + "scale": "3x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "icon-40@2x.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "icon-40@3x.png", + "scale": "3x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "icon-60@2x.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "icon-60@3x.png", + "scale": "3x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "icon-20-ipad.png", + "scale": "1x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "icon-20@2x-ipad.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "icon-29-ipad.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "icon-29@2x-ipad.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "icon-40.png", + "scale": "1x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "icon-40@2x.png", + "scale": "2x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "icon-76.png", + "scale": "1x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "icon-76@2x.png", + "scale": "2x" + }, + { + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "icon-83.5@2x.png", + "scale": "2x" + }, + { + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "icon-1024.png", + "scale": "1x" + } + ], + "info": { + "version": 1, + "author": "icon.wuruihong.com" } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} +} \ No newline at end of file diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 7353c41..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 797d452..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index 6ed2d93..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cd7b00..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index fe73094..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index 321773c..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 797d452..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index 502f463..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index 0ec3034..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index 0ec3034..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index e9f5fea..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index 84ac32a..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 8953cba..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index 0467bf1..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png new file mode 100644 index 0000000..cf4fd63 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png new file mode 100644 index 0000000..657a724 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png new file mode 100644 index 0000000..a247447 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png new file mode 100644 index 0000000..a247447 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png new file mode 100644 index 0000000..4b201aa Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png new file mode 100644 index 0000000..0277354 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png new file mode 100644 index 0000000..0277354 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png new file mode 100644 index 0000000..219a38f Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png new file mode 100644 index 0000000..219a38f Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png new file mode 100644 index 0000000..59c32c4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40.png new file mode 100644 index 0000000..a247447 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png new file mode 100644 index 0000000..1939b70 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png new file mode 100644 index 0000000..c888fbb Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png new file mode 100644 index 0000000..c888fbb Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png new file mode 100644 index 0000000..4871392 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76.png new file mode 100644 index 0000000..b50173b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png new file mode 100644 index 0000000..8513252 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png new file mode 100644 index 0000000..26a922c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png differ diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index 2e6fa19..f3c2851 100644 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -1,10 +1,8 @@ - - - + + - - + @@ -16,14 +14,13 @@ - + - + - diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index b604e47..ccbe8f4 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -15,7 +15,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - network_proxy_flutter + ProxyPin CFBundlePackageType APPL CFBundleShortVersionString @@ -45,6 +45,11 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + UIViewControllerBasedStatusBarAppearance diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 95c1713..70e1d98 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -2,6 +2,22 @@ + com.apple.developer.networking.networkextension + + packet-tunnel-provider + + com.apple.developer.networking.vpn.api + + allow-vpn + + com.apple.security.application-groups + + group.com.proxy.pin + + com.apple.security.network.client + + com.apple.security.network.server + diff --git a/ios/Runner/RunnerDebug.entitlements b/ios/Runner/RunnerDebug.entitlements deleted file mode 100644 index 8261002..0000000 --- a/ios/Runner/RunnerDebug.entitlements +++ /dev/null @@ -1,11 +0,0 @@ - - - - - com.apple.developer.networking.networkextension - - packet-tunnel-provider - - - - diff --git a/ios/Runner/RunnerRelease.entitlements b/ios/Runner/RunnerRelease.entitlements deleted file mode 100644 index 0c67376..0000000 --- a/ios/Runner/RunnerRelease.entitlements +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/ios/Runner/VpnManager.swift b/ios/Runner/VpnManager.swift new file mode 100755 index 0000000..4bea414 --- /dev/null +++ b/ios/Runner/VpnManager.swift @@ -0,0 +1,161 @@ +let kProxyServiceVPNStatusNotification = "kProxyServiceVPNStatusNotification" + +import Foundation +import NetworkExtension + +enum VPNStatus { + case off + case connecting + case on + case disconnecting +} + + +class VpnManager{ + + public var proxtHost: String = "127.0.0.01" + public var proxyPort: Int = 8888 + + static let shared = VpnManager() + var observerAdded: Bool = false + + + fileprivate(set) var vpnStatus = VPNStatus.off { + didSet { + NotificationCenter.default.post(name: Notification.Name(rawValue: kProxyServiceVPNStatusNotification), object: nil) + } + } + + init() { + loadProviderManager{ + guard let manager = $0 else{return} + self.updateVPNStatus(manager) + } + addVPNStatusObserver() + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + func addVPNStatusObserver() { + guard !observerAdded else{ + return + } + loadProviderManager { [unowned self] (manager) -> Void in + if let manager = manager { + self.observerAdded = true + NotificationCenter.default.addObserver(forName: NSNotification.Name.NEVPNStatusDidChange, object: manager.connection, queue: OperationQueue.main, using: { [unowned self] (notification) -> Void in + self.updateVPNStatus(manager) + }) + } + } + } + + + func updateVPNStatus(_ manager: NEVPNManager) { + switch manager.connection.status { + case .connected: + self.vpnStatus = .on + case .connecting, .reasserting: + self.vpnStatus = .connecting + case .disconnecting: + self.vpnStatus = .disconnecting + case .disconnected, .invalid: + self.vpnStatus = .off + @unknown default: break + + } + } +} + +// load VPN Profiles +extension VpnManager{ + + + fileprivate func createProviderManager() -> NETunnelProviderManager { + let manager = NETunnelProviderManager() + let conf = NETunnelProviderProtocol() + conf.serverAddress = "ProxyPin" + manager.protocolConfiguration = conf + manager.localizedDescription = "ProxyPin" + return manager + } + + func loadAndCreatePrividerManager(_ complete: @escaping (NETunnelProviderManager?) -> Void ){ + NETunnelProviderManager.loadAllFromPreferences{ [self] (managers, error) in + guard let managers = managers else{return} + let manager: NETunnelProviderManager + if managers.count > 0 { + manager = managers[0] + }else{ + manager = self.createProviderManager() + } + + var conf = [String:AnyObject]() + conf["proxtHost"] = self.proxtHost as AnyObject + conf["proxyPort"] = self.proxyPort as AnyObject + + let orignConf = manager.protocolConfiguration as! NETunnelProviderProtocol + + orignConf.providerConfiguration = conf + manager.protocolConfiguration = orignConf + + print(orignConf) + manager.isEnabled = true + manager.saveToPreferences{ + if ($0 != nil){ +// complete(nil); +// return; + } + manager.loadFromPreferences{ + if $0 != nil{ + print("loadFromPreferences",$0.debugDescription) + complete(nil);return; + } + self.addVPNStatusObserver() + complete(manager) + } + } + + } + } + + func loadProviderManager(_ complete: @escaping (NETunnelProviderManager?) -> Void){ + NETunnelProviderManager.loadAllFromPreferences { (managers, error) in + if let managers = managers { + if managers.count > 0 { + let manager = managers[0] + complete(manager) + return + } + } + complete(nil) + } + } + +} + +// Actions +extension VpnManager{ + func connect(host: String?, port: Int?){ + self.proxtHost = host ?? self.proxtHost + self.proxyPort = port ?? self.proxyPort + + self.loadAndCreatePrividerManager { (manager) in + guard let manager = manager else{return} + do{ + try manager.connection.startVPNTunnel() + }catch let err{ + print("connect: ", err) + } + } + } + + func disconnect(){ + loadProviderManager{ + $0?.connection.stopVPNTunnel() + } + } + +} diff --git a/lib/network/bin/server.dart b/lib/network/bin/server.dart index a2f036b..1908b1b 100644 --- a/lib/network/bin/server.dart +++ b/lib/network/bin/server.dart @@ -19,7 +19,7 @@ Future main() async { /// 代理服务器 class ProxyServer { - bool init = false; + bool _init = false; int port = 8888; bool _enableSsl = false; @@ -31,6 +31,15 @@ class ProxyServer { bool get enableSsl => _enableSsl; + //初始化 + Future initialize() async { + if (!_init) { + await _loadConfig(); + // 读取配置文件 + _init = true; + } + } + Future homeDir() async { String? userHome; if (Platforms.isDesktop()) { @@ -66,9 +75,9 @@ class ProxyServer { /// 启动代理服务 Future start() async { Server server = Server(); - if (!init) { + if (!_init) { // 读取配置文件 - init = true; + _init = true; await _loadConfig(); } diff --git a/lib/network/util/system_proxy.dart b/lib/network/util/system_proxy.dart index c155f1b..b6bbd8d 100644 --- a/lib/network/util/system_proxy.dart +++ b/lib/network/util/system_proxy.dart @@ -15,6 +15,15 @@ class SystemProxy { } } + static void setSystemProxyEnable(bool enable) async { + if (Platform.isMacOS) { + setProxyEnableMacOS(enable, true); + } else if (Platform.isWindows) { + setProxyEnableWindows(enable); + } + } + + static Future _setProxyServerMacOS(int port, bool enableSsl) async { _hardwarePort = await hardwarePort(); var results = await Process.run('bash', [ @@ -64,7 +73,6 @@ class SystemProxy { 'networksetup -listnetworkserviceorder |grep "Device: $name" -A 1 |grep "Hardware Port" |awk -F ": " \'{print \$2}\'', ]) ]); - print(results); return results.stdout.toString().split(", ")[0]; } diff --git a/lib/ui/desktop/toolbar/setting/setting.dart b/lib/ui/desktop/toolbar/setting/setting.dart index d35c820..cf6b1e1 100644 --- a/lib/ui/desktop/toolbar/setting/setting.dart +++ b/lib/ui/desktop/toolbar/setting/setting.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:network_proxy/network/bin/server.dart'; +import 'package:network_proxy/network/util/system_proxy.dart'; import 'package:network_proxy/ui/desktop/toolbar/setting/request_rewrite.dart'; import 'package:network_proxy/ui/desktop/toolbar/setting/theme.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -17,6 +18,8 @@ class Setting extends StatefulWidget { } class _SettingState extends State { + final ValueNotifier enableDesktopListenable = ValueNotifier(true); + @override Widget build(BuildContext context) { return PopupMenuButton( @@ -26,7 +29,23 @@ class _SettingState extends State { offset: const Offset(10, 30), itemBuilder: (context) { return [ - PopupMenuItem(padding: const EdgeInsets.all(0), child: PortWidget(proxyServer: widget.proxyServer, textStyle: const TextStyle(fontSize: 13))), + PopupMenuItem( + padding: const EdgeInsets.all(0), + child: PortWidget(proxyServer: widget.proxyServer, textStyle: const TextStyle(fontSize: 13))), + PopupMenuItem( + padding: const EdgeInsets.all(0), + child: ValueListenableBuilder( + valueListenable: enableDesktopListenable, + builder: (_, val, __) => SwitchListTile( + hoverColor: Colors.transparent, + title: const Text("启用电脑抓包", style: TextStyle(fontSize: 12)), + visualDensity: const VisualDensity(horizontal: -4), + dense: true, + value: val, + onChanged: (val) { + SystemProxy.setSystemProxyEnable(val); + enableDesktopListenable.value = val; + }))), const PopupMenuItem(padding: EdgeInsets.all(0), child: ThemeSetting(dense: true)), PopupMenuItem( padding: const EdgeInsets.all(0), @@ -51,7 +70,7 @@ class _SettingState extends State { padding: const EdgeInsets.all(0), child: const ListTile(title: Text("Github"), dense: true, trailing: Icon(Icons.arrow_right)), onTap: () { - launchUrl(Uri.parse("https://github.com/wanghongenpin/network-proxy-flutter")); + launchUrl(Uri.parse("https://github.com/wanghongenpin/network_proxy_flutter")); }, ) ]; diff --git a/lib/ui/desktop/toolbar/ssl/ssl.dart b/lib/ui/desktop/toolbar/ssl/ssl.dart index ede2322..f667d83 100644 --- a/lib/ui/desktop/toolbar/ssl/ssl.dart +++ b/lib/ui/desktop/toolbar/ssl/ssl.dart @@ -14,16 +14,17 @@ class SslWidget extends StatefulWidget { } class _SslState extends State { + @override Widget build(BuildContext context) { return PopupMenuButton( - icon: const Icon(Icons.https), + icon: Icon(Icons.https, color: widget.proxyServer.enableSsl ? null : Colors.red), surfaceTintColor: Colors.white70, tooltip: "Https代理", offset: const Offset(10, 30), itemBuilder: (context) { return [ - PopupMenuItem(padding: const EdgeInsets.all(0), child: _Switch(proxyServer: widget.proxyServer)), + PopupMenuItem(padding: const EdgeInsets.all(0), child: _Switch(proxyServer: widget.proxyServer, onEnableChange: (val) => setState(() {}))), PopupMenuItem( padding: const EdgeInsets.all(0), child: ListTile( @@ -47,10 +48,7 @@ class _SslState extends State { onTap: () async { mobileCer(await localIp()); }), - ), - // const PopupMenuItem( - // child: ListTile(title: Text("安装根证书到Android"), dense: true, trailing: Icon(Icons.arrow_right)), - // ) + ) ]; }, ); @@ -117,8 +115,9 @@ class _SslState extends State { class _Switch extends StatefulWidget { final ProxyServer proxyServer; + final Function(bool val) onEnableChange; - const _Switch({Key? key, required this.proxyServer}) : super(key: key); + const _Switch({Key? key, required this.proxyServer, required this.onEnableChange}) : super(key: key); @override State<_Switch> createState() => _SwitchState(); @@ -138,6 +137,7 @@ class _SwitchState extends State<_Switch> { onChanged: (val) { widget.proxyServer.enableSsl = val; changed = true; + widget.onEnableChange(val); setState(() {}); }); } diff --git a/lib/ui/desktop/toolbar/toolbar.dart b/lib/ui/desktop/toolbar/toolbar.dart index 73406ad..e9bfa2d 100644 --- a/lib/ui/desktop/toolbar/toolbar.dart +++ b/lib/ui/desktop/toolbar/toolbar.dart @@ -23,10 +23,13 @@ class Toolbar extends StatefulWidget { } class _ToolbarState extends State { + final ValueNotifier sllEnableListenable = ValueNotifier(true); + @override void initState() { super.initState(); RawKeyboard.instance.addListener(onKeyEvent); + widget.proxyServer.initialize().then((value) => sllEnableListenable.value = widget.proxyServer.enableSsl); } void onKeyEvent(RawKeyEvent event) { @@ -41,12 +44,12 @@ class _ToolbarState extends State { windowManager.blur(); return; } + if (event.isKeyPressed(LogicalKeyboardKey.metaLeft) && event.isKeyPressed(LogicalKeyboardKey.keyQ)) { - print(" windowManager.close()"); + print("windowManager.close()"); windowManager.close(); return; } - } @override @@ -69,7 +72,9 @@ class _ToolbarState extends State { widget.domainStateKey.currentState?.clean(); }), const Padding(padding: EdgeInsets.only(left: 30)), - SslWidget(proxyServer: widget.proxyServer), + ValueListenableBuilder( + valueListenable: sllEnableListenable, + builder: (_, value, __) => SslWidget(proxyServer: widget.proxyServer)), const Padding(padding: EdgeInsets.only(left: 30)), Setting(proxyServer: widget.proxyServer), ], diff --git a/lib/ui/mobile/mobile.dart b/lib/ui/mobile/mobile.dart index df30906..3a301be 100644 --- a/lib/ui/mobile/mobile.dart +++ b/lib/ui/mobile/mobile.dart @@ -26,6 +26,7 @@ class MobileHomePage extends StatefulWidget { class MobileHomeState extends State implements EventListener { static const MethodChannel proxyVpnChannel = MethodChannel('com.proxy/proxyVpn'); + final ValueNotifier sllEnableListenable = ValueNotifier(true); late ProxyServer proxyServer; final requestStateKey = GlobalKey(); @@ -43,9 +44,16 @@ class MobileHomeState extends State implements EventListener { @override void initState() { proxyServer = ProxyServer(listener: this); + proxyServer.initialize().then((value) => sllEnableListenable.value = proxyServer.enableSsl); super.initState(); } + @override + void dispose() { + sllEnableListenable.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -54,16 +62,19 @@ class MobileHomeState extends State implements EventListener { tooltip: "清理", icon: const Icon(Icons.cleaning_services_outlined), onPressed: () => requestStateKey.currentState?.clean()), - IconButton( - tooltip: "Https代理", - icon: const Icon(Icons.https), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute(builder: (BuildContext context) { - return MobileSslWidget(proxyServer: proxyServer); - }), - ); - }) + ValueListenableBuilder( + valueListenable: sllEnableListenable, + builder: (_, bool enabled, __) => IconButton( + tooltip: "Https代理", + icon: Icon(Icons.https, color: enabled ? null : Colors.red), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute(builder: (BuildContext context) { + return MobileSslWidget( + proxyServer: proxyServer, onEnableChange: (val) => sllEnableListenable.value = val); + }), + ); + })) ]), drawer: drawer(), floatingActionButton: FloatingActionButton( @@ -101,9 +112,13 @@ class MobileHomeState extends State implements EventListener { trailing: const Icon(Icons.arrow_right), onTap: () => _filter(HostFilter.blacklist)), ListTile(title: const Text("请求重写"), trailing: const Icon(Icons.arrow_right), onTap: () => _reqeustRewrite()), - ListTile(title: const Text("Github"), trailing: const Icon(Icons.arrow_right), onTap: () { - launchUrl(Uri.parse("https://github.com/wanghongenpin/network-proxy-flutter"), mode: LaunchMode.externalApplication); - }) + ListTile( + title: const Text("Github"), + trailing: const Icon(Icons.arrow_right), + onTap: () { + launchUrl(Uri.parse("https://github.com/wanghongenpin/network_proxy_flutter"), + mode: LaunchMode.externalApplication); + }) ], )); } diff --git a/lib/ui/mobile/request.dart b/lib/ui/mobile/request.dart index 2228b47..b605cd1 100644 --- a/lib/ui/mobile/request.dart +++ b/lib/ui/mobile/request.dart @@ -213,6 +213,7 @@ class DomainListState extends State { Map> containerMap = {}; LinkedHashSet container = LinkedHashSet(); + List list = []; HostAndPort? showHostAndPort; @override @@ -228,10 +229,13 @@ class DomainListState extends State { } list.add(request); } + + list = container.toList(); } add(HttpRequest request) { var hostAndPort = request.hostAndPort!; + container.remove(hostAndPort); container.add(hostAndPort); var list = containerMap[hostAndPort]; if (list == null) { @@ -243,6 +247,7 @@ class DomainListState extends State { requestSequenceKey.currentState?.add(request); } + this.list = [...container].reversed.toList(); setState(() {}); } @@ -261,22 +266,23 @@ class DomainListState extends State { @override Widget build(BuildContext context) { - return ListView.builder( - itemCount: container.length, + return ListView.separated( + separatorBuilder: (context, index) => Divider(height: 0.5, color: Theme.of(context).focusColor), + itemCount: list.length, itemBuilder: (context, index) { var time = formatDate( - containerMap[container.elementAt(index)]!.last.requestTime, [m, '/', d, ' ', HH, ':', nn, ':', ss]); + containerMap[list.elementAt(index)]!.last.requestTime, [m, '/', d, ' ', HH, ':', nn, ':', ss]); return ListTile( - title: Text(container.elementAt(index).url, maxLines: 1, overflow: TextOverflow.ellipsis), + title: Text(list.elementAt(index).url, maxLines: 1, overflow: TextOverflow.ellipsis), trailing: const Icon(Icons.chevron_right), - subtitle: Text("最后请求时间: $time, 次数: ${containerMap[container.elementAt(index)]!.length}", + subtitle: Text("最后请求时间: $time, 次数: ${containerMap[list.elementAt(index)]!.length}", maxLines: 1, overflow: TextOverflow.ellipsis), onTap: () { Navigator.push(context, MaterialPageRoute(builder: (context) { - showHostAndPort = container.elementAt(index); + showHostAndPort = list.elementAt(index); return Scaffold( appBar: AppBar(title: const Text("请求列表")), - body: RequestSequence(key: requestSequenceKey, list: containerMap[container.elementAt(index)]!)); + body: RequestSequence(key: requestSequenceKey, list: containerMap[list.elementAt(index)]!)); })); }); }); diff --git a/lib/ui/mobile/ssl.dart b/lib/ui/mobile/ssl.dart index 5c5ba9b..8ecde2b 100644 --- a/lib/ui/mobile/ssl.dart +++ b/lib/ui/mobile/ssl.dart @@ -4,14 +4,25 @@ import 'package:url_launcher/url_launcher.dart'; class MobileSslWidget extends StatefulWidget { final ProxyServer proxyServer; + final Function(bool val) onEnableChange; - const MobileSslWidget({super.key, required this.proxyServer}); + const MobileSslWidget({super.key, required this.proxyServer, required this.onEnableChange}); @override State createState() => _MobileSslState(); } class _MobileSslState extends State { + bool changed = false; + + @override + void dispose() { + super.dispose(); + if (changed) { + widget.proxyServer.flushConfig(); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -20,7 +31,16 @@ class _MobileSslState extends State { centerTitle: true, ), body: Column(children: [ - _Switch(proxyServer: widget.proxyServer), + SwitchListTile( + hoverColor: Colors.transparent, + title: const Text("启用Https代理", style: TextStyle(fontSize: 16)), + value: widget.proxyServer.enableSsl, + onChanged: (val) { + widget.proxyServer.enableSsl = val; + widget.onEnableChange(val); + changed = true; + setState(() {}); + }), ExpansionTile( title: const Text("安装根证书"), initiallyExpanded: true, @@ -39,37 +59,3 @@ class _MobileSslState extends State { launchUrl(Uri.parse("http://127.0.0.1:${widget.proxyServer.port}/ssl"), mode: LaunchMode.externalApplication); } } - -class _Switch extends StatefulWidget { - final ProxyServer proxyServer; - - const _Switch({Key? key, required this.proxyServer}) : super(key: key); - - @override - State<_Switch> createState() => _SwitchState(); -} - -class _SwitchState extends State<_Switch> { - bool changed = false; - - @override - Widget build(BuildContext context) { - return SwitchListTile( - hoverColor: Colors.transparent, - title: const Text("启用Https代理", style: TextStyle(fontSize: 16)), - value: widget.proxyServer.enableSsl, - onChanged: (val) { - widget.proxyServer.enableSsl = val; - changed = true; - setState(() {}); - }); - } - - @override - void dispose() { - super.dispose(); - if (changed) { - widget.proxyServer.flushConfig(); - } - } -}