Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e65d84b6ab | ||
|
|
36cb499bf8 | ||
|
|
f78146f48d | ||
|
|
34ffd33316 | ||
|
|
e0158845d3 | ||
|
|
1e8101a699 | ||
|
|
dabbe10a2c | ||
|
|
92560bc48d | ||
|
|
3607fa9564 | ||
|
|
dfa368cff2 | ||
|
|
e54d69ef4b | ||
|
|
be8269ad56 | ||
|
|
7118ec3b02 | ||
|
|
71045bf0dd | ||
|
|
27abdd66f5 | ||
|
|
162e18c912 | ||
|
|
d68e4ec869 | ||
|
|
762263bfbd |
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
GlassVPN/SwiftSocket/** linguist-vendored
|
||||
GlassVPN/robbiehanson-CocoaAsyncSocket/** linguist-vendored
|
||||
GlassVPN/zhuhaow-NEKit/** linguist-vendored
|
||||
GlassVPN/zhuhaow-Resolver/** linguist-vendored
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -4,4 +4,6 @@ build/
|
||||
DerivedData/
|
||||
|
||||
Carthage/Checkouts
|
||||
Carthage/Build
|
||||
Carthage/Build
|
||||
|
||||
.DS_Store
|
||||
|
||||
@@ -104,10 +104,8 @@
|
||||
54CA01D52426B252003A5E04 /* SafeDict.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01D42426B251003A5E04 /* SafeDict.swift */; };
|
||||
54CA025C2426B2FD003A5E04 /* ConnectSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01E22426B2FC003A5E04 /* ConnectSession.swift */; };
|
||||
54CA025D2426B2FD003A5E04 /* HTTPHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01E32426B2FC003A5E04 /* HTTPHeader.swift */; };
|
||||
54CA025E2426B2FD003A5E04 /* ResponseGeneratorFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01E42426B2FC003A5E04 /* ResponseGeneratorFactory.swift */; };
|
||||
54CA025F2426B2FD003A5E04 /* ProxyServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01E62426B2FC003A5E04 /* ProxyServer.swift */; };
|
||||
54CA02602426B2FD003A5E04 /* GCDProxyServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01E72426B2FC003A5E04 /* GCDProxyServer.swift */; };
|
||||
54CA02612426B2FD003A5E04 /* GCDSOCKS5ProxyServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01E82426B2FC003A5E04 /* GCDSOCKS5ProxyServer.swift */; };
|
||||
54CA02622426B2FD003A5E04 /* GCDHTTPProxyServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01E92426B2FC003A5E04 /* GCDHTTPProxyServer.swift */; };
|
||||
54CA02662426B2FD003A5E04 /* NWUDPSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01EF2426B2FC003A5E04 /* NWUDPSocket.swift */; };
|
||||
54CA02672426B2FD003A5E04 /* RawTCPSocketProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA01F02426B2FC003A5E04 /* RawTCPSocketProtocol.swift */; };
|
||||
@@ -129,15 +127,8 @@
|
||||
54CA027B2426B2FD003A5E04 /* HTTPAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02062426B2FC003A5E04 /* HTTPAuthentication.swift */; };
|
||||
54CA027C2426B2FD003A5E04 /* StreamScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02072426B2FC003A5E04 /* StreamScanner.swift */; };
|
||||
54CA027D2426B2FD003A5E04 /* GlobalIntializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02082426B2FC003A5E04 /* GlobalIntializer.swift */; };
|
||||
54CA027E2426B2FD003A5E04 /* DomainListRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA020A2426B2FC003A5E04 /* DomainListRule.swift */; };
|
||||
54CA02802426B2FD003A5E04 /* DNSSessionMatchType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA020C2426B2FC003A5E04 /* DNSSessionMatchType.swift */; };
|
||||
54CA02812426B2FD003A5E04 /* DNSFailRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA020D2426B2FC003A5E04 /* DNSFailRule.swift */; };
|
||||
54CA02822426B2FD003A5E04 /* AllRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA020E2426B2FC003A5E04 /* AllRule.swift */; };
|
||||
54CA02832426B2FD003A5E04 /* DNSSessionMatchResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA020F2426B2FC003A5E04 /* DNSSessionMatchResult.swift */; };
|
||||
54CA02842426B2FD003A5E04 /* Rule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02102426B2FC003A5E04 /* Rule.swift */; };
|
||||
54CA02852426B2FD003A5E04 /* DirectRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02112426B2FC003A5E04 /* DirectRule.swift */; };
|
||||
54CA02862426B2FD003A5E04 /* RuleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02122426B2FC003A5E04 /* RuleManager.swift */; };
|
||||
54CA02872426B2FD003A5E04 /* IPRangeListRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02132426B2FC003A5E04 /* IPRangeListRule.swift */; };
|
||||
54CA02882426B2FD003A5E04 /* QueueFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02152426B2FC003A5E04 /* QueueFactory.swift */; };
|
||||
54CA02892426B2FD003A5E04 /* Tunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02162426B2FC003A5E04 /* Tunnel.swift */; };
|
||||
54CA028A2426B2FD003A5E04 /* ResponseGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02172426B2FC003A5E04 /* ResponseGenerator.swift */; };
|
||||
@@ -156,26 +147,12 @@
|
||||
54CA029E2426B2FD003A5E04 /* EventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02302426B2FC003A5E04 /* EventType.swift */; };
|
||||
54CA029F2426B2FD003A5E04 /* ProxySocketEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02312426B2FC003A5E04 /* ProxySocketEvent.swift */; };
|
||||
54CA02A02426B2FD003A5E04 /* TunnelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02322426B2FC003A5E04 /* TunnelEvent.swift */; };
|
||||
54CA02A12426B2FD003A5E04 /* RuleMatchEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02332426B2FC003A5E04 /* RuleMatchEvent.swift */; };
|
||||
54CA02A22426B2FD003A5E04 /* ObserverFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02342426B2FC003A5E04 /* ObserverFactory.swift */; };
|
||||
54CA02A32426B2FD003A5E04 /* HTTPAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02372426B2FC003A5E04 /* HTTPAdapter.swift */; };
|
||||
54CA02A42426B2FD003A5E04 /* SecureHTTPAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02382426B2FC003A5E04 /* SecureHTTPAdapter.swift */; };
|
||||
54CA02A62426B2FD003A5E04 /* AdapterSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA023A2426B2FC003A5E04 /* AdapterSocket.swift */; };
|
||||
54CA02A72426B2FD003A5E04 /* DirectAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA023B2426B2FC003A5E04 /* DirectAdapter.swift */; };
|
||||
54CA02A82426B2FD003A5E04 /* SOCKS5Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA023C2426B2FC003A5E04 /* SOCKS5Adapter.swift */; };
|
||||
54CA02A92426B2FD003A5E04 /* RejectAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA023D2426B2FC003A5E04 /* RejectAdapter.swift */; };
|
||||
54CA02AC2426B2FD003A5E04 /* AuthenticationServerAdapterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02412426B2FC003A5E04 /* AuthenticationServerAdapterFactory.swift */; };
|
||||
54CA02AD2426B2FD003A5E04 /* RejectAdapterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02422426B2FC003A5E04 /* RejectAdapterFactory.swift */; };
|
||||
54CA02AE2426B2FD003A5E04 /* AdapterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02432426B2FD003A5E04 /* AdapterFactory.swift */; };
|
||||
54CA02AF2426B2FD003A5E04 /* SOCKS5AdapterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02442426B2FD003A5E04 /* SOCKS5AdapterFactory.swift */; };
|
||||
54CA02B02426B2FD003A5E04 /* SecureHTTPAdapterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02452426B2FD003A5E04 /* SecureHTTPAdapterFactory.swift */; };
|
||||
54CA02B12426B2FD003A5E04 /* ServerAdapterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02462426B2FD003A5E04 /* ServerAdapterFactory.swift */; };
|
||||
54CA02B22426B2FD003A5E04 /* AdapterFactoryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02472426B2FD003A5E04 /* AdapterFactoryManager.swift */; };
|
||||
54CA02B32426B2FD003A5E04 /* HTTPAdapterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02482426B2FD003A5E04 /* HTTPAdapterFactory.swift */; };
|
||||
54CA02B82426B2FD003A5E04 /* HTTPProxySocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA024F2426B2FD003A5E04 /* HTTPProxySocket.swift */; };
|
||||
54CA02B92426B2FD003A5E04 /* DirectProxySocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02502426B2FD003A5E04 /* DirectProxySocket.swift */; };
|
||||
54CA02BA2426B2FD003A5E04 /* ProxySocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02512426B2FD003A5E04 /* ProxySocket.swift */; };
|
||||
54CA02BB2426B2FD003A5E04 /* SOCKS5ProxySocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02522426B2FD003A5E04 /* SOCKS5ProxySocket.swift */; };
|
||||
54CA02BC2426B2FD003A5E04 /* SocketProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02532426B2FD003A5E04 /* SocketProtocol.swift */; };
|
||||
54CA02BE2426D4F3003A5E04 /* DDLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02BD2426D4F3003A5E04 /* DDLog.swift */; };
|
||||
54CA02C32426DCCD003A5E04 /* GCDAsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 54CA02BF2426DCCC003A5E04 /* GCDAsyncSocket.m */; };
|
||||
@@ -241,7 +218,7 @@
|
||||
5412FCC024C628F9000DE429 /* TVCChooseAlertTone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TVCChooseAlertTone.swift; sourceTree = "<group>"; };
|
||||
5412FCC124C628FA000DE429 /* TVCConnectionAlerts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TVCConnectionAlerts.swift; sourceTree = "<group>"; };
|
||||
541A957523E602DF00C09C19 /* LaunchIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = LaunchIcon.png; sourceTree = "<group>"; };
|
||||
541AC5D42399498A00A769D7 /* AppCheck.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppCheck.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
541AC5D42399498A00A769D7 /* AppChk.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppChk.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
541AC5D72399498A00A769D7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
541AC5DC2399498A00A769D7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
541AC5DE2399498B00A769D7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
@@ -313,10 +290,8 @@
|
||||
54CA01D42426B251003A5E04 /* SafeDict.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SafeDict.swift; sourceTree = "<group>"; };
|
||||
54CA01E22426B2FC003A5E04 /* ConnectSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectSession.swift; sourceTree = "<group>"; };
|
||||
54CA01E32426B2FC003A5E04 /* HTTPHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPHeader.swift; sourceTree = "<group>"; };
|
||||
54CA01E42426B2FC003A5E04 /* ResponseGeneratorFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResponseGeneratorFactory.swift; sourceTree = "<group>"; };
|
||||
54CA01E62426B2FC003A5E04 /* ProxyServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxyServer.swift; sourceTree = "<group>"; };
|
||||
54CA01E72426B2FC003A5E04 /* GCDProxyServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GCDProxyServer.swift; sourceTree = "<group>"; };
|
||||
54CA01E82426B2FC003A5E04 /* GCDSOCKS5ProxyServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GCDSOCKS5ProxyServer.swift; sourceTree = "<group>"; };
|
||||
54CA01E92426B2FC003A5E04 /* GCDHTTPProxyServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GCDHTTPProxyServer.swift; sourceTree = "<group>"; };
|
||||
54CA01EF2426B2FC003A5E04 /* NWUDPSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NWUDPSocket.swift; sourceTree = "<group>"; };
|
||||
54CA01F02426B2FC003A5E04 /* RawTCPSocketProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawTCPSocketProtocol.swift; sourceTree = "<group>"; };
|
||||
@@ -338,15 +313,8 @@
|
||||
54CA02062426B2FC003A5E04 /* HTTPAuthentication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPAuthentication.swift; sourceTree = "<group>"; };
|
||||
54CA02072426B2FC003A5E04 /* StreamScanner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StreamScanner.swift; sourceTree = "<group>"; };
|
||||
54CA02082426B2FC003A5E04 /* GlobalIntializer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalIntializer.swift; sourceTree = "<group>"; };
|
||||
54CA020A2426B2FC003A5E04 /* DomainListRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListRule.swift; sourceTree = "<group>"; };
|
||||
54CA020C2426B2FC003A5E04 /* DNSSessionMatchType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DNSSessionMatchType.swift; sourceTree = "<group>"; };
|
||||
54CA020D2426B2FC003A5E04 /* DNSFailRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DNSFailRule.swift; sourceTree = "<group>"; };
|
||||
54CA020E2426B2FC003A5E04 /* AllRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AllRule.swift; sourceTree = "<group>"; };
|
||||
54CA020F2426B2FC003A5E04 /* DNSSessionMatchResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DNSSessionMatchResult.swift; sourceTree = "<group>"; };
|
||||
54CA02102426B2FC003A5E04 /* Rule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Rule.swift; sourceTree = "<group>"; };
|
||||
54CA02112426B2FC003A5E04 /* DirectRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DirectRule.swift; sourceTree = "<group>"; };
|
||||
54CA02122426B2FC003A5E04 /* RuleManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuleManager.swift; sourceTree = "<group>"; };
|
||||
54CA02132426B2FC003A5E04 /* IPRangeListRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IPRangeListRule.swift; sourceTree = "<group>"; };
|
||||
54CA02152426B2FC003A5E04 /* QueueFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueueFactory.swift; sourceTree = "<group>"; };
|
||||
54CA02162426B2FC003A5E04 /* Tunnel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tunnel.swift; sourceTree = "<group>"; };
|
||||
54CA02172426B2FC003A5E04 /* ResponseGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResponseGenerator.swift; sourceTree = "<group>"; };
|
||||
@@ -365,26 +333,12 @@
|
||||
54CA02302426B2FC003A5E04 /* EventType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventType.swift; sourceTree = "<group>"; };
|
||||
54CA02312426B2FC003A5E04 /* ProxySocketEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxySocketEvent.swift; sourceTree = "<group>"; };
|
||||
54CA02322426B2FC003A5E04 /* TunnelEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelEvent.swift; sourceTree = "<group>"; };
|
||||
54CA02332426B2FC003A5E04 /* RuleMatchEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuleMatchEvent.swift; sourceTree = "<group>"; };
|
||||
54CA02342426B2FC003A5E04 /* ObserverFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverFactory.swift; sourceTree = "<group>"; };
|
||||
54CA02372426B2FC003A5E04 /* HTTPAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPAdapter.swift; sourceTree = "<group>"; };
|
||||
54CA02382426B2FC003A5E04 /* SecureHTTPAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecureHTTPAdapter.swift; sourceTree = "<group>"; };
|
||||
54CA023A2426B2FC003A5E04 /* AdapterSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdapterSocket.swift; sourceTree = "<group>"; };
|
||||
54CA023B2426B2FC003A5E04 /* DirectAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DirectAdapter.swift; sourceTree = "<group>"; };
|
||||
54CA023C2426B2FC003A5E04 /* SOCKS5Adapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SOCKS5Adapter.swift; sourceTree = "<group>"; };
|
||||
54CA023D2426B2FC003A5E04 /* RejectAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RejectAdapter.swift; sourceTree = "<group>"; };
|
||||
54CA02412426B2FC003A5E04 /* AuthenticationServerAdapterFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationServerAdapterFactory.swift; sourceTree = "<group>"; };
|
||||
54CA02422426B2FC003A5E04 /* RejectAdapterFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RejectAdapterFactory.swift; sourceTree = "<group>"; };
|
||||
54CA02432426B2FD003A5E04 /* AdapterFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdapterFactory.swift; sourceTree = "<group>"; };
|
||||
54CA02442426B2FD003A5E04 /* SOCKS5AdapterFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SOCKS5AdapterFactory.swift; sourceTree = "<group>"; };
|
||||
54CA02452426B2FD003A5E04 /* SecureHTTPAdapterFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecureHTTPAdapterFactory.swift; sourceTree = "<group>"; };
|
||||
54CA02462426B2FD003A5E04 /* ServerAdapterFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServerAdapterFactory.swift; sourceTree = "<group>"; };
|
||||
54CA02472426B2FD003A5E04 /* AdapterFactoryManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdapterFactoryManager.swift; sourceTree = "<group>"; };
|
||||
54CA02482426B2FD003A5E04 /* HTTPAdapterFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPAdapterFactory.swift; sourceTree = "<group>"; };
|
||||
54CA024F2426B2FD003A5E04 /* HTTPProxySocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPProxySocket.swift; sourceTree = "<group>"; };
|
||||
54CA02502426B2FD003A5E04 /* DirectProxySocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DirectProxySocket.swift; sourceTree = "<group>"; };
|
||||
54CA02512426B2FD003A5E04 /* ProxySocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxySocket.swift; sourceTree = "<group>"; };
|
||||
54CA02522426B2FD003A5E04 /* SOCKS5ProxySocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SOCKS5ProxySocket.swift; sourceTree = "<group>"; };
|
||||
54CA02532426B2FD003A5E04 /* SocketProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketProtocol.swift; sourceTree = "<group>"; };
|
||||
54CA02BD2426D4F3003A5E04 /* DDLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DDLog.swift; sourceTree = "<group>"; };
|
||||
54CA02BF2426DCCC003A5E04 /* GCDAsyncSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDAsyncSocket.m; sourceTree = "<group>"; };
|
||||
@@ -492,7 +446,7 @@
|
||||
541AC5D52399498A00A769D7 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
541AC5D42399498A00A769D7 /* AppCheck.app */,
|
||||
541AC5D42399498A00A769D7 /* AppChk.app */,
|
||||
543CDB1D23EEE61900B7F323 /* GlassVPN.appex */,
|
||||
);
|
||||
name = Products;
|
||||
@@ -685,7 +639,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
54CA01E12426B2FC003A5E04 /* Messages */,
|
||||
54CA01E42426B2FC003A5E04 /* ResponseGeneratorFactory.swift */,
|
||||
54CA01E52426B2FC003A5E04 /* ProxyServer */,
|
||||
54CA01EE2426B2FC003A5E04 /* RawSocket */,
|
||||
54CA01F72426B2FC003A5E04 /* Opt.swift */,
|
||||
@@ -716,7 +669,6 @@
|
||||
children = (
|
||||
54CA01E62426B2FC003A5E04 /* ProxyServer.swift */,
|
||||
54CA01E72426B2FC003A5E04 /* GCDProxyServer.swift */,
|
||||
54CA01E82426B2FC003A5E04 /* GCDSOCKS5ProxyServer.swift */,
|
||||
54CA01E92426B2FC003A5E04 /* GCDHTTPProxyServer.swift */,
|
||||
);
|
||||
path = ProxyServer;
|
||||
@@ -757,15 +709,8 @@
|
||||
54CA02092426B2FC003A5E04 /* Rule */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
54CA020A2426B2FC003A5E04 /* DomainListRule.swift */,
|
||||
54CA020C2426B2FC003A5E04 /* DNSSessionMatchType.swift */,
|
||||
54CA020D2426B2FC003A5E04 /* DNSFailRule.swift */,
|
||||
54CA020E2426B2FC003A5E04 /* AllRule.swift */,
|
||||
54CA020F2426B2FC003A5E04 /* DNSSessionMatchResult.swift */,
|
||||
54CA02102426B2FC003A5E04 /* Rule.swift */,
|
||||
54CA02112426B2FC003A5E04 /* DirectRule.swift */,
|
||||
54CA02122426B2FC003A5E04 /* RuleManager.swift */,
|
||||
54CA02132426B2FC003A5E04 /* IPRangeListRule.swift */,
|
||||
);
|
||||
path = Rule;
|
||||
sourceTree = "<group>";
|
||||
@@ -828,7 +773,6 @@
|
||||
54CA02302426B2FC003A5E04 /* EventType.swift */,
|
||||
54CA02312426B2FC003A5E04 /* ProxySocketEvent.swift */,
|
||||
54CA02322426B2FC003A5E04 /* TunnelEvent.swift */,
|
||||
54CA02332426B2FC003A5E04 /* RuleMatchEvent.swift */,
|
||||
);
|
||||
path = Event;
|
||||
sourceTree = "<group>";
|
||||
@@ -846,12 +790,8 @@
|
||||
54CA02362426B2FC003A5E04 /* AdapterSocket */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
54CA02372426B2FC003A5E04 /* HTTPAdapter.swift */,
|
||||
54CA02382426B2FC003A5E04 /* SecureHTTPAdapter.swift */,
|
||||
54CA023A2426B2FC003A5E04 /* AdapterSocket.swift */,
|
||||
54CA023B2426B2FC003A5E04 /* DirectAdapter.swift */,
|
||||
54CA023C2426B2FC003A5E04 /* SOCKS5Adapter.swift */,
|
||||
54CA023D2426B2FC003A5E04 /* RejectAdapter.swift */,
|
||||
54CA023E2426B2FC003A5E04 /* Factory */,
|
||||
);
|
||||
path = AdapterSocket;
|
||||
@@ -860,14 +800,7 @@
|
||||
54CA023E2426B2FC003A5E04 /* Factory */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
54CA02412426B2FC003A5E04 /* AuthenticationServerAdapterFactory.swift */,
|
||||
54CA02422426B2FC003A5E04 /* RejectAdapterFactory.swift */,
|
||||
54CA02432426B2FD003A5E04 /* AdapterFactory.swift */,
|
||||
54CA02442426B2FD003A5E04 /* SOCKS5AdapterFactory.swift */,
|
||||
54CA02452426B2FD003A5E04 /* SecureHTTPAdapterFactory.swift */,
|
||||
54CA02462426B2FD003A5E04 /* ServerAdapterFactory.swift */,
|
||||
54CA02472426B2FD003A5E04 /* AdapterFactoryManager.swift */,
|
||||
54CA02482426B2FD003A5E04 /* HTTPAdapterFactory.swift */,
|
||||
);
|
||||
path = Factory;
|
||||
sourceTree = "<group>";
|
||||
@@ -876,9 +809,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
54CA024F2426B2FD003A5E04 /* HTTPProxySocket.swift */,
|
||||
54CA02502426B2FD003A5E04 /* DirectProxySocket.swift */,
|
||||
54CA02512426B2FD003A5E04 /* ProxySocket.swift */,
|
||||
54CA02522426B2FD003A5E04 /* SOCKS5ProxySocket.swift */,
|
||||
);
|
||||
path = ProxySocket;
|
||||
sourceTree = "<group>";
|
||||
@@ -898,9 +829,9 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
541AC5D32399498A00A769D7 /* AppCheck */ = {
|
||||
541AC5D32399498A00A769D7 /* AppChk */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 541AC5E62399498B00A769D7 /* Build configuration list for PBXNativeTarget "AppCheck" */;
|
||||
buildConfigurationList = 541AC5E62399498B00A769D7 /* Build configuration list for PBXNativeTarget "AppChk" */;
|
||||
buildPhases = (
|
||||
541AC5D02399498A00A769D7 /* Sources */,
|
||||
541AC5D12399498A00A769D7 /* Frameworks */,
|
||||
@@ -912,11 +843,11 @@
|
||||
dependencies = (
|
||||
543CDB2423EEE61900B7F323 /* PBXTargetDependency */,
|
||||
);
|
||||
name = AppCheck;
|
||||
name = AppChk;
|
||||
packageProductDependencies = (
|
||||
);
|
||||
productName = PrivacyScore;
|
||||
productReference = 541AC5D42399498A00A769D7 /* AppCheck.app */;
|
||||
productReference = 541AC5D42399498A00A769D7 /* AppChk.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
543CDB1C23EEE61900B7F323 /* GlassVPN */ = {
|
||||
@@ -945,7 +876,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1130;
|
||||
LastUpgradeCheck = 1010;
|
||||
LastUpgradeCheck = 1250;
|
||||
ORGANIZATIONNAME = relikd;
|
||||
TargetAttributes = {
|
||||
541AC5D32399498A00A769D7 = {
|
||||
@@ -963,7 +894,7 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 541AC5CF2399498A00A769D7 /* Build configuration list for PBXProject "AppCheck" */;
|
||||
buildConfigurationList = 541AC5CF2399498A00A769D7 /* Build configuration list for PBXProject "AppChk" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
@@ -978,7 +909,7 @@
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
541AC5D32399498A00A769D7 /* AppCheck */,
|
||||
541AC5D32399498A00A769D7 /* AppChk */,
|
||||
543CDB1C23EEE61900B7F323 /* GlassVPN */,
|
||||
);
|
||||
};
|
||||
@@ -1118,7 +1049,6 @@
|
||||
54CA027A2426B2FD003A5E04 /* HTTPURL.swift in Sources */,
|
||||
54CA025D2426B2FD003A5E04 /* HTTPHeader.swift in Sources */,
|
||||
54CA02832426B2FD003A5E04 /* DNSSessionMatchResult.swift in Sources */,
|
||||
54CA02862426B2FD003A5E04 /* RuleManager.swift in Sources */,
|
||||
54CA02B82426B2FD003A5E04 /* HTTPProxySocket.swift in Sources */,
|
||||
54CA02C32426DCCD003A5E04 /* GCDAsyncSocket.m in Sources */,
|
||||
54CA02752426B2FD003A5E04 /* IPRange.swift in Sources */,
|
||||
@@ -1128,27 +1058,21 @@
|
||||
5404AEEB24A90717003B2F54 /* PrefsShared.swift in Sources */,
|
||||
54CA02C42426DCCD003A5E04 /* GCDAsyncUdpSocket.m in Sources */,
|
||||
54CA02BA2426B2FD003A5E04 /* ProxySocket.swift in Sources */,
|
||||
54CA025E2426B2FD003A5E04 /* ResponseGeneratorFactory.swift in Sources */,
|
||||
54CA02892426B2FD003A5E04 /* Tunnel.swift in Sources */,
|
||||
54CA029F2426B2FD003A5E04 /* ProxySocketEvent.swift in Sources */,
|
||||
54CA027D2426B2FD003A5E04 /* GlobalIntializer.swift in Sources */,
|
||||
54CA026F2426B2FD003A5E04 /* Port.swift in Sources */,
|
||||
54CA028A2426B2FD003A5E04 /* ResponseGenerator.swift in Sources */,
|
||||
54CA027C2426B2FD003A5E04 /* StreamScanner.swift in Sources */,
|
||||
54CA02AF2426B2FD003A5E04 /* SOCKS5AdapterFactory.swift in Sources */,
|
||||
54CA029E2426B2FD003A5E04 /* EventType.swift in Sources */,
|
||||
54CA02912426B2FD003A5E04 /* DNSMessage.swift in Sources */,
|
||||
54CA02712426B2FD003A5E04 /* UInt128.swift in Sources */,
|
||||
54CA02882426B2FD003A5E04 /* QueueFactory.swift in Sources */,
|
||||
54CA02A12426B2FD003A5E04 /* RuleMatchEvent.swift in Sources */,
|
||||
54CA02BE2426D4F3003A5E04 /* DDLog.swift in Sources */,
|
||||
54CA02962426B2FD003A5E04 /* PacketProtocolParser.swift in Sources */,
|
||||
54CA02932426B2FD003A5E04 /* DNSServer.swift in Sources */,
|
||||
54CA02B22426B2FD003A5E04 /* AdapterFactoryManager.swift in Sources */,
|
||||
54CA02AE2426B2FD003A5E04 /* AdapterFactory.swift in Sources */,
|
||||
54CA02A82426B2FD003A5E04 /* SOCKS5Adapter.swift in Sources */,
|
||||
54CA02792426B2FD003A5E04 /* Checksum.swift in Sources */,
|
||||
54CA02AD2426B2FD003A5E04 /* RejectAdapterFactory.swift in Sources */,
|
||||
541075D224CDBA0000D6F1BF /* ThrottledBatchQueue.swift in Sources */,
|
||||
54CA02672426B2FD003A5E04 /* RawTCPSocketProtocol.swift in Sources */,
|
||||
54CA02602426B2FD003A5E04 /* GCDProxyServer.swift in Sources */,
|
||||
@@ -1157,54 +1081,38 @@
|
||||
54CA01D52426B252003A5E04 /* SafeDict.swift in Sources */,
|
||||
54CA027B2426B2FD003A5E04 /* HTTPAuthentication.swift in Sources */,
|
||||
54CA02762426B2FD003A5E04 /* IPAddress.swift in Sources */,
|
||||
54CA02B02426B2FD003A5E04 /* SecureHTTPAdapterFactory.swift in Sources */,
|
||||
54CA02A62426B2FD003A5E04 /* AdapterSocket.swift in Sources */,
|
||||
54CA02742426B2FD003A5E04 /* IPMask.swift in Sources */,
|
||||
541075CF24C9D43A00D6F1BF /* UNNotification.swift in Sources */,
|
||||
54CA02BB2426B2FD003A5E04 /* SOCKS5ProxySocket.swift in Sources */,
|
||||
54D8B97F2471B89100EB2414 /* DBCommon.swift in Sources */,
|
||||
54CA02A42426B2FD003A5E04 /* SecureHTTPAdapter.swift in Sources */,
|
||||
54CA02942426B2FD003A5E04 /* DNSResolver.swift in Sources */,
|
||||
54CA025F2426B2FD003A5E04 /* ProxyServer.swift in Sources */,
|
||||
54CA02842426B2FD003A5E04 /* Rule.swift in Sources */,
|
||||
54CE8BC524B1ED2100CC1756 /* PushNotification.swift in Sources */,
|
||||
54CA02B92426B2FD003A5E04 /* DirectProxySocket.swift in Sources */,
|
||||
54751E522423955100168273 /* URL.swift in Sources */,
|
||||
54CA02A92426B2FD003A5E04 /* RejectAdapter.swift in Sources */,
|
||||
54CA02732426B2FD003A5E04 /* IPPool.swift in Sources */,
|
||||
541075D624CE286200D6F1BF /* CachedConnectionAlert.swift in Sources */,
|
||||
54CA027E2426B2FD003A5E04 /* DomainListRule.swift in Sources */,
|
||||
54CA02782426B2FD003A5E04 /* BinaryDataScanner.swift in Sources */,
|
||||
54CA02B12426B2FD003A5E04 /* ServerAdapterFactory.swift in Sources */,
|
||||
54CA02952426B2FD003A5E04 /* DNSEnums.swift in Sources */,
|
||||
54CA02802426B2FD003A5E04 /* DNSSessionMatchType.swift in Sources */,
|
||||
54CA02A22426B2FD003A5E04 /* ObserverFactory.swift in Sources */,
|
||||
54CA02612426B2FD003A5E04 /* GCDSOCKS5ProxyServer.swift in Sources */,
|
||||
54CA029D2426B2FD003A5E04 /* ProxyServerEvent.swift in Sources */,
|
||||
54CA02BC2426B2FD003A5E04 /* SocketProtocol.swift in Sources */,
|
||||
54CA029C2426B2FD003A5E04 /* AdapterSocketEvent.swift in Sources */,
|
||||
54CA02A72426B2FD003A5E04 /* DirectAdapter.swift in Sources */,
|
||||
54CA02A32426B2FD003A5E04 /* HTTPAdapter.swift in Sources */,
|
||||
54CA02622426B2FD003A5E04 /* GCDHTTPProxyServer.swift in Sources */,
|
||||
54CA02822426B2FD003A5E04 /* AllRule.swift in Sources */,
|
||||
543CDB2023EEE61900B7F323 /* PacketTunnelProvider.swift in Sources */,
|
||||
54CA02662426B2FD003A5E04 /* NWUDPSocket.swift in Sources */,
|
||||
54CA02682426B2FD003A5E04 /* NWTCPSocket.swift in Sources */,
|
||||
54CA02852426B2FD003A5E04 /* DirectRule.swift in Sources */,
|
||||
54CA01D32426B23D003A5E04 /* Resolver.swift in Sources */,
|
||||
54CA028B2426B2FD003A5E04 /* Utils.swift in Sources */,
|
||||
54CA02972426B2FD003A5E04 /* IPPacket.swift in Sources */,
|
||||
54CA026A2426B2FD003A5E04 /* RawSocketFactory.swift in Sources */,
|
||||
54CA02A02426B2FD003A5E04 /* TunnelEvent.swift in Sources */,
|
||||
546063E523FEFAFE008F505A /* DBCore.swift in Sources */,
|
||||
54CA02872426B2FD003A5E04 /* IPRangeListRule.swift in Sources */,
|
||||
54CA02922426B2FD003A5E04 /* DNSSession.swift in Sources */,
|
||||
54CA026D2426B2FD003A5E04 /* Opt.swift in Sources */,
|
||||
54CA02B32426B2FD003A5E04 /* HTTPAdapterFactory.swift in Sources */,
|
||||
54CA02702426B2FD003A5E04 /* HTTPStreamScanner.swift in Sources */,
|
||||
54CA02812426B2FD003A5E04 /* DNSFailRule.swift in Sources */,
|
||||
541075DA24CE2C7200D6F1BF /* GlassVPNHook.swift in Sources */,
|
||||
54CA02AC2426B2FD003A5E04 /* AuthenticationServerAdapterFactory.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1296,6 +1204,7 @@
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -1360,6 +1269,7 @@
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -1397,7 +1307,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = main/main.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 38;
|
||||
INFOPLIST_FILE = main/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -1405,8 +1315,9 @@
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "de.uni-bamberg.psi.AppCheck";
|
||||
PRODUCT_NAME = AppCheck;
|
||||
PRODUCT_NAME = AppChk;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -1416,7 +1327,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = main/main.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 38;
|
||||
INFOPLIST_FILE = main/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -1424,8 +1335,9 @@
|
||||
);
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "de.uni-bamberg.psi.AppCheck";
|
||||
PRODUCT_NAME = AppCheck;
|
||||
PRODUCT_NAME = AppChk;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -1435,7 +1347,7 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = GlassVPN/GlassVPN.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 38;
|
||||
INFOPLIST_FILE = GlassVPN/Info.plist;
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "de.uni-bamberg.psi.AppCheck.VPN";
|
||||
@@ -1444,6 +1356,7 @@
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "GlassVPN/robbiehanson-CocoaAsyncSocket/CocoaAsyncSocket.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -1453,7 +1366,7 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = GlassVPN/GlassVPN.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 38;
|
||||
INFOPLIST_FILE = GlassVPN/Info.plist;
|
||||
MARKETING_VERSION = 1.0.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "de.uni-bamberg.psi.AppCheck.VPN";
|
||||
@@ -1461,13 +1374,14 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "GlassVPN/robbiehanson-CocoaAsyncSocket/CocoaAsyncSocket.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
541AC5CF2399498A00A769D7 /* Build configuration list for PBXProject "AppCheck" */ = {
|
||||
541AC5CF2399498A00A769D7 /* Build configuration list for PBXProject "AppChk" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
541AC5E42399498B00A769D7 /* Debug */,
|
||||
@@ -1476,7 +1390,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
541AC5E62399498B00A769D7 /* Build configuration list for PBXNativeTarget "AppCheck" */ = {
|
||||
541AC5E62399498B00A769D7 /* Build configuration list for PBXNativeTarget "AppChk" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
541AC5E72399498B00A769D7 /* Debug */,
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1130"
|
||||
LastUpgradeVersion = "1250"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -15,9 +15,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "541AC5D32399498A00A769D7"
|
||||
BuildableName = "AppCheck.app"
|
||||
BlueprintName = "AppCheck"
|
||||
ReferencedContainer = "container:AppCheck.xcodeproj">
|
||||
BuildableName = "AppChk.app"
|
||||
BlueprintName = "AppChk"
|
||||
ReferencedContainer = "container:AppChk.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
@@ -45,9 +45,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "541AC5D32399498A00A769D7"
|
||||
BuildableName = "AppCheck.app"
|
||||
BlueprintName = "AppCheck"
|
||||
ReferencedContainer = "container:AppCheck.xcodeproj">
|
||||
BuildableName = "AppChk.app"
|
||||
BlueprintName = "AppChk"
|
||||
ReferencedContainer = "container:AppChk.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
@@ -61,9 +61,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "541AC5D32399498A00A769D7"
|
||||
BuildableName = "AppCheck.app"
|
||||
BlueprintName = "AppCheck"
|
||||
ReferencedContainer = "container:AppCheck.xcodeproj">
|
||||
BuildableName = "AppChk.app"
|
||||
BlueprintName = "AppChk"
|
||||
ReferencedContainer = "container:AppChk.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1130"
|
||||
LastUpgradeVersion = "1250"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
@@ -18,7 +18,7 @@
|
||||
BlueprintIdentifier = "543CDB1C23EEE61900B7F323"
|
||||
BuildableName = "GlassVPN.appex"
|
||||
BlueprintName = "GlassVPN"
|
||||
ReferencedContainer = "container:AppCheck.xcodeproj">
|
||||
ReferencedContainer = "container:AppChk.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
@@ -30,9 +30,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "541AC5D32399498A00A769D7"
|
||||
BuildableName = "AppCheck.app"
|
||||
BlueprintName = "AppCheck"
|
||||
ReferencedContainer = "container:AppCheck.xcodeproj">
|
||||
BuildableName = "AppChk.app"
|
||||
BlueprintName = "AppChk"
|
||||
ReferencedContainer = "container:AppChk.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
@@ -62,9 +62,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "541AC5D32399498A00A769D7"
|
||||
BuildableName = "AppCheck.app"
|
||||
BlueprintName = "AppCheck"
|
||||
ReferencedContainer = "container:AppCheck.xcodeproj">
|
||||
BuildableName = "AppChk.app"
|
||||
BlueprintName = "AppChk"
|
||||
ReferencedContainer = "container:AppChk.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
@@ -74,15 +74,16 @@
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
askForAppToLaunch = "Yes"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "541AC5D32399498A00A769D7"
|
||||
BuildableName = "AppCheck.app"
|
||||
BlueprintName = "AppCheck"
|
||||
ReferencedContainer = "container:AppCheck.xcodeproj">
|
||||
BuildableName = "AppChk.app"
|
||||
BlueprintName = "AppChk"
|
||||
ReferencedContainer = "container:AppChk.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
@@ -20,6 +20,8 @@
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import NetworkExtension
|
||||
|
||||
let connectMessage: Data = "CONNECT".data(using: .ascii)!
|
||||
let swcdUserAgent: Data = "User-Agent: swcd".data(using: .ascii)!
|
||||
fileprivate var hook : GlassVPNHook!
|
||||
|
||||
@@ -16,17 +17,17 @@ class LDObserverFactory: ObserverFactory {
|
||||
override func signal(_ event: ProxySocketEvent) {
|
||||
switch event {
|
||||
case .receivedRequest(let session, let socket):
|
||||
if socket.isCancelled ||
|
||||
(hook.forceDisconnectUnresolvable && session.ipAddress.isEmpty) {
|
||||
var kill = !hook.isBackgroundRecording && hook.forceDisconnectUnresolvable && session.ipAddress.isEmpty
|
||||
if kill || socket.isCancelled { // isCancelled is set by branch below
|
||||
hook.silentlyPrevented(session.host)
|
||||
socket.forceDisconnect()
|
||||
return
|
||||
} else {
|
||||
kill = hook.processDNSRequest(session.host)
|
||||
}
|
||||
let kill = hook.processDNSRequest(session.host)
|
||||
if kill { socket.forceDisconnect() }
|
||||
case .readData(let data, on: let socket):
|
||||
if hook.forceDisconnectSWCD, data.range(of: swcdUserAgent) != nil {
|
||||
socket.disconnect()
|
||||
if !hook.isBackgroundRecording, hook.forceDisconnectSWCD,
|
||||
data.starts(with: connectMessage), data.range(of: swcdUserAgent) != nil {
|
||||
socket.disconnect() // sets isCancelled above
|
||||
}
|
||||
default:
|
||||
break
|
||||
|
||||
BIN
GlassVPN/SwiftSocket/.DS_Store
vendored
Normal file
BIN
GlassVPN/SwiftSocket/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -1,16 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
public enum RuleMatchEvent: EventType {
|
||||
public var description: String {
|
||||
switch self {
|
||||
case let .ruleMatched(session, rule: rule):
|
||||
return "Rule \(rule) matched session \(session)."
|
||||
case let .ruleDidNotMatch(session, rule: rule):
|
||||
return "Rule \(rule) did not match session \(session)."
|
||||
case let .dnsRuleMatched(session, rule: rule, type: type, result: result):
|
||||
return "Rule \(rule) matched DNS session \(session) of type \(type), the result is \(result)."
|
||||
}
|
||||
}
|
||||
|
||||
case ruleMatched(ConnectSession, rule: Rule), ruleDidNotMatch(ConnectSession, rule: Rule), dnsRuleMatched(DNSSession, rule: Rule, type: DNSSessionMatchType, result: DNSSessionMatchResult)
|
||||
}
|
||||
@@ -20,8 +20,4 @@ open class ObserverFactory {
|
||||
open func getObserverForProxyServer(_ server: ProxyServer) -> Observer<ProxyServerEvent>? {
|
||||
return nil
|
||||
}
|
||||
|
||||
open func getObserverForRuleManager(_ manager: RuleManager) -> Observer<RuleMatchEvent>? {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,6 @@ open class DNSServer: DNSResolverDelegate, IPStackProtocol {
|
||||
return
|
||||
}
|
||||
|
||||
RuleManager.currentManager.matchDNS(session, type: .domain)
|
||||
|
||||
switch session.matchResult! {
|
||||
case .fake:
|
||||
guard setUpFakeIP(session) else {
|
||||
@@ -248,10 +246,6 @@ open class DNSServer: DNSResolverDelegate, IPStackProtocol {
|
||||
|
||||
session.realIP = message.resolvedIPv4Address
|
||||
|
||||
if session.matchResult != .fake && session.matchResult != .real {
|
||||
RuleManager.currentManager.matchDNS(session, type: .ip)
|
||||
}
|
||||
|
||||
switch session.matchResult! {
|
||||
case .fake:
|
||||
if !self.setUpFakeIP(session) {
|
||||
|
||||
@@ -7,7 +7,6 @@ open class DNSSession {
|
||||
open var fakeIP: IPAddress?
|
||||
open var realResponseMessage: DNSMessage?
|
||||
var realResponseIPPacket: IPPacket?
|
||||
open var matchedRule: Rule?
|
||||
open var matchResult: DNSSessionMatchResult?
|
||||
var indexToMatch = 0
|
||||
var expireAt: Date?
|
||||
|
||||
@@ -21,9 +21,6 @@ public final class ConnectSession {
|
||||
/// The requested port.
|
||||
public let port: Int
|
||||
|
||||
/// The rule to use to connect to remote.
|
||||
public var matchedRule: Rule?
|
||||
|
||||
/// Whether If the `requestedHost` is an IP address.
|
||||
public let fakeIPEnabled: Bool
|
||||
|
||||
@@ -126,11 +123,6 @@ public final class ConnectSession {
|
||||
|
||||
host = session.requestMessage.queries[0].name
|
||||
ipAddress = session.realIP?.presentation ?? ""
|
||||
matchedRule = session.matchedRule
|
||||
|
||||
// if session.countryCode != nil {
|
||||
// country = session.countryCode!
|
||||
// }
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ open class HTTPHeader {
|
||||
// Chunk is not supported yet.
|
||||
open var contentLength: Int = 0
|
||||
open var headers: [(String, String)] = []
|
||||
open var rawHeader: Data?
|
||||
|
||||
public init(headerString: String) throws {
|
||||
let lines = headerString.components(separatedBy: "\r\n")
|
||||
@@ -127,7 +126,6 @@ open class HTTPHeader {
|
||||
}
|
||||
|
||||
try self.init(headerString: headerString)
|
||||
rawHeader = headerData
|
||||
}
|
||||
|
||||
open subscript(index: String) -> String? {
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// The SOCKS5 proxy server.
|
||||
public final class GCDSOCKS5ProxyServer: GCDProxyServer {
|
||||
/**
|
||||
Create an instance of SOCKS5 proxy server.
|
||||
|
||||
- parameter address: The address of proxy server.
|
||||
- parameter port: The port of proxy server.
|
||||
*/
|
||||
override public init(address: IPAddress?, port: Port) {
|
||||
super.init(address: address, port: port)
|
||||
}
|
||||
|
||||
/**
|
||||
Handle the new accepted socket as a SOCKS5 proxy connection.
|
||||
|
||||
- parameter socket: The accepted socket.
|
||||
*/
|
||||
override public func handleNewGCDSocket(_ socket: GCDTCPSocket) {
|
||||
let proxySocket = SOCKS5ProxySocket(socket: socket)
|
||||
didAcceptNewSocket(proxySocket)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
open class ResponseGeneratorFactory {
|
||||
static var HTTPProxyResponseGenerator: ResponseGenerator.Type?
|
||||
static var SOCKS5ProxyResponseGenerator: ResponseGenerator.Type?
|
||||
}
|
||||
48
GlassVPN/zhuhaow-NEKit/Rule/AllRule.swift
vendored
48
GlassVPN/zhuhaow-NEKit/Rule/AllRule.swift
vendored
@@ -1,48 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// The rule matches all DNS and connect sessions.
|
||||
open class AllRule: Rule {
|
||||
fileprivate let adapterFactory: AdapterFactory
|
||||
|
||||
open override var description: String {
|
||||
return "<AllRule>"
|
||||
}
|
||||
|
||||
/**
|
||||
Create a new `AllRule` instance.
|
||||
|
||||
- parameter adapterFactory: The factory which builds a corresponding adapter when needed.
|
||||
*/
|
||||
public init(adapterFactory: AdapterFactory) {
|
||||
self.adapterFactory = adapterFactory
|
||||
super.init()
|
||||
}
|
||||
|
||||
/**
|
||||
Match DNS session to this rule.
|
||||
|
||||
- parameter session: The DNS session to match.
|
||||
- parameter type: What kind of information is available.
|
||||
|
||||
- returns: The result of match.
|
||||
*/
|
||||
override open func matchDNS(_ session: DNSSession, type: DNSSessionMatchType) -> DNSSessionMatchResult {
|
||||
// only return real IP when we connect to remote directly
|
||||
if let _ = adapterFactory as? DirectAdapterFactory {
|
||||
return .real
|
||||
} else {
|
||||
return .fake
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Match connect session to this rule.
|
||||
|
||||
- parameter session: connect session to match.
|
||||
|
||||
- returns: The configured adapter.
|
||||
*/
|
||||
override open func match(_ session: ConnectSession) -> AdapterFactory? {
|
||||
return adapterFactory
|
||||
}
|
||||
}
|
||||
60
GlassVPN/zhuhaow-NEKit/Rule/DNSFailRule.swift
vendored
60
GlassVPN/zhuhaow-NEKit/Rule/DNSFailRule.swift
vendored
@@ -1,60 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// The rule matches the request which failed to look up.
|
||||
open class DNSFailRule: Rule {
|
||||
fileprivate let adapterFactory: AdapterFactory
|
||||
|
||||
open override var description: String {
|
||||
return "<DNSFailRule>"
|
||||
}
|
||||
|
||||
/**
|
||||
Create a new `DNSFailRule` instance.
|
||||
|
||||
- parameter adapterFactory: The factory which builds a corresponding adapter when needed.
|
||||
*/
|
||||
public init(adapterFactory: AdapterFactory) {
|
||||
self.adapterFactory = adapterFactory
|
||||
super.init()
|
||||
}
|
||||
|
||||
/**
|
||||
Match DNS request to this rule.
|
||||
|
||||
- parameter session: The DNS session to match.
|
||||
- parameter type: What kind of information is available.
|
||||
|
||||
- returns: The result of match.
|
||||
*/
|
||||
override open func matchDNS(_ session: DNSSession, type: DNSSessionMatchType) -> DNSSessionMatchResult {
|
||||
guard type == .ip else {
|
||||
return .unknown
|
||||
}
|
||||
|
||||
// only return real IP when we connect to remote directly
|
||||
if session.realIP == nil {
|
||||
if let _ = adapterFactory as? DirectAdapterFactory {
|
||||
return .real
|
||||
} else {
|
||||
return .fake
|
||||
}
|
||||
} else {
|
||||
return .pass
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Match connect session to this rule.
|
||||
|
||||
- parameter session: connect session to match.
|
||||
|
||||
- returns: The configured adapter.
|
||||
*/
|
||||
override open func match(_ session: ConnectSession) -> AdapterFactory? {
|
||||
if session.ipAddress == "" {
|
||||
return adapterFactory
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
16
GlassVPN/zhuhaow-NEKit/Rule/DirectRule.swift
vendored
16
GlassVPN/zhuhaow-NEKit/Rule/DirectRule.swift
vendored
@@ -1,16 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// The rule matches every request and returns direct adapter.
|
||||
///
|
||||
/// This is equivalent to create an `AllRule` with a `DirectAdapterFactory`.
|
||||
open class DirectRule: AllRule {
|
||||
open override var description: String {
|
||||
return "<DirectRule>"
|
||||
}
|
||||
/**
|
||||
Create a new `DirectRule` instance.
|
||||
*/
|
||||
public init() {
|
||||
super.init(adapterFactory: DirectAdapterFactory())
|
||||
}
|
||||
}
|
||||
84
GlassVPN/zhuhaow-NEKit/Rule/DomainListRule.swift
vendored
84
GlassVPN/zhuhaow-NEKit/Rule/DomainListRule.swift
vendored
@@ -1,84 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// The rule matches the host domain to a list of predefined criteria.
|
||||
open class DomainListRule: Rule {
|
||||
public enum MatchCriterion {
|
||||
case regex(NSRegularExpression), prefix(String), suffix(String), keyword(String), complete(String)
|
||||
|
||||
func match(_ domain: String) -> Bool {
|
||||
switch self {
|
||||
case .regex(let regex):
|
||||
return regex.firstMatch(in: domain, options: [], range: NSRange(location: 0, length: domain.utf8.count)) != nil
|
||||
case .prefix(let prefix):
|
||||
return domain.hasPrefix(prefix)
|
||||
case .suffix(let suffix):
|
||||
return domain.hasSuffix(suffix)
|
||||
case .keyword(let keyword):
|
||||
return domain.contains(keyword)
|
||||
case .complete(let match):
|
||||
return domain == match
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate let adapterFactory: AdapterFactory
|
||||
|
||||
open override var description: String {
|
||||
return "<DomainListRule>"
|
||||
}
|
||||
|
||||
/// The list of criteria to match to.
|
||||
open var matchCriteria: [MatchCriterion] = []
|
||||
|
||||
/**
|
||||
Create a new `DomainListRule` instance.
|
||||
|
||||
- parameter adapterFactory: The factory which builds a corresponding adapter when needed.
|
||||
- parameter criteria: The list of criteria to match.
|
||||
*/
|
||||
public init(adapterFactory: AdapterFactory, criteria: [MatchCriterion]) {
|
||||
self.adapterFactory = adapterFactory
|
||||
self.matchCriteria = criteria
|
||||
}
|
||||
|
||||
/**
|
||||
Match DNS request to this rule.
|
||||
|
||||
- parameter session: The DNS session to match.
|
||||
- parameter type: What kind of information is available.
|
||||
|
||||
- returns: The result of match.
|
||||
*/
|
||||
override open func matchDNS(_ session: DNSSession, type: DNSSessionMatchType) -> DNSSessionMatchResult {
|
||||
if matchDomain(session.requestMessage.queries.first!.name) {
|
||||
if let _ = adapterFactory as? DirectAdapterFactory {
|
||||
return .real
|
||||
}
|
||||
return .fake
|
||||
}
|
||||
return .pass
|
||||
}
|
||||
|
||||
/**
|
||||
Match connect session to this rule.
|
||||
|
||||
- parameter session: connect session to match.
|
||||
|
||||
- returns: The configured adapter if matched, return `nil` if not matched.
|
||||
*/
|
||||
override open func match(_ session: ConnectSession) -> AdapterFactory? {
|
||||
if matchDomain(session.host) {
|
||||
return adapterFactory
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
fileprivate func matchDomain(_ domain: String) -> Bool {
|
||||
for criterion in matchCriteria {
|
||||
if criterion.match(domain) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// The rule matches the ip of the target hsot to a list of IP ranges.
|
||||
open class IPRangeListRule: Rule {
|
||||
fileprivate let adapterFactory: AdapterFactory
|
||||
|
||||
open override var description: String {
|
||||
return "<IPRangeList>"
|
||||
}
|
||||
|
||||
/// The list of regular expressions to match to.
|
||||
open var ranges: [IPRange] = []
|
||||
|
||||
/**
|
||||
Create a new `IPRangeListRule` instance.
|
||||
|
||||
- parameter adapterFactory: The factory which builds a corresponding adapter when needed.
|
||||
- parameter ranges: The list of IP ranges to match. The IP ranges are expressed in CIDR form ("127.0.0.1/8") or range form ("127.0.0.1+16777216").
|
||||
|
||||
- throws: The error when parsing the IP range.
|
||||
*/
|
||||
public init(adapterFactory: AdapterFactory, ranges: [String]) throws {
|
||||
self.adapterFactory = adapterFactory
|
||||
self.ranges = try ranges.map {
|
||||
let range = try IPRange(withString: $0)
|
||||
return range
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Match DNS request to this rule.
|
||||
|
||||
- parameter session: The DNS session to match.
|
||||
- parameter type: What kind of information is available.
|
||||
|
||||
- returns: The result of match.
|
||||
*/
|
||||
override open func matchDNS(_ session: DNSSession, type: DNSSessionMatchType) -> DNSSessionMatchResult {
|
||||
guard type == .ip else {
|
||||
return .unknown
|
||||
}
|
||||
|
||||
// Probably we should match all answers?
|
||||
guard let ip = session.realIP else {
|
||||
return .pass
|
||||
}
|
||||
|
||||
for range in ranges {
|
||||
if range.contains(ip: ip) {
|
||||
return .fake
|
||||
}
|
||||
}
|
||||
return .pass
|
||||
}
|
||||
|
||||
/**
|
||||
Match connect session to this rule.
|
||||
|
||||
- parameter session: connect session to match.
|
||||
|
||||
- returns: The configured adapter if matched, return `nil` if not matched.
|
||||
*/
|
||||
override open func match(_ session: ConnectSession) -> AdapterFactory? {
|
||||
guard let ip = IPAddress(fromString: session.ipAddress) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
for range in ranges {
|
||||
if range.contains(ip: ip) {
|
||||
return adapterFactory
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
37
GlassVPN/zhuhaow-NEKit/Rule/Rule.swift
vendored
37
GlassVPN/zhuhaow-NEKit/Rule/Rule.swift
vendored
@@ -1,37 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// The rule defines what to do for DNS requests and connect sessions.
|
||||
open class Rule: CustomStringConvertible {
|
||||
open var description: String {
|
||||
return "<Rule>"
|
||||
}
|
||||
|
||||
/**
|
||||
Create a new rule.
|
||||
*/
|
||||
public init() {
|
||||
}
|
||||
|
||||
/**
|
||||
Match DNS request to this rule.
|
||||
|
||||
- parameter session: The DNS session to match.
|
||||
- parameter type: What kind of information is available.
|
||||
|
||||
- returns: The result of match.
|
||||
*/
|
||||
open func matchDNS(_ session: DNSSession, type: DNSSessionMatchType) -> DNSSessionMatchResult {
|
||||
return .real
|
||||
}
|
||||
|
||||
/**
|
||||
Match connect session to this rule.
|
||||
|
||||
- parameter session: connect session to match.
|
||||
|
||||
- returns: The configured adapter if matched, return `nil` if not matched.
|
||||
*/
|
||||
open func match(_ session: ConnectSession) -> AdapterFactory? {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
80
GlassVPN/zhuhaow-NEKit/Rule/RuleManager.swift
vendored
80
GlassVPN/zhuhaow-NEKit/Rule/RuleManager.swift
vendored
@@ -1,80 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// The class managing rules.
|
||||
open class RuleManager {
|
||||
/// The current used `RuleManager`, there is only one manager should be used at a time.
|
||||
///
|
||||
/// - note: This should be set before any DNS or connect sessions.
|
||||
public static var currentManager: RuleManager = RuleManager(fromRules: [], appendDirect: true)
|
||||
|
||||
/// The rule list.
|
||||
var rules: [Rule] = []
|
||||
|
||||
open var observer: Observer<RuleMatchEvent>?
|
||||
|
||||
/**
|
||||
Create a new `RuleManager` from the given rules.
|
||||
|
||||
- parameter rules: The rules.
|
||||
- parameter appendDirect: Whether to append a `DirectRule` at the end of the list so any request does not match with any rule go directly.
|
||||
*/
|
||||
public init(fromRules rules: [Rule], appendDirect: Bool = false) {
|
||||
self.rules = []
|
||||
|
||||
if appendDirect || self.rules.count == 0 {
|
||||
self.rules.append(DirectRule())
|
||||
}
|
||||
|
||||
observer = ObserverFactory.currentFactory?.getObserverForRuleManager(self)
|
||||
}
|
||||
|
||||
/**
|
||||
Match DNS request to all rules.
|
||||
|
||||
- parameter session: The DNS session to match.
|
||||
- parameter type: What kind of information is available.
|
||||
*/
|
||||
func matchDNS(_ session: DNSSession, type: DNSSessionMatchType) {
|
||||
for (i, rule) in rules[session.indexToMatch..<rules.count].enumerated() {
|
||||
let result = rule.matchDNS(session, type: type)
|
||||
|
||||
observer?.signal(.dnsRuleMatched(session, rule: rule, type: type, result: result))
|
||||
|
||||
switch result {
|
||||
case .fake, .real, .unknown:
|
||||
session.matchedRule = rule
|
||||
session.matchResult = result
|
||||
session.indexToMatch = i + session.indexToMatch // add the offset
|
||||
return
|
||||
case .pass:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Match connect session to all rules.
|
||||
|
||||
- parameter session: connect session to match.
|
||||
|
||||
- returns: The matched configured adapter.
|
||||
*/
|
||||
func match(_ session: ConnectSession) -> AdapterFactory! {
|
||||
if session.matchedRule != nil {
|
||||
observer?.signal(.ruleMatched(session, rule: session.matchedRule!))
|
||||
return session.matchedRule!.match(session)
|
||||
}
|
||||
|
||||
for rule in rules {
|
||||
if let adapterFactory = rule.match(session) {
|
||||
observer?.signal(.ruleMatched(session, rule: rule))
|
||||
|
||||
session.matchedRule = rule
|
||||
return adapterFactory
|
||||
} else {
|
||||
observer?.signal(.ruleDidNotMatch(session, rule: rule))
|
||||
}
|
||||
}
|
||||
return nil // this should never happens
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// This is a very simple wrapper of a dict of type `[String: AdapterFactory]`.
|
||||
///
|
||||
/// Use it as a normal dict.
|
||||
public class AdapterFactoryManager {
|
||||
private var factoryDict: [String: AdapterFactory]
|
||||
|
||||
public subscript(index: String) -> AdapterFactory? {
|
||||
get {
|
||||
if index == "direct" {
|
||||
return DirectAdapterFactory()
|
||||
}
|
||||
return factoryDict[index]
|
||||
}
|
||||
set { factoryDict[index] = newValue }
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize a new factory manager.
|
||||
|
||||
- parameter factoryDict: The factory dict.
|
||||
*/
|
||||
public init(factoryDict: [String: AdapterFactory]) {
|
||||
self.factoryDict = factoryDict
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// Factory building server adapter which requires authentication.
|
||||
open class HTTPAuthenticationAdapterFactory: ServerAdapterFactory {
|
||||
let auth: HTTPAuthentication?
|
||||
|
||||
required public init(serverHost: String, serverPort: Int, auth: HTTPAuthentication?) {
|
||||
self.auth = auth
|
||||
super.init(serverHost: serverHost, serverPort: serverPort)
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// Factory building HTTP adapter.
|
||||
open class HTTPAdapterFactory: HTTPAuthenticationAdapterFactory {
|
||||
required public init(serverHost: String, serverPort: Int, auth: HTTPAuthentication?) {
|
||||
super.init(serverHost: serverHost, serverPort: serverPort, auth: auth)
|
||||
}
|
||||
|
||||
/**
|
||||
Get a HTTP adapter.
|
||||
|
||||
- parameter session: The connect session.
|
||||
|
||||
- returns: The built adapter.
|
||||
*/
|
||||
override open func getAdapterFor(session: ConnectSession) -> AdapterSocket {
|
||||
let adapter = HTTPAdapter(serverHost: serverHost, serverPort: serverPort, auth: auth)
|
||||
adapter.socket = RawSocketFactory.getRawSocket()
|
||||
return adapter
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
open class RejectAdapterFactory: AdapterFactory {
|
||||
public let delay: Int
|
||||
|
||||
public init(delay: Int = Opt.RejectAdapterDefaultDelay) {
|
||||
self.delay = delay
|
||||
}
|
||||
|
||||
override open func getAdapterFor(session: ConnectSession) -> AdapterSocket {
|
||||
return RejectAdapter(delay: delay)
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// Factory building SOCKS5 adapter.
|
||||
open class SOCKS5AdapterFactory: ServerAdapterFactory {
|
||||
override public init(serverHost: String, serverPort: Int) {
|
||||
super.init(serverHost: serverHost, serverPort: serverPort)
|
||||
}
|
||||
|
||||
/**
|
||||
Get a SOCKS5 adapter.
|
||||
|
||||
- parameter session: The connect session.
|
||||
|
||||
- returns: The built adapter.
|
||||
*/
|
||||
override open func getAdapterFor(session: ConnectSession) -> AdapterSocket {
|
||||
let adapter = SOCKS5Adapter(serverHost: serverHost, serverPort: serverPort)
|
||||
adapter.socket = RawSocketFactory.getRawSocket()
|
||||
return adapter
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// Factory building secured HTTP (HTTP with SSL) adapter.
|
||||
open class SecureHTTPAdapterFactory: HTTPAdapterFactory {
|
||||
required public init(serverHost: String, serverPort: Int, auth: HTTPAuthentication?) {
|
||||
super.init(serverHost: serverHost, serverPort: serverPort, auth: auth)
|
||||
}
|
||||
|
||||
/**
|
||||
Get a secured HTTP adapter.
|
||||
|
||||
- parameter session: The connect session.
|
||||
|
||||
- returns: The built adapter.
|
||||
*/
|
||||
override open func getAdapterFor(session: ConnectSession) -> AdapterSocket {
|
||||
let adapter = SecureHTTPAdapter(serverHost: serverHost, serverPort: serverPort, auth: auth)
|
||||
adapter.socket = RawSocketFactory.getRawSocket()
|
||||
return adapter
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// Factory building adapter with proxy server host and port.
|
||||
open class ServerAdapterFactory: AdapterFactory {
|
||||
let serverHost: String
|
||||
let serverPort: Int
|
||||
|
||||
public init(serverHost: String, serverPort: Int) {
|
||||
self.serverHost = serverHost
|
||||
self.serverPort = serverPort
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
public enum HTTPAdapterError: Error, CustomStringConvertible {
|
||||
case invalidURL, serailizationFailure
|
||||
|
||||
public var description: String {
|
||||
switch self {
|
||||
case .invalidURL:
|
||||
return "Invalid url when connecting through proxy"
|
||||
case .serailizationFailure:
|
||||
return "Failed to serialize HTTP CONNECT header"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This adapter connects to remote host through a HTTP proxy.
|
||||
public class HTTPAdapter: AdapterSocket {
|
||||
enum HTTPAdapterStatus {
|
||||
case invalid,
|
||||
connecting,
|
||||
readingResponse,
|
||||
forwarding,
|
||||
stopped
|
||||
}
|
||||
|
||||
/// The host domain of the HTTP proxy.
|
||||
let serverHost: String
|
||||
|
||||
/// The port of the HTTP proxy.
|
||||
let serverPort: Int
|
||||
|
||||
/// The authentication information for the HTTP proxy.
|
||||
let auth: HTTPAuthentication?
|
||||
|
||||
/// Whether the connection to the proxy should be secured or not.
|
||||
var secured: Bool
|
||||
|
||||
var internalStatus: HTTPAdapterStatus = .invalid
|
||||
|
||||
public init(serverHost: String, serverPort: Int, auth: HTTPAuthentication?) {
|
||||
self.serverHost = serverHost
|
||||
self.serverPort = serverPort
|
||||
self.auth = auth
|
||||
secured = false
|
||||
super.init()
|
||||
}
|
||||
|
||||
override public func openSocketWith(session: ConnectSession) {
|
||||
super.openSocketWith(session: session)
|
||||
|
||||
guard !isCancelled else {
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
internalStatus = .connecting
|
||||
try socket.connectTo(host: serverHost, port: serverPort, enableTLS: secured, tlsSettings: nil)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
override public func didConnectWith(socket: RawTCPSocketProtocol) {
|
||||
super.didConnectWith(socket: socket)
|
||||
|
||||
guard let url = URL(string: "\(session.host):\(session.port)") else {
|
||||
observer?.signal(.errorOccured(HTTPAdapterError.invalidURL, on: self))
|
||||
disconnect()
|
||||
return
|
||||
}
|
||||
let message = CFHTTPMessageCreateRequest(kCFAllocatorDefault, "CONNECT" as CFString, url as CFURL, kCFHTTPVersion1_1).takeRetainedValue()
|
||||
if let authData = auth {
|
||||
CFHTTPMessageSetHeaderFieldValue(message, "Proxy-Authorization" as CFString, authData.authString() as CFString?)
|
||||
}
|
||||
CFHTTPMessageSetHeaderFieldValue(message, "Host" as CFString, "\(session.host):\(session.port)" as CFString?)
|
||||
CFHTTPMessageSetHeaderFieldValue(message, "Content-Length" as CFString, "0" as CFString?)
|
||||
|
||||
guard let requestData = CFHTTPMessageCopySerializedMessage(message)?.takeRetainedValue() else {
|
||||
observer?.signal(.errorOccured(HTTPAdapterError.serailizationFailure, on: self))
|
||||
disconnect()
|
||||
return
|
||||
}
|
||||
|
||||
internalStatus = .readingResponse
|
||||
write(data: requestData as Data)
|
||||
socket.readDataTo(data: Utils.HTTPData.DoubleCRLF)
|
||||
}
|
||||
|
||||
override public func didRead(data: Data, from socket: RawTCPSocketProtocol) {
|
||||
super.didRead(data: data, from: socket)
|
||||
|
||||
switch internalStatus {
|
||||
case .readingResponse:
|
||||
internalStatus = .forwarding
|
||||
observer?.signal(.readyForForward(self))
|
||||
delegate?.didBecomeReadyToForwardWith(socket: self)
|
||||
case .forwarding:
|
||||
observer?.signal(.readData(data, on: self))
|
||||
delegate?.didRead(data: data, from: self)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
override public func didWrite(data: Data?, by socket: RawTCPSocketProtocol) {
|
||||
super.didWrite(data: data, by: socket)
|
||||
if internalStatus == .forwarding {
|
||||
observer?.signal(.wroteData(data, on: self))
|
||||
delegate?.didWrite(data: data, by: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
public class RejectAdapter: AdapterSocket {
|
||||
public let delay: Int
|
||||
|
||||
public init(delay: Int) {
|
||||
self.delay = delay
|
||||
}
|
||||
|
||||
override public func openSocketWith(session: ConnectSession) {
|
||||
super.openSocketWith(session: session)
|
||||
|
||||
QueueFactory.getQueue().asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.milliseconds(delay)) {
|
||||
[weak self] in
|
||||
self?.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Disconnect the socket elegantly.
|
||||
*/
|
||||
public override func disconnect(becauseOf error: Error? = nil) {
|
||||
guard !isCancelled else {
|
||||
return
|
||||
}
|
||||
|
||||
_cancelled = true
|
||||
session.disconnected(becauseOf: error, by: .adapter)
|
||||
observer?.signal(.disconnectCalled(self))
|
||||
_status = .closed
|
||||
delegate?.didDisconnectWith(socket: self)
|
||||
}
|
||||
|
||||
/**
|
||||
Disconnect the socket immediately.
|
||||
*/
|
||||
public override func forceDisconnect(becauseOf error: Error? = nil) {
|
||||
guard !isCancelled else {
|
||||
return
|
||||
}
|
||||
|
||||
_cancelled = true
|
||||
session.disconnected(becauseOf: error, by: .adapter)
|
||||
observer?.signal(.forceDisconnectCalled(self))
|
||||
_status = .closed
|
||||
delegate?.didDisconnectWith(socket: self)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
public class SOCKS5Adapter: AdapterSocket {
|
||||
enum SOCKS5AdapterStatus {
|
||||
case invalid,
|
||||
connecting,
|
||||
readingMethodResponse,
|
||||
readingResponseFirstPart,
|
||||
readingResponseSecondPart,
|
||||
forwarding
|
||||
}
|
||||
public let serverHost: String
|
||||
public let serverPort: Int
|
||||
|
||||
var internalStatus: SOCKS5AdapterStatus = .invalid
|
||||
|
||||
let helloData = Data([0x05, 0x01, 0x00])
|
||||
|
||||
public enum ReadTag: Int {
|
||||
case methodResponse = -20000, connectResponseFirstPart, connectResponseSecondPart
|
||||
}
|
||||
|
||||
public enum WriteTag: Int {
|
||||
case open = -21000, connectIPv4, connectIPv6, connectDomainLength, connectPort
|
||||
}
|
||||
|
||||
public init(serverHost: String, serverPort: Int) {
|
||||
self.serverHost = serverHost
|
||||
self.serverPort = serverPort
|
||||
super.init()
|
||||
}
|
||||
|
||||
public override func openSocketWith(session: ConnectSession) {
|
||||
super.openSocketWith(session: session)
|
||||
|
||||
guard !isCancelled else {
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
internalStatus = .connecting
|
||||
try socket.connectTo(host: serverHost, port: serverPort, enableTLS: false, tlsSettings: nil)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
public override func didConnectWith(socket: RawTCPSocketProtocol) {
|
||||
super.didConnectWith(socket: socket)
|
||||
|
||||
write(data: helloData)
|
||||
internalStatus = .readingMethodResponse
|
||||
socket.readDataTo(length: 2)
|
||||
}
|
||||
|
||||
public override func didRead(data: Data, from socket: RawTCPSocketProtocol) {
|
||||
super.didRead(data: data, from: socket)
|
||||
|
||||
switch internalStatus {
|
||||
case .readingMethodResponse:
|
||||
var response: [UInt8]
|
||||
if session.isIPv4() {
|
||||
response = [0x05, 0x01, 0x00, 0x01]
|
||||
let address = IPAddress(fromString: session.host)!
|
||||
response += [UInt8](address.dataInNetworkOrder)
|
||||
} else if session.isIPv6() {
|
||||
response = [0x05, 0x01, 0x00, 0x04]
|
||||
let address = IPAddress(fromString: session.host)!
|
||||
response += [UInt8](address.dataInNetworkOrder)
|
||||
} else {
|
||||
response = [0x05, 0x01, 0x00, 0x03]
|
||||
response.append(UInt8(session.host.utf8.count))
|
||||
response += [UInt8](session.host.utf8)
|
||||
}
|
||||
|
||||
let portBytes: [UInt8] = Utils.toByteArray(UInt16(session.port)).reversed()
|
||||
response.append(contentsOf: portBytes)
|
||||
write(data: Data(response))
|
||||
|
||||
internalStatus = .readingResponseFirstPart
|
||||
socket.readDataTo(length: 5)
|
||||
case .readingResponseFirstPart:
|
||||
var readLength = 0
|
||||
switch data[3] {
|
||||
case 1:
|
||||
readLength = 3 + 2
|
||||
case 3:
|
||||
readLength = Int(data[4]) + 2
|
||||
case 4:
|
||||
readLength = 15 + 2
|
||||
default:
|
||||
break
|
||||
}
|
||||
internalStatus = .readingResponseSecondPart
|
||||
socket.readDataTo(length: readLength)
|
||||
case .readingResponseSecondPart:
|
||||
internalStatus = .forwarding
|
||||
observer?.signal(.readyForForward(self))
|
||||
delegate?.didBecomeReadyToForwardWith(socket: self)
|
||||
case .forwarding:
|
||||
delegate?.didRead(data: data, from: self)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
override open func didWrite(data: Data?, by socket: RawTCPSocketProtocol) {
|
||||
super.didWrite(data: data, by: socket)
|
||||
|
||||
if internalStatus == .forwarding {
|
||||
delegate?.didWrite(data: data, by: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// This adapter connects to remote host through a HTTP proxy with SSL.
|
||||
public class SecureHTTPAdapter: HTTPAdapter {
|
||||
override public init(serverHost: String, serverPort: Int, auth: HTTPAuthentication?) {
|
||||
super.init(serverHost: serverHost, serverPort: serverPort, auth: auth)
|
||||
secured = true
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// This class just forwards data directly.
|
||||
/// - note: It is designed to work with tun2socks only.
|
||||
public class DirectProxySocket: ProxySocket {
|
||||
enum DirectProxyReadStatus: CustomStringConvertible {
|
||||
case invalid,
|
||||
forwarding,
|
||||
stopped
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .invalid:
|
||||
return "invalid"
|
||||
case .forwarding:
|
||||
return "forwarding"
|
||||
case .stopped:
|
||||
return "stopped"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum DirectProxyWriteStatus {
|
||||
case invalid,
|
||||
forwarding,
|
||||
stopped
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .invalid:
|
||||
return "invalid"
|
||||
case .forwarding:
|
||||
return "forwarding"
|
||||
case .stopped:
|
||||
return "stopped"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var readStatus: DirectProxyReadStatus = .invalid
|
||||
private var writeStatus: DirectProxyWriteStatus = .invalid
|
||||
|
||||
public var readStatusDescription: String {
|
||||
return readStatus.description
|
||||
}
|
||||
|
||||
public var writeStatusDescription: String {
|
||||
return writeStatus.description
|
||||
}
|
||||
|
||||
/**
|
||||
Begin reading and processing data from the socket.
|
||||
|
||||
- note: Since there is nothing to read and process before forwarding data, this just calls `delegate?.didReceiveRequest`.
|
||||
*/
|
||||
override public func openSocket() {
|
||||
super.openSocket()
|
||||
|
||||
guard !isCancelled else {
|
||||
return
|
||||
}
|
||||
|
||||
if let address = socket.destinationIPAddress, let port = socket.destinationPort {
|
||||
session = ConnectSession(host: address.presentation, port: Int(port.value))
|
||||
|
||||
observer?.signal(.receivedRequest(session!, on: self))
|
||||
delegate?.didReceive(session: session!, from: self)
|
||||
} else {
|
||||
forceDisconnect()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Response to the `AdapterSocket` on the other side of the `Tunnel` which has succefully connected to the remote server.
|
||||
|
||||
- parameter adapter: The `AdapterSocket`.
|
||||
*/
|
||||
override public func respondTo(adapter: AdapterSocket) {
|
||||
super.respondTo(adapter: adapter)
|
||||
|
||||
guard !isCancelled else {
|
||||
return
|
||||
}
|
||||
|
||||
readStatus = .forwarding
|
||||
writeStatus = .forwarding
|
||||
|
||||
observer?.signal(.readyForForward(self))
|
||||
delegate?.didBecomeReadyToForwardWith(socket: self)
|
||||
}
|
||||
|
||||
/**
|
||||
The socket did read some data.
|
||||
|
||||
- parameter data: The data read from the socket.
|
||||
- parameter from: The socket where the data is read from.
|
||||
*/
|
||||
override open func didRead(data: Data, from: RawTCPSocketProtocol) {
|
||||
super.didRead(data: data, from: from)
|
||||
delegate?.didRead(data: data, from: self)
|
||||
}
|
||||
|
||||
/**
|
||||
The socket did send some data.
|
||||
|
||||
- parameter data: The data which have been sent to remote (acknowledged). Note this may not be available since the data may be released to save memory.
|
||||
- parameter by: The socket where the data is sent out.
|
||||
*/
|
||||
override open func didWrite(data: Data?, by: RawTCPSocketProtocol) {
|
||||
super.didWrite(data: data, by: by)
|
||||
delegate?.didWrite(data: data, by: self)
|
||||
}
|
||||
}
|
||||
@@ -1,244 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
public class SOCKS5ProxySocket: ProxySocket {
|
||||
enum SOCKS5ProxyReadStatus: CustomStringConvertible {
|
||||
case invalid,
|
||||
readingVersionIdentifierAndNumberOfMethods,
|
||||
readingMethods,
|
||||
readingConnectHeader,
|
||||
readingIPv4Address,
|
||||
readingDomainLength,
|
||||
readingDomain,
|
||||
readingIPv6Address,
|
||||
readingPort,
|
||||
forwarding,
|
||||
stopped
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .invalid:
|
||||
return "invalid"
|
||||
case .readingVersionIdentifierAndNumberOfMethods:
|
||||
return "reading version and methods"
|
||||
case .readingMethods:
|
||||
return "reading methods"
|
||||
case .readingConnectHeader:
|
||||
return "reading connect header"
|
||||
case .readingIPv4Address:
|
||||
return "IPv4 address"
|
||||
case .readingDomainLength:
|
||||
return "domain length"
|
||||
case .readingDomain:
|
||||
return "domain"
|
||||
case .readingIPv6Address:
|
||||
return "IPv6 address"
|
||||
case .readingPort:
|
||||
return "reading port"
|
||||
case .forwarding:
|
||||
return "forwarding"
|
||||
case .stopped:
|
||||
return "stopped"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum SOCKS5ProxyWriteStatus: CustomStringConvertible {
|
||||
case invalid,
|
||||
sendingResponse,
|
||||
forwarding,
|
||||
stopped
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .invalid:
|
||||
return "invalid"
|
||||
case .sendingResponse:
|
||||
return "sending response"
|
||||
case .forwarding:
|
||||
return "forwarding"
|
||||
case .stopped:
|
||||
return "stopped"
|
||||
}
|
||||
}
|
||||
}
|
||||
/// The remote host to connect to.
|
||||
public var destinationHost: String!
|
||||
|
||||
/// The remote port to connect to.
|
||||
public var destinationPort: Int!
|
||||
|
||||
private var readStatus: SOCKS5ProxyReadStatus = .invalid
|
||||
private var writeStatus: SOCKS5ProxyWriteStatus = .invalid
|
||||
|
||||
public var readStatusDescription: String {
|
||||
return readStatus.description
|
||||
}
|
||||
|
||||
public var writeStatusDescription: String {
|
||||
return writeStatus.description
|
||||
}
|
||||
|
||||
/**
|
||||
Begin reading and processing data from the socket.
|
||||
*/
|
||||
override public func openSocket() {
|
||||
super.openSocket()
|
||||
|
||||
guard !isCancelled else {
|
||||
return
|
||||
}
|
||||
|
||||
readStatus = .readingVersionIdentifierAndNumberOfMethods
|
||||
socket.readDataTo(length: 2)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
// swiftlint:disable cyclomatic_complexity
|
||||
/**
|
||||
The socket did read some data.
|
||||
|
||||
- parameter data: The data read from the socket.
|
||||
- parameter from: The socket where the data is read from.
|
||||
*/
|
||||
override public func didRead(data: Data, from: RawTCPSocketProtocol) {
|
||||
super.didRead(data: data, from: from)
|
||||
|
||||
switch readStatus {
|
||||
case .forwarding:
|
||||
delegate?.didRead(data: data, from: self)
|
||||
case .readingVersionIdentifierAndNumberOfMethods:
|
||||
data.withUnsafeBytes { pointer in
|
||||
let p = pointer.bindMemory(to: Int8.self)
|
||||
|
||||
guard p.baseAddress!.pointee == 5 else {
|
||||
// TODO: notify observer
|
||||
self.disconnect()
|
||||
return
|
||||
}
|
||||
|
||||
guard p.baseAddress!.successor().pointee > 0 else {
|
||||
// TODO: notify observer
|
||||
self.disconnect()
|
||||
return
|
||||
}
|
||||
|
||||
self.readStatus = .readingMethods
|
||||
self.socket.readDataTo(length: Int(p.baseAddress!.successor().pointee))
|
||||
}
|
||||
case .readingMethods:
|
||||
// TODO: check for 0x00 in read data
|
||||
|
||||
let response = Data([0x05, 0x00])
|
||||
// we would not be able to read anything before the data is written out, so no need to handle the dataWrote event.
|
||||
write(data: response)
|
||||
readStatus = .readingConnectHeader
|
||||
socket.readDataTo(length: 4)
|
||||
case .readingConnectHeader:
|
||||
data.withUnsafeBytes { pointer in
|
||||
let p = pointer.bindMemory(to: Int8.self)
|
||||
|
||||
guard p.baseAddress!.pointee == 5 && p.baseAddress!.successor().pointee == 1 else {
|
||||
// TODO: notify observer
|
||||
self.disconnect()
|
||||
return
|
||||
}
|
||||
switch p.baseAddress!.advanced(by: 3).pointee {
|
||||
case 1:
|
||||
readStatus = .readingIPv4Address
|
||||
socket.readDataTo(length: 4)
|
||||
case 3:
|
||||
readStatus = .readingDomainLength
|
||||
socket.readDataTo(length: 1)
|
||||
case 4:
|
||||
readStatus = .readingIPv6Address
|
||||
socket.readDataTo(length: 16)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
case .readingIPv4Address:
|
||||
var address = Data(count: Int(INET_ADDRSTRLEN))
|
||||
_ = data.withUnsafeBytes { data_ptr in
|
||||
address.withUnsafeMutableBytes { addr_ptr in
|
||||
inet_ntop(AF_INET, data_ptr.baseAddress!, addr_ptr.bindMemory(to: Int8.self).baseAddress!, socklen_t(INET_ADDRSTRLEN))
|
||||
}
|
||||
}
|
||||
|
||||
destinationHost = String(data: address, encoding: .utf8)
|
||||
|
||||
readStatus = .readingPort
|
||||
socket.readDataTo(length: 2)
|
||||
case .readingIPv6Address:
|
||||
var address = Data(count: Int(INET6_ADDRSTRLEN))
|
||||
_ = data.withUnsafeBytes { data_ptr in
|
||||
address.withUnsafeMutableBytes { addr_ptr in
|
||||
inet_ntop(AF_INET6, data_ptr.baseAddress!, addr_ptr.bindMemory(to: Int8.self).baseAddress!, socklen_t(INET6_ADDRSTRLEN))
|
||||
}
|
||||
}
|
||||
|
||||
destinationHost = String(data: address, encoding: .utf8)
|
||||
|
||||
readStatus = .readingPort
|
||||
socket.readDataTo(length: 2)
|
||||
case .readingDomainLength:
|
||||
readStatus = .readingDomain
|
||||
socket.readDataTo(length: Int(data.first!))
|
||||
case .readingDomain:
|
||||
destinationHost = String(data: data, encoding: .utf8)
|
||||
readStatus = .readingPort
|
||||
socket.readDataTo(length: 2)
|
||||
case .readingPort:
|
||||
data.withUnsafeBytes {
|
||||
destinationPort = Int($0.load(as: UInt16.self).bigEndian)
|
||||
}
|
||||
|
||||
readStatus = .forwarding
|
||||
session = ConnectSession(host: destinationHost, port: destinationPort)
|
||||
observer?.signal(.receivedRequest(session!, on: self))
|
||||
delegate?.didReceive(session: session!, from: self)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The socket did send some data.
|
||||
|
||||
- parameter data: The data which have been sent to remote (acknowledged). Note this may not be available since the data may be released to save memory.
|
||||
- parameter from: The socket where the data is sent out.
|
||||
*/
|
||||
override public func didWrite(data: Data?, by: RawTCPSocketProtocol) {
|
||||
super.didWrite(data: data, by: by)
|
||||
|
||||
switch writeStatus {
|
||||
case .forwarding:
|
||||
delegate?.didWrite(data: data, by: self)
|
||||
case .sendingResponse:
|
||||
writeStatus = .forwarding
|
||||
observer?.signal(.readyForForward(self))
|
||||
delegate?.didBecomeReadyToForwardWith(socket: self)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Response to the `AdapterSocket` on the other side of the `Tunnel` which has succefully connected to the remote server.
|
||||
|
||||
- parameter adapter: The `AdapterSocket`.
|
||||
*/
|
||||
override public func respondTo(adapter: AdapterSocket) {
|
||||
super.respondTo(adapter: adapter)
|
||||
|
||||
guard !isCancelled else {
|
||||
return
|
||||
}
|
||||
|
||||
var responseBytes = [UInt8](repeating: 0, count: 10)
|
||||
responseBytes[0...3] = [0x05, 0x00, 0x00, 0x01]
|
||||
let responseData = Data(responseBytes)
|
||||
|
||||
writeStatus = .sendingResponse
|
||||
write(data: responseData)
|
||||
}
|
||||
}
|
||||
4
GlassVPN/zhuhaow-NEKit/Tunnel/Tunnel.swift
vendored
4
GlassVPN/zhuhaow-NEKit/Tunnel/Tunnel.swift
vendored
@@ -170,9 +170,7 @@ public class Tunnel: NSObject, SocketDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
let manager = RuleManager.currentManager
|
||||
let factory = manager.match(session)!
|
||||
adapterSocket = factory.getAdapterFor(session: session)
|
||||
adapterSocket = DirectAdapterFactory().getAdapterFor(session: session)
|
||||
adapterSocket!.delegate = self
|
||||
adapterSocket!.openSocketWith(session: session)
|
||||
}
|
||||
|
||||
59
README.md
59
README.md
@@ -1,4 +1,4 @@
|
||||
AppCheck – Privacy Monitor
|
||||
AppChk – Privacy Monitor
|
||||
==========================
|
||||
|
||||
A pocket DNS monitor and network filter.
|
||||
@@ -8,35 +8,44 @@ A pocket DNS monitor and network filter.
|
||||
|
||||
## What is it?
|
||||
|
||||
AppCheck helps you identify which applications communicate with third parties.
|
||||
It does so by logging network requests.
|
||||
AppCheck learns only the destination addresses, not the actual data that is exchanged.
|
||||
AppChk helps you identify applications that communicate with other parties.
|
||||
|
||||
Your data belongs to you.
|
||||
Therefore, monitoring and analysis take place on your device only.
|
||||
The app does not share any data with us or any other third-party – unless you choose to.
|
||||
|
||||
Join [Testflight beta](https://testflight.apple.com/join/9jjaFeHO)
|
||||
Join the [Testflight beta][testflight] or look at the evaluation results [appchk.de].
|
||||
|
||||
|
||||
### How does it work?
|
||||
|
||||
AppCheck creates a local VPN tunnel to intercept all network connections.
|
||||
For each connection AppCheck looks into the DNS headers only, namely the domain names.
|
||||
These domain names are logged in the background while the VPN is active.
|
||||
That means, AppCheck does not have to be active in the foreground all the time.
|
||||
AppChk creates a local VPN proxy to intercept all network connections.
|
||||
For each connection, AppChk looks into the DNS headers only, namely the domain names.
|
||||
These domain names are logged in the background while the VPN is running.
|
||||
AppChk does not need to be active all the time.
|
||||
|
||||
|
||||
### What about privacy?
|
||||
|
||||
Your data belongs to you.
|
||||
Therefore, monitoring takes place on your device only.
|
||||
AppChk learns only the destination addresses, not the actual data that is exchanged.
|
||||
The app does not share any data with us or any other third-party – unless you choose to.
|
||||
|
||||
|
||||
### How can I contribute?
|
||||
|
||||
AppChk allows you to record app-specific activity.
|
||||
You can share these recordings with the community; it can help you and others avoid phony applications, even before you install an app.
|
||||
|
||||
Join the [Testflight beta][testflight]
|
||||
|
||||
## Features
|
||||
|
||||
- See outgoing (DNS) network requests in real-time
|
||||
- See history of previous connections
|
||||
- See the history of previous connections
|
||||
- Block unwanted traffic based on domain names
|
||||
- Record app specific activity<sup>1</sup>
|
||||
- Record app-specific activity<sup>1</sup>
|
||||
- Apply logging filters (block or ignore) and display filters (specific range or last x minutes)
|
||||
- Sort results by time, name, or occurrence count
|
||||
- Context Analysis
|
||||
- What other domains occur often at the same time?
|
||||
- What other domains often occur at the same time?
|
||||
- What happened immediately before or after the action?
|
||||
- Export results for custom analysis
|
||||
- Alert Monitor & reminder
|
||||
@@ -51,7 +60,19 @@ That means, AppCheck does not have to be active in the foreground all the time.
|
||||
|
||||
## Research Project
|
||||
|
||||
*information will be added soon™*
|
||||
This research project is an effort to shine a light on the background activity of iOS apps, making the otherwise hidden network connections visible to everyone.
|
||||
The goal is to make privacy more accessible to the general public.
|
||||
And thus create incentives for app developers to respect users' privacy.
|
||||
|
||||
For now, go to the results page at [https://appchk.de/](https://appchk.de/).
|
||||
Btw. we are searching for [help](https://appchk.de/help/) on our ongoing research project.
|
||||
We want to offer users, activists, data protection authorities, and data protection officers an easily accessible and flexible tool to assess the privacy measures of iOS applications.
|
||||
AppChk allows users to:
|
||||
|
||||
- get a visual overview of an apps communication signature
|
||||
- assess how an app ranks within its peer group or category
|
||||
- influence the ranking according to their preferences
|
||||
|
||||
The evaluation results page is at [appchk.de] and the research paper at [arxiv](https://arxiv.org/abs/2104.06167).
|
||||
|
||||
|
||||
[testflight]: https://testflight.apple.com/join/9jjaFeHO
|
||||
[appchk.de]: https://appchk.de/
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 158 KiB After Width: | Height: | Size: 141 KiB |
@@ -12,6 +12,7 @@ enum PrefsShared {
|
||||
|
||||
static func registerDefaults() {
|
||||
suite.register(defaults: [
|
||||
"ForceDisconnectSWCD" : true,
|
||||
"RestartReminderEnabled" : true,
|
||||
"RestartReminderWithText" : true,
|
||||
"RestartReminderWithBadge" : true,
|
||||
|
||||
@@ -40,7 +40,7 @@ func AskAlert(title: String?, text: String?, buttonText: String = "Continue", ca
|
||||
/// Show alert hinting the user to go to system settings and re-enable notifications.
|
||||
func NotificationsDisabledAlert(presentIn viewController: UIViewController) {
|
||||
AskAlert(title: "Notifications Disabled",
|
||||
text: "Go to System Settings > Notifications > AppCheck to re-enable notifications.",
|
||||
text: "Go to System Settings > Notifications > AppChk to re-enable notifications.",
|
||||
buttonText: "Open settings") { _ in
|
||||
URL(string: UIApplication.openSettingsURLString)?.open()
|
||||
}.presentIn(viewController)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="W5Q-oz-bFb">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="W5Q-oz-bFb">
|
||||
<device id="retina4_0" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
@@ -65,7 +65,7 @@
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" translatesAutoresizingMaskIntoConstraints="NO" id="zbU-wC-qJG">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" translatesAutoresizingMaskIntoConstraints="NO" id="zbU-wC-qJG">
|
||||
<rect key="frame" x="15" y="11" width="290" height="20.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="rN0-kA-Eln">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="rN0-kA-Eln">
|
||||
<rect key="frame" x="16" y="12" width="33.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
@@ -235,7 +235,7 @@
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Detail" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="0pW-ZC-wmh">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Detail" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="0pW-ZC-wmh">
|
||||
<rect key="frame" x="113" y="12" width="44" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
@@ -252,7 +252,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="57.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="xDy-8J-JFT">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="xDy-8J-JFT">
|
||||
<rect key="frame" x="16" y="9" width="33.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
@@ -407,13 +407,13 @@
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="checkmark" indentationWidth="10" reuseIdentifier="shareLogCell" textLabel="c0B-OV-ujb" detailTextLabel="sAD-Ns-DV6" style="IBUITableViewCellStyleSubtitle" id="ilN-ct-Db4">
|
||||
<rect key="frame" x="0.0" y="229.5" width="320" height="58.5"/>
|
||||
<rect key="frame" x="0.0" y="229.5" width="320" height="57.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ilN-ct-Db4" id="xMK-8l-diB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="280" height="58.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="280" height="57.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="c0B-OV-ujb">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="c0B-OV-ujb">
|
||||
<rect key="frame" x="16" y="9" width="33.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
@@ -521,7 +521,7 @@
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Guy-Ra-fpS" userLabel="Title">
|
||||
<rect key="frame" x="0.0" y="0.0" width="288" height="40"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="AppCheck" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Et0-8d-CId">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="AppChk" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Et0-8d-CId">
|
||||
<rect key="frame" x="0.0" y="2" width="80" height="20.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pdd-aM-sKl">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pdd-aM-sKl">
|
||||
<device id="retina4_0" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
@@ -24,7 +24,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="293" height="57.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="0HB-5f-eB1">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="0HB-5f-eB1">
|
||||
<rect key="frame" x="16" y="9" width="33.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
@@ -94,7 +94,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="293" height="57.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Rnk-SP-UHm">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Rnk-SP-UHm">
|
||||
<rect key="frame" x="16" y="9" width="33.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
@@ -204,7 +204,7 @@
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Subtitle" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="No8-Bf-ptL">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Subtitle" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="No8-Bf-ptL">
|
||||
<rect key="frame" x="113" y="12" width="59" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="qdB-ZO-LHY">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="qdB-ZO-LHY">
|
||||
<device id="retina4_0" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
@@ -14,7 +15,7 @@
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="8kq-PY-wp7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<sections>
|
||||
<tableViewSection headerTitle="VPN Proxy Settings" id="w58-6X-Jea">
|
||||
<cells>
|
||||
@@ -67,7 +68,7 @@
|
||||
<rect key="frame" x="113" y="13" width="73" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -94,7 +95,7 @@
|
||||
<rect key="frame" x="113" y="13" width="73" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -115,17 +116,17 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Reminders" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="pN1-lL-bGz">
|
||||
<rect key="frame" x="16" y="12" width="81.5" height="20.5"/>
|
||||
<rect key="frame" x="16" y="12" width="81" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Disabled" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ldE-NT-c2c">
|
||||
<rect key="frame" x="218" y="12" width="67" height="20.5"/>
|
||||
<rect key="frame" x="218.5" y="12" width="66.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -142,17 +143,17 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Connection Alerts" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="o7c-vQ-haI">
|
||||
<rect key="frame" x="16" y="12" width="137.5" height="20.5"/>
|
||||
<rect key="frame" x="16" y="12" width="137" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Disabled" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="VeV-go-DXR">
|
||||
<rect key="frame" x="218" y="12" width="67" height="20.5"/>
|
||||
<rect key="frame" x="218.5" y="12" width="66.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -173,7 +174,7 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Auto-Delete Logs" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8gD-At-D8n">
|
||||
<rect key="frame" x="16" y="12" width="134" height="20.5"/>
|
||||
<rect key="frame" x="16" y="12" width="133.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
@@ -183,7 +184,7 @@
|
||||
<rect key="frame" x="239.5" y="12" width="45.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -200,7 +201,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6B5-l4-Hgz">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6B5-l4-Hgz">
|
||||
<rect key="frame" x="74.5" y="7" width="171" height="30"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<state key="normal" title="Reset Introduction Alerts"/>
|
||||
@@ -222,11 +223,11 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sE3-Vh-0lM">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sE3-Vh-0lM">
|
||||
<rect key="frame" x="111.5" y="7" width="97" height="30"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<state key="normal" title="Delete all logs">
|
||||
<color key="titleColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleColor" systemColor="systemRedColor"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="clearDatabaseResults" destination="qdB-ZO-LHY" eventType="touchUpInside" id="heU-m1-oJq"/>
|
||||
@@ -251,17 +252,17 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Force disconnect unresolvable" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="rio-m6-pXN">
|
||||
<rect key="frame" x="16" y="5" width="234" height="20.5"/>
|
||||
<rect key="frame" x="15" y="5" width="233" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="in case DNS returns empty IP" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="rr4-sR-VxD">
|
||||
<rect key="frame" x="16" y="25.5" width="166" height="14.5"/>
|
||||
<rect key="frame" x="15" y="25.5" width="165.5" height="14.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TSu-IP-KFG">
|
||||
@@ -285,17 +286,17 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Force disconnect swcd" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="x5u-5T-XTO">
|
||||
<rect key="frame" x="16" y="5" width="177" height="20.5"/>
|
||||
<rect key="frame" x="15" y="5" width="176" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="User-Agent: swcd (may affect performance)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="n7p-Ab-69G">
|
||||
<rect key="frame" x="16" y="25.5" width="249.5" height="14.5"/>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="background deamon User-Agent: swcd" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="n7p-Ab-69G">
|
||||
<rect key="frame" x="15" y="25.5" width="220.5" height="14.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="c5N-PN-qWU">
|
||||
@@ -318,7 +319,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vZa-EO-FAZ">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vZa-EO-FAZ">
|
||||
<rect key="frame" x="125" y="7" width="70" height="30"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<state key="normal" title="Export DB"/>
|
||||
@@ -366,7 +367,7 @@
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="GSg-ZZ-F8J">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="DomainFilterCell" textLabel="MrS-rb-RLB" style="IBUITableViewCellStyleDefault" id="EO2-ww-xuz">
|
||||
<rect key="frame" x="0.0" y="28" width="320" height="43.5"/>
|
||||
@@ -375,7 +376,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="MrS-rb-RLB">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="characterWrap" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" id="MrS-rb-RLB">
|
||||
<rect key="frame" x="16" y="0.0" width="288" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
@@ -410,12 +411,12 @@
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Dop-3B-Uvh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<sections>
|
||||
<tableViewSection headerTitle="Restart Reminder" id="UOi-fT-8Vh">
|
||||
<string key="footerTitle">If VPN stops accidentally, show a notification 5 minutes later. It will remind you to re-enable the VPN after system reboot.
|
||||
|
||||
if Notification is enabled, show a notification banner once, stating the VPN has stopped.
|
||||
If Notification is enabled, show a notification banner once, stating the VPN has stopped.
|
||||
|
||||
If App Badge is enabled, display the letter "1" on the homescreen app icon, as long as the VPN is not running.</string>
|
||||
<cells>
|
||||
@@ -434,7 +435,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="zaV-mh-eqb">
|
||||
<rect key="frame" x="251" y="6" width="54" height="31"/>
|
||||
<rect key="frame" x="250" y="6" width="54" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAllowRestartReminder:" destination="JYM-cs-i4H" eventType="valueChanged" id="F4e-k2-bni"/>
|
||||
@@ -461,7 +462,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="HaE-En-NH3">
|
||||
<rect key="frame" x="251" y="6" width="54" height="31"/>
|
||||
<rect key="frame" x="250" y="6" width="54" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAllowRestartNotify:" destination="JYM-cs-i4H" eventType="valueChanged" id="12C-h5-mrR"/>
|
||||
@@ -488,7 +489,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="N2Q-cU-pkd">
|
||||
<rect key="frame" x="251" y="6" width="54" height="31"/>
|
||||
<rect key="frame" x="250" y="6" width="54" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAllowRestartBadge:" destination="JYM-cs-i4H" eventType="valueChanged" id="76l-6y-fOu"/>
|
||||
@@ -508,7 +509,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Sound" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="UBT-zI-VNd">
|
||||
<rect key="frame" x="16" y="12" width="49.5" height="20.5"/>
|
||||
<rect key="frame" x="16" y="12" width="49" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
@@ -518,7 +519,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<rect key="frame" x="241" y="12" width="44" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -566,7 +567,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Sound" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="VYC-xF-awf">
|
||||
<rect key="frame" x="16" y="12" width="49.5" height="20.5"/>
|
||||
<rect key="frame" x="16" y="12" width="49" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
@@ -576,7 +577,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<rect key="frame" x="241" y="12" width="44" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -614,7 +615,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="w2R-BE-lM4">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="checkmark" indentationWidth="10" reuseIdentifier="SettingsAlertToneCell" textLabel="O50-Db-5TI" style="IBUITableViewCellStyleDefault" id="38V-eP-HSv">
|
||||
<rect key="frame" x="0.0" y="55.5" width="320" height="43.5"/>
|
||||
@@ -653,7 +654,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="u0e-LW-1Qh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<sections>
|
||||
<tableViewSection headerTitle="Connection Alerts" footerTitle="Get a notification whenever a specific DNS request occurs." id="4OJ-qA-l8L">
|
||||
<cells>
|
||||
@@ -692,7 +693,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Sound" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="pck-pT-tnX">
|
||||
<rect key="frame" x="16" y="12" width="49.5" height="20.5"/>
|
||||
<rect key="frame" x="16" y="12" width="49" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
@@ -702,7 +703,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<rect key="frame" x="241" y="12" width="44" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -843,7 +844,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<rect key="frame" x="113" y="13" width="73" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -870,7 +871,7 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
<rect key="frame" x="113" y="13" width="73" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
@@ -902,6 +903,17 @@ If App Badge is enabled, display the letter "1" on the homescreen app icon, as l
|
||||
</scenes>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="tUF-Kv-koO"/>
|
||||
<segue reference="EzT-Xq-wka"/>
|
||||
<segue reference="2ak-aX-wVl"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
<resources>
|
||||
<systemColor name="secondaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemRedColor">
|
||||
<color red="1" green="0.23137254901960785" blue="0.18823529411764706" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -89,7 +89,7 @@ final class GlassVPNManager {
|
||||
|
||||
private func createNewVPN(_ success: @escaping (_ manager: NETunnelProviderManager) -> Void) {
|
||||
let mgr = NETunnelProviderManager()
|
||||
mgr.localizedDescription = "AppCheck Monitor"
|
||||
mgr.localizedDescription = "AppChk Monitor"
|
||||
let proto = NETunnelProviderProtocol()
|
||||
proto.providerBundleIdentifier = GlassVPNManager.bundleIdentifier
|
||||
proto.serverAddress = "127.0.0.1"
|
||||
|
||||
@@ -10,6 +10,7 @@ class GlassVPNHook {
|
||||
private var cachedNotify: CachedConnectionAlert!
|
||||
private var currentlyRecording: Bool = false
|
||||
|
||||
public var isBackgroundRecording: Bool = false
|
||||
public var forceDisconnectUnresolvable: Bool = false
|
||||
public var forceDisconnectSWCD: Bool = false
|
||||
|
||||
@@ -22,6 +23,7 @@ class GlassVPNHook {
|
||||
setAutoDelete(PrefsShared.AutoDeleteLogsDays)
|
||||
cachedNotify = CachedConnectionAlert()
|
||||
currentlyRecording = PrefsShared.CurrentlyRecording != .Off
|
||||
isBackgroundRecording = PrefsShared.CurrentlyRecording == .Background
|
||||
forceDisconnectUnresolvable = PrefsShared.ForceDisconnectUnresolvableDNS
|
||||
forceDisconnectSWCD = PrefsShared.ForceDisconnectSWCD
|
||||
}
|
||||
@@ -34,6 +36,7 @@ class GlassVPNHook {
|
||||
autoDeleteTimer?.invalidate()
|
||||
cachedNotify = nil
|
||||
currentlyRecording = false
|
||||
isBackgroundRecording = false
|
||||
forceDisconnectUnresolvable = false
|
||||
forceDisconnectSWCD = false
|
||||
}
|
||||
@@ -57,6 +60,7 @@ class GlassVPNHook {
|
||||
case "recording-now":
|
||||
let newState = CurrentRecordingState(rawValue: Int(value) ?? 0)
|
||||
currentlyRecording = newState != .Off
|
||||
isBackgroundRecording = newState == .Background
|
||||
return
|
||||
case "disconnect-unresolvable":
|
||||
forceDisconnectUnresolvable = value == "1"
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
|
||||
@@ -99,8 +99,8 @@ extension PushNotification {
|
||||
guard #available(iOS 10, *), PrefsShared.RestartReminder.WithText else { return }
|
||||
|
||||
schedule(.CantStopMeNowReminder,
|
||||
content: .make("AppCheck disabled",
|
||||
body: "AppCheck can't monitor network traffic because VPN has stopped.",
|
||||
content: .make("AppChk disabled",
|
||||
body: "AppChk can't monitor network traffic because VPN has stopped.",
|
||||
sound: .from(string: PrefsShared.RestartReminder.Sound)),
|
||||
trigger: .make(Date(timeIntervalSinceNow: 5 * 60)),
|
||||
waitUntilDone: true)
|
||||
|
||||
@@ -9,6 +9,7 @@ enum NotificationRequestState {
|
||||
case .authorized: self = .Authorized
|
||||
case .provisional: self = .Provisional
|
||||
case .notDetermined: fallthrough
|
||||
case .ephemeral: fallthrough
|
||||
@unknown default: self = .NotDetermined
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,12 @@ class TVCShareRecording : UITableViewController, UITextViewDelegate, VCEditTextD
|
||||
private lazy var dataSource: [String : [Timestamp]] = RecordingsDB.detailCluster(self.record)
|
||||
|
||||
private lazy var dataSourceKeyValue: [(key: String, value: String)] = [
|
||||
("Notes", " – "), // see delegate below, update reloadNotes() and cellForRowAt
|
||||
("Date", self.weekInYear),
|
||||
("Rec-Length", "\(self.record.duration) sec"),
|
||||
("App-Bundle", self.record.appId ?? " – "),
|
||||
("App-Name", self.record.title ?? " – "),
|
||||
("Notes", " – ") // see delegate below
|
||||
("iOS", UIDevice.current.systemVersion),
|
||||
]
|
||||
|
||||
private lazy var dataSourceLogs: [(domain: String, occurrences: String, enabled: Bool)] = self.dataSource.map {
|
||||
@@ -42,7 +43,7 @@ class TVCShareRecording : UITableViewController, UITextViewDelegate, VCEditTextD
|
||||
private func reloadNotes() {
|
||||
tableView.reloadRows(at: [
|
||||
IndexPath(row: 0, section: 1), // edit field
|
||||
IndexPath(row: 4, section: 2) // display field
|
||||
IndexPath(row: 0, section: 2) // display field
|
||||
], with: .automatic)
|
||||
}
|
||||
|
||||
@@ -152,7 +153,7 @@ class TVCShareRecording : UITableViewController, UITextViewDelegate, VCEditTextD
|
||||
cell = tableView.dequeueReusableCell(withIdentifier: "shareKeyValueCell")!
|
||||
let src = dataSourceKeyValue[indexPath.row]
|
||||
cell.textLabel?.text = src.key
|
||||
let flag = indexPath.row == 4 && shareNotes && hasNotes
|
||||
let flag = indexPath.row == 0 && shareNotes && hasNotes
|
||||
cell.detailTextLabel?.text = flag ? editedNotes : src.value
|
||||
case 3:
|
||||
cell = tableView.dequeueReusableCell(withIdentifier: "shareLogCell")!
|
||||
@@ -187,6 +188,7 @@ class TVCShareRecording : UITableViewController, UITextViewDelegate, VCEditTextD
|
||||
let allowed = dataSourceLogs.filter{ $0.enabled }.map{ $0.domain }
|
||||
let json = try? JSONSerialization.data(withJSONObject: [
|
||||
"v" : 1,
|
||||
"ios" : UIDevice.current.systemVersion,
|
||||
"date" : weekInYear,
|
||||
"duration" : record.duration,
|
||||
"app-bundle" : record.appId ?? "",
|
||||
|
||||
@@ -30,9 +30,9 @@ class VCRecordings: UIViewController, UINavigationControllerDelegate {
|
||||
x.addSheet().addArrangedSubview(TinyMarkdown.load("tut-recording-1"))
|
||||
x.addSheet().addArrangedSubview(TinyMarkdown.load("tut-recording-2"))
|
||||
x.buttonTitleDone = "Got it"
|
||||
x.present {
|
||||
x.present(didClose: {
|
||||
Prefs.DidShowTutorial.Recordings = true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,9 +55,9 @@ class VCRecordings: UIViewController, UINavigationControllerDelegate {
|
||||
let x = TutorialSheet()
|
||||
x.addSheet().addArrangedSubview(TinyMarkdown.load("tut-recording-howto"))
|
||||
x.buttonTitleDone = "Close"
|
||||
x.present() {
|
||||
x.present(didClose: {
|
||||
Prefs.DidShowTutorial.RecordingHowTo = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class TVCChooseAlertTone: UITableViewController {
|
||||
}
|
||||
|
||||
override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
section == 1 ? "AppCheck" : nil
|
||||
section == 1 ? "AppChk" : nil
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
@@ -70,7 +70,7 @@ fileprivate let AvailableSounds: [[(title: String, file: String)]] = [
|
||||
[ // System sounds
|
||||
("None", "#mute"),
|
||||
("Default", "#default")
|
||||
], [ // AppCheck sounds
|
||||
], [ // AppChk sounds
|
||||
("Clock", "clock"),
|
||||
("Drum 1", "drum1"),
|
||||
("Drum 2", "drum2"),
|
||||
|
||||
@@ -36,9 +36,9 @@ class TBCMain: UITabBarController {
|
||||
let x = TutorialSheet()
|
||||
x.addSheet().addArrangedSubview(TinyMarkdown.load("tut-welcome-1"))
|
||||
x.addSheet().addArrangedSubview(TinyMarkdown.load("tut-welcome-2"))
|
||||
x.present {
|
||||
x.present(didClose: {
|
||||
Prefs.DidShowTutorial.Welcome = true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,44 @@ br.vet
|
||||
br.vlog
|
||||
br.wiki
|
||||
br.zlg
|
||||
cn.ac
|
||||
cn.ah
|
||||
cn.bj
|
||||
cn.com
|
||||
cn.cq
|
||||
cn.edu
|
||||
cn.fj
|
||||
cn.gd
|
||||
cn.gov
|
||||
cn.gs
|
||||
cn.gx
|
||||
cn.gz
|
||||
cn.ha
|
||||
cn.hb
|
||||
cn.he
|
||||
cn.hi
|
||||
cn.hl
|
||||
cn.hn
|
||||
cn.jl
|
||||
cn.js
|
||||
cn.jx
|
||||
cn.ln
|
||||
cn.mil
|
||||
cn.net
|
||||
cn.nm
|
||||
cn.nx
|
||||
cn.org
|
||||
cn.qh
|
||||
cn.sc
|
||||
cn.sd
|
||||
cn.sh
|
||||
cn.sn
|
||||
cn.sx
|
||||
cn.tj
|
||||
cn.xj
|
||||
cn.xz
|
||||
cn.yn
|
||||
cn.zj
|
||||
co.a
|
||||
co.b
|
||||
co.com
|
||||
@@ -105,10 +143,10 @@ co.y
|
||||
er.com
|
||||
er.edu
|
||||
er.gov
|
||||
er.ind
|
||||
er.mil
|
||||
er.net
|
||||
er.org
|
||||
er.ind
|
||||
es.com
|
||||
es.edu
|
||||
es.gob
|
||||
@@ -207,6 +245,15 @@ in.res
|
||||
je.co
|
||||
je.net
|
||||
je.org
|
||||
jp.ac
|
||||
jp.ad
|
||||
jp.co
|
||||
jp.ed
|
||||
jp.go
|
||||
jp.gr
|
||||
jp.lg
|
||||
jp.ne
|
||||
jp.or
|
||||
kr.ac
|
||||
kr.busan
|
||||
kr.chungbuk
|
||||
@@ -256,6 +303,11 @@ lk.org
|
||||
lk.sch
|
||||
lk.soc
|
||||
lk.web
|
||||
mo.com
|
||||
mo.edu
|
||||
mo.gov
|
||||
mo.net
|
||||
mo.org
|
||||
ms.com
|
||||
ms.edu
|
||||
ms.gov
|
||||
@@ -477,6 +529,16 @@ tt.org
|
||||
tt.pro
|
||||
tt.tel
|
||||
tt.travel
|
||||
tw.club
|
||||
tw.com
|
||||
tw.ebiz
|
||||
tw.edu
|
||||
tw.game
|
||||
tw.gov
|
||||
tw.idv
|
||||
tw.mil
|
||||
tw.net
|
||||
tw.org
|
||||
ua.cherkassy
|
||||
ua.cherkasy
|
||||
ua.chernigov
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
___Co-Occurrence___ allows you to find requests that happen often at the same time as the selected domain. Hence it will give you a hint what Apps might be involved in the activity.
|
||||
___Co-Occurrence___ allows you to find requests that happen often at the same time as the selected domain. Hence, it will give you a hint what apps might be involved in the activity.
|
||||
|
||||
How do you interpret these results? Lets look at an example:
|
||||
|
||||
<IMG>
|
||||
|
||||
The domain __example.org__ had __14__ requests with an _average time divergence_ of __0.71 seconds__. That is, these 14 domain calls happend, on average, less then a second before or after the original request of the selected domain.
|
||||
The domain __example.org__ has __14__ requests with an _average time divergence_ of __0.71 seconds__. That is, these 14 domain calls happend, on average, less then a second before or after the original request of the selected domain.
|
||||
|
||||
Close temporal proximity and high occurrence counts are both indicators for domain correlation. Results are sorted by a ranking index (__9.__) which strikes a balance between the two. Preferring entries with higher counts as well as low time divergence.
|
||||
|
||||
_Tip:_ As a visual guide you can look for the colored bar beside each value. The larger the bar, the greater the correlation.
|
||||
_Tip:_ As a visual guide, you can look for the colored bar beside each value. The larger the bar, the greater the correlation.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# What are Recordings?
|
||||
|
||||
Similar to the default logging, recordings will intercept every request and log it for later review. App recordings are usually 1 – 4 minutes long and cover a single application. You can utilize recordings for App analysis or to get a ground truth on background traffic.
|
||||
Similar to the default logging, recordings will intercept every request and log it for later review. App recordings are usually 1 – 4 minutes long and cover a single application. You can utilize recordings for app analysis or to get a ground truth on background traffic.
|
||||
|
||||
Optionally, you can help us by providing your app specific recordings. Together with your findings we can create a community driven privacy monitor. The research results will help you and others avoid Apps that unnecessarily share data with third-party providers.
|
||||
Optionally, you can help us by providing your app recordings. With your findings we can create a community driven privacy monitor. The research results will help you and others avoid apps that, unnecessarily, share data with third-party providers.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Contribute
|
||||
|
||||
This step is completely __optional__. You can choose to share your results with us. We can compare similar applications and suggest privacy friendly alternatives. Together with other likeminded individuals we can increase the awareness for privacy friendly design.
|
||||
This step is completely __optional__. You can choose to share your results with us. We can compare similar applications and suggest privacy friendly alternatives. Together with other likeminded individuals, we can increase the awareness for privacy friendly design.
|
||||
|
||||
Thank you very much.
|
||||
|
||||
@@ -4,17 +4,17 @@ Before you begin, there are two types of recordings: app specific recordings and
|
||||
|
||||
### Important notice
|
||||
|
||||
During the recording all logging filter are paused. This means blocked domains are not being blocked and ignored domains show up regardless. This is necessary for comparability reasons.
|
||||
During the recording all logging filters are paused. This means, blocked domains are not being blocked and ignored domains show up regardless. This is necessary for comparability reasons.
|
||||
|
||||
## App recording
|
||||
|
||||
Before you begin make sure that you quit all running applications and wait a few seconds. Tap on the 'App' recording button and switch to the application you'd like to inspect. Use the App as you would normally. Try to get to all corners and functionality the App provides. When you feel that you have captured enough content, come back to _AppCheck_ and stop the recording.
|
||||
Before you begin, make sure that you quit all running applications and wait a few seconds. Tap on the 'App' recording button and switch to the application you would like to inspect. Use the app as you would normally. Try to get to all corners and functionality the app provides. When you feel that you have captured enough content, come back to _AppChk_ and stop the recording.
|
||||
|
||||
## Background recording
|
||||
|
||||
Will answer one simple question: What communications happen while you aren't using your device. You should solely start a background recording when you know you aren't going to use your device in the near future. For example, before you go to bed.
|
||||
As soon as you start using your device, you should stop the recording to avoid distorting the results.
|
||||
Answers one simple question: What communications happen while you aren't using your device. You should only start a background recording when you know you aren't going to use your device in the near future. For example, before you go to bed.
|
||||
As soon as you start using your device, you should stop the recording to avoid further diverging the results.
|
||||
|
||||
## Afterwards
|
||||
|
||||
Upon completion you will find your recording in the section below. You can review your results and remove any user specific information if necessary.
|
||||
Upon completion you will find your recording in the section below. You can review your results and remove any sensitive user information if necessary.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Welcome
|
||||
|
||||
AppCheck helps you identify which applications communicate with third parties. It does so by logging network requests. AppCheck learns only the destination addresses, not the actual data that is exchanged.
|
||||
AppChk helps you identify which applications communicate with third parties. It does so by logging network requests. AppChk learns only the destination addresses, not the actual data that is exchanged.
|
||||
|
||||
Your data belongs to you. Therefore, monitoring and analysis take place on your device only. The app does not share any data with us or any other third-party. Unless you choose to.
|
||||
Your data belongs to you. Therefore, monitoring and analysis take place on your device only. AppChk does not share any data with us or any other third-party. Unless you choose to.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# How it works
|
||||
|
||||
AppCheck creates a local VPN tunnel to intercept all network connections. For each connection AppCheck looks into the DNS headers only, namely the domain names.
|
||||
These domain names are logged in the background while the VPN is active. That means, AppCheck does not have to be active in the foreground. You can close the app and come back later to see the results.
|
||||
AppChk creates a local VPN tunnel to intercept all network connections. For each connection, AppChk looks into the DNS headers only, namely the domain names.
|
||||
These domain names are logged in the background while the VPN is active. That means, AppChk does not have to be active in the foreground. You can close the app and come back later to see the results.
|
||||
|
||||
Reference in New Issue
Block a user