在macOS(沙盒)中检测VPN连接

时间:2019-02-14 19:40:46

标签: objective-c cocoa vpn

我试图从沙盒应用程序中检测VPN连接是否在macOS中处于活动状态,但是很难为各种VPN服务找到通用的解决方案。目前,我正在使用2种方法(请参阅下文),但是这些方法对于所有VPN服务/客户端似乎都不可靠。

以下方法对于Cisco AnyConnect客户端和我的VPN服务非常有效,但是对于其他VPN客户端/服务,例如Viscosity(以及可能的其他OpenVPN客户端),这些方法根本不起作用。将非活动 -VPN连接的值与活动 -VPN连接的值进行比较时,在DNS服务器或主要服务值中均未检测到更改。

我还应该提到我已经见过this post,并且认为这不是解决此特定用例的好方法。我不想假设对于每个VPN服务,当VPN连接处于活动状态时,总是会只有 个主机。

任何指导将不胜感激。先感谢您。

1)查看当前的DNS服务器(取自here

- (NSString *)getDNSAddressesCSV
{
    NSMutableArray *addresses = [NSMutableArray new];

    union res_sockaddr_union servers[NI_MAXSERV];

    int serversFound = res_9_getservers(_state, servers, NI_MAXSERV);

    char hostBuffer[NI_MAXHOST];

    for (int i = 0; i < serversFound; i ++)
    {
        union res_sockaddr_union s = servers[i];

        if (s.sin.sin_len > 0)
        {
            if (EXIT_SUCCESS == getnameinfo((struct sockaddr *)&s.sin,  // Pointer to your struct sockaddr
                                            (socklen_t)s.sin.sin_len,   // Size of this struct
                                            (char *)&hostBuffer,        // Pointer to hostname string
                                            sizeof(hostBuffer),         // Size of this string
                                            nil,                        // Pointer to service name string
                                            0,
                                            NI_NUMERICHOST))
            {          // Flags given
                [addresses addObject:[NSString stringWithUTF8String:hostBuffer]];
            }
        }
    }

    return [addresses componentsJoinedByString:@","];
}



和2)从SCDynamicStore获取当前的主要服务(取自here

- (NSString *) getVPNService
{
    SCDynamicStoreRef dynamicStoreDomainState = SCDynamicStoreCreate(NULL,
                                                                     CFSTR("appNameGoesHere"),
                                                                     NULL,
                                                                     NULL);
    if (dynamicStoreDomainState)
    {
        NSString *netIPv4Key = [NSString stringWithFormat:@"%@/%@/%@/%@",
                                kSCDynamicStoreDomainState,
                                kSCCompNetwork,
                                kSCCompGlobal,
                                kSCEntNetIPv4];

        NSMutableDictionary *netIPv4Dictionary = (NSMutableDictionary *) CFBridgingRelease(SCDynamicStoreCopyValue(dynamicStoreDomainState, (CFStringRef)netIPv4Key));

        if (netIPv4Dictionary )
        {
            NSString *primaryService = [netIPv4Dictionary objectForKey:(NSString *)kSCDynamicStorePropNetPrimaryService];

            if (primaryService)
            {
                CFRelease(dynamicStoreDomainState);
                CFRelease((__bridge CFTypeRef)(netIPv4Key));
                return primaryService;
            }
            else
            {
                CFRelease(dynamicStoreDomainState);
                CFRelease((__bridge CFTypeRef)(netIPv4Key));
                return @"";
            }
        }

        CFRelease(dynamicStoreDomainState);
    }

    return @"";
}

1 个答案:

答案 0 :(得分:0)

在Google上,请点击此处:https://forums.developer.apple.com/thread/113491

  

Apple员工表示不存在此类公共API。

也来自Google,请看这里:https://superuser.com/questions/577094/how-can-i-tell-if-os-x-is-connected-to-a-vpn-network-from-the-command-line

  

最后一个Apple Script解决方案可能会让您感兴趣