一点微小的工作
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]);
}