Преглед изворни кода

Add onClientAddress callbacks to Mobile Library API

- Fix: don't redact ClientAddress value

- Fix: ensure Untunneled notices excluded from diagnostics
Rod Hynes пре 4 година
родитељ
комит
e3e40a4992

+ 5 - 0
MobileLibrary/Android/PsiphonTunnel/PsiphonTunnel.java

@@ -110,6 +110,7 @@ public class PsiphonTunnel {
         default public void onConnected() {}
         default public void onHomepage(String url) {}
         default public void onClientRegion(String region) {}
+        default public void onClientAddress(String address) {}
         default public void onClientUpgradeDownloaded(String filename) {}
         default public void onClientIsLatestVersion() {}
         default public void onSplitTunnelRegions(List<String> regions) {}
@@ -953,6 +954,9 @@ public class PsiphonTunnel {
                 mHostService.onHomepage(notice.getJSONObject("data").getString("url"));
             } else if (noticeType.equals("ClientRegion")) {
                 mHostService.onClientRegion(notice.getJSONObject("data").getString("region"));
+            } else if (noticeType.equals("ClientAddress")) {
+                diagnostic = false;
+                mHostService.onClientAddress(notice.getJSONObject("data").getString("address"));
             } else if (noticeType.equals("SplitTunnelRegions")) {
                 JSONArray splitTunnelRegions = notice.getJSONObject("data").getJSONArray("regions");
                 ArrayList<String> regions = new ArrayList<String>();
@@ -961,6 +965,7 @@ public class PsiphonTunnel {
                 }
                 mHostService.onSplitTunnelRegions(regions);
             } else if (noticeType.equals("Untunneled")) {
+                diagnostic = false;
                 mHostService.onUntunneledAddress(notice.getJSONObject("data").getString("address"));
             } else if (noticeType.equals("BytesTransferred")) {
                 diagnostic = false;

+ 5 - 0
MobileLibrary/Android/SampleApps/TunneledWebView/app/src/main/java/ca/psiphon/tunneledwebview/MainActivity.java

@@ -300,6 +300,11 @@ public class MainActivity extends AppCompatActivity
         logMessage("client region: " + region);
     }
 
+    @Override
+    public void onClientAddress(String address) {
+        logMessage("client address: " + address);
+    }
+
     private static String readInputStreamToString(InputStream inputStream) throws IOException {
         return new String(readInputStreamToBytes(inputStream), "UTF-8");
     }

+ 6 - 0
MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h

@@ -226,6 +226,12 @@ WWAN or vice versa or VPN state changed
  */
 - (void)onClientRegion:(NSString * _Nonnull)region;
 
+/*!
+ Called after the handshake with the Psiphon server, with the client address as seen by the server.
+ @param address  The Internet address of the client, IP:port, as seen by the server.
+ */
+- (void)onClientAddress:(NSString * _Nonnull)address;
+
 /*!
  Called to report that split tunnel is on for the given regions.
  @param regions  The regions split tunnel is on for.

+ 17 - 0
MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.m

@@ -994,6 +994,21 @@ typedef NS_ERROR_ENUM(PsiphonTunnelErrorDomain, PsiphonTunnelErrorCode) {
             });
         }
     }
+    else if ([noticeType isEqualToString:@"ClientAddress"]) {
+        diagnostic = FALSE;
+
+        id address = [notice valueForKeyPath:@"data.address"];
+        if (![address isKindOfClass:[NSString class]]) {
+            [self logMessage:[NSString stringWithFormat: @"ClientAddress notice missing data.address: %@", noticeJSON]];
+            return;
+        }
+
+        if ([self.tunneledAppDelegate respondsToSelector:@selector(onClientAddress:)]) {
+            dispatch_sync(self->callbackQueue, ^{
+                [self.tunneledAppDelegate onClientAddress:address];
+            });
+        }
+    }
     else if ([noticeType isEqualToString:@"SplitTunnelRegions"]) {
         id regions = [notice valueForKeyPath:@"data.regions"];
         if (![regions isKindOfClass:[NSArray class]]) {
@@ -1008,6 +1023,8 @@ typedef NS_ERROR_ENUM(PsiphonTunnelErrorDomain, PsiphonTunnelErrorCode) {
         }
     }
     else if ([noticeType isEqualToString:@"Untunneled"]) {
+        diagnostic = FALSE;
+
         id address = [notice valueForKeyPath:@"data.address"];
         if (![address isKindOfClass:[NSString class]]) {
             [self logMessage:[NSString stringWithFormat: @"Untunneled notice missing data.address: %@", noticeJSON]];

+ 3 - 1
psiphon/notice.go

@@ -675,9 +675,11 @@ func NoticeClientRegion(region string) {
 // NoticeClientAddress is the client's public network address, the IP address
 // and port, as seen by the server and reported to the client in the
 // handshake.
+//
+// Note: "address" should remain private and not included in diagnostics logs.
 func NoticeClientAddress(address string) {
 	singletonNoticeLogger.outputNotice(
-		"ClientAddress", 0,
+		"ClientAddress", noticeSkipRedaction,
 		"address", address)
 }