??????????Э???????????????????Э???VPN???????
????[manager setProtocol:p];
????IPSec??IKEv2Э?鶼???????????????裨O(shè)n-demand???????????????????????????????????????????????????????????豸??????????????????????VPN?????????????????????????????????????????????????????á???????????????onDemandEnabled???YES??
????[[NEVPNManager sharedManager] setOnDemandEnabled:YES];
?????????????????????????????????on-demand?????????????????????????????Щ???????Щ???????“???????”???????????????????VPN?????????????????????????????onDemandRules?????????????飬??????????VPN????????????????????磬????????????????????????????????????Apple.com?????VPN?????????VPN???????????????????????????????????????????ó???????????????????VPN????????????е?iOS????????????????VPN?????????????????????????Ч?????????????NEOnDemandRuleConnect????NetworkExtension????У?????????Щ??????????????塣NEOnDemandRuleConnect???????е??????塣??????????????iOS?????????????????VPN??????????????????????????????????VPN?????????????????NEOnDemandRuleConnect?????????
????[[NEVPNManager sharedManager] setOnDemandEnabled:YES];
????NSMutableArray *rules = [[NSMutableArray alloc] init];
????NEOnDemandRuleConnect *connectRule = [NEOnDemandRuleConnect new];
????[rules addObject:connectRule];
????[[NEVPNManager sharedManager] setOnDemandRules:array];
????????????????????VPN?????????????????
????[manager setLocalizedDescription:@"[You VPN configuration name]"];
?????????????н???????????????н????檔??????????????????????aveToPreferencesWithCompletionHandler: method:??
????[manager saveToPreferencesWithCompletionHandler:^(NSError *error) {
????if(error) {
????NSLog(@"Save error: %@"?? error);
????}
????else {
????NSLog(@"Saved!");
????}
????}];
????????VPN connection
????????????????????????????????NEVPNManager????????????connection???????????NEVPNConnection?????????????VPN??????????????????VPN????????????????????NEVPNConnection???startVPNTunnelAndReturnError:??????
????- (IBAction)buttonPressed:(id)sender {
????NSError *startError;
????[[NEVPNManager sharedManager].connection startVPNTunnelAndReturnError:&startError];
????if(startError) {
????NSLog(@"Start error: %@"?? startError.localizedDescription);
????} else {
????NSLog(@"Connection established!");
????}
????}
??????????豸?????г?????????????????????μ????????????????????????????????????????????stopVPNTunnel?????????VPN?????????????
???????′???????gist??
- (void)viewDidLoad
{
[super viewDidLoad];
// init VPN manager
self.vpnManager = [NEVPNManager sharedManager];
// load config from perference
[_vpnManager loadFromPreferencesWithCompletionHandler:^(NSError *error) {
if (error) {
NSLog(@"Load config failed [%@]"?? error.localizedDescription);
return;
}
NEVPNProtocolIPSec *p = _vpnManager.protocol;
if (p) {
// Protocol exists.
// If you don't want to edit it?? just return here.
} else {
// create a new one.
p = [[NEVPNProtocolIPSec alloc] init];
}
// config IPSec protocol
p.username = @"[Your username]";
p.serverAddress = @"[Your server address]";;
// Get password persistent reference from keychain
// If password doesn't exist in keychain?? should create it beforehand.
// [self createKeychainValue:@"your_password" forIdentifier:@"VPN_PASSWORD"];
p.passwordReference = [self searchKeychainCopyMatching:@"VPN_PASSWORD"];
// PSK
p.authenticationMethod = NEVPNIKEAuthenticationMethodSharedSecret;
// [self createKeychainValue:@"your_psk" forIdentifier:@"PSK"];
p.sharedSecretReference = [self searchKeychainCopyMatching:@"PSK"];
/*
// certificate
p.identityData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"]];
p.identityDataPassword = @"[Your certificate import password]";
*/
p.localIdentifier = @"[VPN local identifier]";
p.remoteIdentifier = @"[VPN remote identifier]";
p.useExtendedAuthentication = YES;
p.disconnectOnSleep = NO;
_vpnManager.protocol = p;
_vpnManager.localizedDescription = @"IPSec Demo";
[_vpnManager saveToPreferencesWithCompletionHandler:^(NSError *error) {
if (error) {
NSLog(@"Save config failed [%@]"?? error.localizedDescription);
}
}];
}];
}
- (IBAction)startVPNConnection:(id)sender {
//[[VodManager sharedManager] installVPNProfile];
NSError *startError;
[_vpnManager.connection startVPNTunnelAndReturnError:&startError];
if (startError) {
NSLog(@"Start VPN failed: [%@]"?? startError.localizedDescription);
}
}
#pragma mark - KeyChain
static NSString * const serviceName = @"im.zorro.ipsec_demo.vpn_config";
- (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier {
NSMutableDictionary *searchDictionary = [[NSMutableDictionary alloc] init];
[searchDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
NSData *encodedIdentifier = [identifier dataUsingEncoding:NSUTF8StringEncoding];
[searchDictionary setObject:encodedIdentifier forKey:(__bridge id)kSecAttrGeneric];
[searchDictionary setObject:encodedIdentifier forKey:(__bridge id)kSecAttrAccount];
[searchDictionary setObject:serviceName forKey:(__bridge id)kSecAttrService];
return searchDictionary;
}
- (NSData *)searchKeychainCopyMatching:(NSString *)identifier {
NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
// Add search attributes
[searchDictionary setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
// Add search return types
// Must be persistent ref !!!!
[searchDictionary setObject:@YES forKey:(__bridge id)kSecReturnPersistentRef];
CFTypeRef result = NULL;
SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary?? &result);
return (__bridge_transfer NSData *)result;
}
- (BOOL)createKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier {
NSMutableDictionary *dictionary = [self newSearchDictionary:identifier];
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)dictionary);
NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
[dictionary setObject:passwordData forKey:(__bridge id)kSecValueData];
status = SecItemAdd((__bridge CFDictionaryRef)dictionary?? NULL);
if (status == errSecSuccess) {
return YES;
}
return NO;
}
?????????