Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to detect iphone's VPN connectivity?

I need to detect whether iphone is connected to VPN or not, programatically. I am developing a app which try to load URL, this page open only when device is connected to VPN. Before loading this URL I need to check VPN connectivity. I tried the following . But this is not working as expected.

- (BOOL)checkForVPNConnectivity {
  NSDictionary *dict = (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
  //NSLog(@"cfnetwork proxy setting : %@", dict);
  return [dict count] > 0; 
 }
like image 473
Kashyap Avatar asked Apr 29 '13 17:04

Kashyap


People also ask

How do you know if your phone is connected to VPN?

Tip: When you're connected, you'll see VPN on . Open your phone's Settings app. VPN. If you can't find it, search for "VPN." If you still can't find it, get help from your device manufacturer.

Can iOS apps detect VPN?

Using these loopholes app developers are able to detect users that have an active VPN connection and then correlate a user's true cellular IP to their online activity conducted while using a VPN. This allows Apple or any developer to track VPN use to a particular IP, device, and/or person.


2 Answers

I do not believe that one should determine VPN connectivity by checking for a non-zero number of elements in the CFNetworkCopySystemProxySettings(). (For example, I see entries when on a WiFi network, but not on a VPN.)

So, two observations:

  1. I would consider using the SystemConfiguration.framework and use the following code with the hostname of something on your VPN:

    - (BOOL)checkForConnectivity:(NSString *)hostName
    {
        BOOL success = false;
    
        SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
        SCNetworkReachabilityFlags flags;
        success = SCNetworkReachabilityGetFlags(reachability, &flags);
        CFRelease(reachability);
    
        NSLog(@"success=%x", flags);
    
        // this is the standard non-VPN logic, you might have to alter it for VPN connectivity
    
        BOOL isAvailable = success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
        if (isAvailable) {
            NSLog(@"Host is reachable: %d", flags);
            return YES;
        }else{
            NSLog(@"Host is unreachable");
            return NO;
        }
    }
    

    Assuming that success is non-zero, you might have to do some empirical research on the setting of the bits in flags. See SCNetworkReachability Reference for the technical definitions of these flags. I've heard claims that they get kSCNetworkReachabilityFlagsReachable | kSCNetworkReachabilityFlagsTransientConnection when the VPN is connected, but I don't have a VPN, so I cannot test that claim. I'd suggest trying it with and without the VPN up and see if you get different flags returned.

  2. Unrelated to the problem at hand, your code sample will leak. If using ARC, don't forget to use CFBridgingRelease or __bridge_transfer. Or regardless of whether in ARC or not, explicitly call CFRelease before you return.

    If you run the static analyzer (press shift+command+B or choose "Analyze" from the "Product" menu) in recent versions of Xcode, it should warn you about the memory management of Core Foundation calls.

    Anyway, this is how I'd be inclined to handle it in ARC:

    - (BOOL)checkForVPNConnectivity
    {
        NSDictionary *dict = CFBridgingRelease(CFNetworkCopySystemProxySettings());
    
        return [dict count] > 0;
    }
    
like image 97
Rob Avatar answered Nov 14 '22 23:11

Rob


Simple using this method you can acheive. The list of keys has been changed since iOS 12 and iOS 13

2 keys have been added

utun1 and utun2

so the function should be:

static func isConnectedToVPN() -> Bool {

let cfDict = CFNetworkCopySystemProxySettings()
let nsDict = cfDict!.takeRetainedValue() as NSDictionary
let keys = nsDict["__SCOPED__"] as! NSDictionary
for key: String in keys.allKeys as! [String] {
       if (key == "tap" || key == "tun" || key == "ppp" || key == "ipsec" || key == "ipsec0" || key == "utun1" || key == "utun2") {
           return true
       }
   }
   return false

}

like image 29
Shahbaz Akram Avatar answered Nov 14 '22 21:11

Shahbaz Akram