5

I'm trying to make a custom TunnelProvider network extension by starting with the XCode template for the TunnelProvider and then adding the code to the host app in order to configure it and start it.

I am using an instance of NETunnelProviderManager to configure it, and when I call saveToPreferencesWithCompletionHandler: I get success (error = 0). However, when I call startVPNTunnelAndReturnError: on the (non-zero) connection I always get the below error:

Error Domain=NEVPNErrorDomain Code=1 "(null)"

I have read through all of the related Apple documentation as well as tried to make my program look as close as possible to the SimpleTunnel test program, however I cannot determine why I am getting this "1" (which seems to indicate a configuration issue).

I've seen a few other people with this same problem in posts around the net, but no solutions.

I have the special entitlements required and I know that is not the issue since after using the proper provisioning profile I was able to see the popup confirming I want to add a VPN when I run the app, and then it get's added in Settings under VPN.

Here is my code in case it is relevant:

NETunnelProviderManager * man = [[NETunnelProviderManager alloc] init];       
NETunnelProviderProtocol *protocol = [[NETunnelProviderProtocol alloc] init];

[protocol setServerAddress:@"aaa.bbb.ccc.ddd"]; // not actual value
[protocol setUsername:@"testuser"];

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];

NSData *data = [[NSData alloc] init];
[dictionary setObject:@"UUID" forKey:(id)kSecAttrService];
[dictionary setObject:data forKey:(id)kSecValueData];
[dictionary setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(id)kSecAttrAccessible];
[dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(id)kSecClass];
[dictionary setObject:(__bridge id)kCFBooleanTrue forKey:(id)kSecReturnPersistentRef];

CFTypeRef passwordRef = nil;

OSStatus delStatus = SecItemDelete((__bridge CFDictionaryRef)dictionary);
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dictionary, &passwordRef);

[protocol setPasswordReference:(__bridge NSData * _Nullable)(passwordRef)];

man.protocolConfiguration = protocol;
man.localizedDescription = @"My VPN";
man.onDemandEnabled = false;  
man.enabled = true;

[man saveToPreferencesWithCompletionHandler:^(NSError *err) {
    NSLog(@"saved preferences: error = %@", err);
    [man.connection startVPNTunnelAndReturnError:&err];        
    NSLog(@"after start tunnel: error = %@", err);
}];
Coding Duchess
  • 6,445
  • 20
  • 113
  • 209
Locksleyu
  • 5,192
  • 8
  • 52
  • 77

1 Answers1

4

I discovered that if I call loadFromPreferencesWithCompletionHandler: before trying to start the tunnel (but after saveToPreferencesWithCompletionHandler), this error goes away I am able to get things proceed a little farther.

However I run into more problems after that. So for the time being I am going to analyze the SimpleTunnel program a bit more.

Locksleyu
  • 5,192
  • 8
  • 52
  • 77
  • As you said, you must call loadFromPreferencesWithCompletionHandler before saveToPreferencesWithCompletionHandler (It's written at the saveToPreferencesWithCompletionHandler documentation). Which errors you get after that? – Witterquick Feb 19 '16 at 09:31
  • Though I did get some errors (I don't remember the exact ones though), now that I think of it the biggest issue is that I would have had to implement alot of stuff in order to get a tunnel working. So starting with the sample program saved me a lot of time since it already had all that stuff, though I had to (partially) learn swift. – Locksleyu Feb 19 '16 at 13:44
  • @Locksleyu I'm facing same issue for first time, did you resolved ? As you said I'm calling first loadFromPreferencesWithCompletionHandler in success of that saving pref => after start tunnel. is anything I'm doing wrong https://stackoverflow.com/questions/47550706/error-domain-nevpnerrordomain-code-1-null-while-connecting-vpn-server here is my question can you please help me? – Shrikant K Nov 29 '17 at 11:35
  • Can you post your working code please? I facing same issue while connecting for first time, but it get connect on second request. – Mukesh Lokare Nov 29 '17 at 12:39