逆向Preferences中关于VPN部分的问题

一点微小的工作

void createVPN(NSString* server, NSString* username, NSString* password, NSString* type)
{
    NSBundle* vpn = [NSBundle bundleWithPath:@"/System/Library/PreferenceBundles/VPNPreferences.bundle"];

    if ([vpn load] == NO)
    {
        DbgLog(@"load vpn failed");
        return;
    }

    VPNConnectionStore* vpnStore;
    VPNSetupListController* vpnSetup;

    vpnStore = [objc_getClass("VPNConnectionStore") sharedInstance];

    for (NEConfiguration* cfg in [vpnStore configurations])
    {
        NSString* uuid = [[cfg identifier] UUIDString];

        if ([vpnStore respondsToSelector:@selector(deleteVPNWithServiceID:)])
        {
            [vpnStore deleteVPNWithServiceID:uuid];
        }
        else if ([vpnStore respondsToSelector:@selector(deleteVPNWithServiceID:withGrade:)])
        {
            [vpnStore deleteVPNWithServiceID:uuid withGrade:nil];
        }
        else
        {
            DbgLog(@"cant delete vpn");
            return;
        }
    }

    sleep(2);

    vpnSetup = [[objc_getClass("VPNSetupListController") alloc] init];
    [vpnSetup setDisplayName:@"displayName" forSpecifier:nil];
    [vpnSetup setVPNType:(__bridge CFStringRef)type forSpecifier:nil];
    [vpnSetup setServer:server forSpecifier:nil];
    [vpnSetup setUsername:username forSpecifier:nil];
    [vpnSetup setPassword:password forSpecifier:nil];
    [vpnSetup setSendAllTraffic:[NSNumber numberWithBool:YES] forSpecifier:nil];
    [vpnSetup setPPTPEncryptionLevel:@1 forSpecifier:nil];

    if ([vpnSetup respondsToSelector:@selector(saveConfigurationSettings)])
    {
        [vpnSetup saveConfigurationSettings];
    }
    else if ([vpnSetup respondsToSelector:@selector(_saveConfigurationSettings)])
    {
        [vpnSetup _saveConfigurationSettings];
    }
    else
    {
        DbgLog(@"cant saveConfigurationSettings");
        return;
    }

    sleep(2);
}
VPNStatus::Status connectVPN(BOOL connect)
{
    VPNConnectionStore*     vpnStore;
    VPNConnection*          vpn;
    dispatch_semaphore_t    semaphore;
    NSNotificationCenter*   center;
    id                      changeObserver;

    if (loadVPNBundle() == NO)
        return VPNStatus::NotConnected;

    vpnStore = [objc_getClass("VPNConnectionStore") sharedInstance];
    vpn = [vpnStore currentConnectionWithGrade:[vpnStore currentOnlyConnectionGrade]];
    if (vpn == nil)
        return VPNStatus::NotConnected;

    DbgLog(@"vpn = %@", vpn);
    DbgLog(@"session_status = %d, status = %ld, statusText = %@", [vpn session_status], [vpn status], [vpn statusText]);

    if (connect == NO && VPNStatus::fromStatus([vpn status]) == VPNStatus::NotConnected)
        return VPNStatus::NotConnected;

    semaphore = dispatch_semaphore_create(0);
    center    = [NSNotificationCenter defaultCenter];

    changeObserver = [center
                        addObserverForName:@"VPNConnectionStatusChanged"
                        object:nil
                        queue:[NSOperationQueue mainQueue]
                        usingBlock:^(NSNotification* note) {
                            NSString*       name;
                            VPNConnection*  vpn;
                            // NSDictionary*   userInfo;

                            name     = [note name];
                            vpn      = [note object];
                            // userInfo = [note userInfo];

                            DbgLog(@"name     = %@", name);
                            DbgLog(@"object   = %@", vpn);
                            // DbgLog(@"userInfo = %@", userInfo);
                            DbgLog(@"session_status = %d, status = %ld, statusText = %@", [vpn session_status], [vpn status], [vpn statusText]);

                            switch (VPNStatus::fromStatus([vpn status]))
                            {
                                case VPNStatus::Connecting:
                                case VPNStatus::Disconnecting:
                                    break;

                                default:
                                    dispatch_semaphore_signal(semaphore);
                            }
                        }
                    ];

    connect ? [vpn connect] : [vpn disconnect];

    const int64_t tenSeconds = 15ll * 1000 * 1000 * 1000;

    if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, tenSeconds)) != 0)
    {
        DbgLog(@"connectVPN timeout");
        [vpn disconnect];
        dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, tenSeconds));
    }

    [center removeObserver:changeObserver];

    DbgLog(@"connectVPN done");

    return VPNStatus::fromStatus([vpn status]);
}
1 个赞