OpenVPNAdapter icon indicating copy to clipboard operation
OpenVPNAdapter copied to clipboard

tunnel provider

Open wangchangfei opened this issue 8 years ago • 16 comments

Have you finished tunnel provider yet?Can you provide me with demo?

wangchangfei avatar Feb 24 '17 02:02 wangchangfei

Alas, but I've not finished it yet, didn't have enough spare time. I hope I can do it this weekend.

ss-abramchuk avatar Feb 24 '17 08:02 ss-abramchuk

Any update?

t4nja avatar Mar 14 '17 10:03 t4nja

Tunnel provider itself is almost finished. Only handling of events and errors are left. I'll deal with this in a couple of days.

ss-abramchuk avatar Mar 14 '17 10:03 ss-abramchuk

Any update?

wangchangfei avatar Apr 29 '17 15:04 wangchangfei

Is it all right now?

oneLeaf2012 avatar Oct 14 '17 14:10 oneLeaf2012

@ss-abramchuk I have couple of Questions

  1. If we use open adapter framework , then apple approve it or not.
  2. PacketTunnelProvider where we used this class , there is such info in readme

visionstech avatar Feb 23 '18 13:02 visionstech

Hi @visionstech,

  1. This framework doesn't use any private API so the only obstacle you can face is the licence. I don't mind if you use my code but openvpn3 library is licensed under AGPL-3 that incompatible with AppStore rules. You can try to ask openvpn developers to change the license for you.
  2. PacketTunnelProvider is a part of Packet Tunnel Provider app extension. When you add new app extension target to your project you will find that class there.

ss-abramchuk avatar Feb 23 '18 14:02 ss-abramchuk

@ss-abramchuk

Thanks for reply I have follow the instruction & integrate the openVPN Adapter framework but it does not connect to our open VPN server & there is no error. Can you please me know ,how we will debug the extension?

Code to setup configuration `func setUPVPNConfig() { NETunnelProviderManager.loadAllFromPreferences { (managers, error) in guard error == nil else { // Handle an occured error return }

        self.providerManager = managers?.first ?? NETunnelProviderManager()
        
        self.providerManager.loadFromPreferences(completionHandler: { (error) in
            guard error == nil else {
                // Handle an occured error
                return
            }
            
            // Assuming the app bundle contains a configuration file named 'client.ovpn' lets get its
            // Data representation
            guard
                let configurationFileURL = Bundle.main.url(forResource: "config", withExtension: "ovpn"),
                let configurationFileContent = try? Data(contentsOf: configurationFileURL)
                else {
                    fatalError()
            }
            
            let tunnelProtocol = NETunnelProviderProtocol()
            
            // If the ovpn file doesn't contain server address you can use this property
            // to provide it. Or just set an empty string value because `serverAddress`
            // property must be set to a non-nil string in either case.
            tunnelProtocol.serverAddress = ""
            
            // The most important field which MUST be the bundle ID of our custom network
            // extension target.
        tunnelProtocol.providerBundleIdentifier = "com.visions.DigibitVPNApp.Extension"
            
            // Use `providerConfiguration` to save content of the ovpn file.
            tunnelProtocol.providerConfiguration = ["ovpn": configurationFileContent]
            
            // Provide user credentials if needed. It is highly recommended to use
            // keychain to store a password.
            tunnelProtocol.username = "test"
             let passwordRef = KeychainService.loadPasswordData()
            tunnelProtocol.passwordReference = passwordRef // A persistent keychain reference to an item containing the password
                
                // Finish configuration by assigning tunnel protocol to `protocolConfiguration`
                // property of `providerManager` and by setting description.
                self.providerManager.protocolConfiguration = tunnelProtocol
            self.providerManager.localizedDescription = "OpenVPN Client"
            
            self.providerManager.isEnabled = true
            
            // Save configuration in the Network Extension preferences
            self.providerManager.saveToPreferences(completionHandler: { (error) in
                if let error = error  {
                    // Handle an occured error
                    print(error)
                }
            })
        })
    }
    
}`

code to connect ` self.providerManager.loadFromPreferences(completionHandler: { (error) in guard error == nil else { // Handle an occured error print(error) return }

        do {
            try self.providerManager.connection.startVPNTunnel()
        } catch {
            // Handle an occured error
             print(error)
        }
    })`

connection status is disconnected

visionstech avatar Mar 01 '18 09:03 visionstech

@visionstech any luck? I am facing a similar issue. connection status is disconnected

roshit-omanakuttan avatar May 28 '18 09:05 roshit-omanakuttan

@visionstech or @roshit-omanakuttan any update on this, as I am getting same issue. connection status is disconnected

harmispatel avatar Jun 09 '18 06:06 harmispatel

Hi @harmispatel,

Have you tried to debug Packet Tunnel Provider extension step by step and check log messages?

ss-abramchuk avatar Jun 09 '18 07:06 ss-abramchuk

@ss-abramchuk Actually I am totally new. I have follow your steps, in ViewController I have put all your code and follow instruction and did file configurationFileURL and serverAddress etc.. changes as per you mention. I have create object like "var providerManager = NETunnelProviderManager()".

and create PacketTunnelProvider and put all your code as it is. It's not calling any function from PacketTunnelProvider.

if possible could you please guide me that how can I use "PacketTunnelProvider" in my code and use extension. If do you have any sample code please share it.

It would be very helpful.

harmispatel avatar Jun 09 '18 07:06 harmispatel

@harmispatel

I meet the  problem same to you, have solved it ? thanks for sharing to me .

LCodeX avatar Jun 18 '18 14:06 LCodeX

Hello Guys , I have able to save VPN configuration. Please tell me how to make the server address variable or get server address and what is the remote identifier for? Please tell me if anyone worked on VPN Configuration Here is my code:

func connectVPN(){
    do {
             if let file = URL(string: "example.com") {
            let data = try Data(contentsOf: file)
            let json = try JSONSerialization.jsonObject(with: data, options: [])
            if let object = json as? [String: String] {
            // json is a dictionary
            var data_VPN = object["VPN_data"]!
            //print("data:\(data_VPN)")
            let certificate = data_VPN
            let nsdata = certificate.data(using: .utf8)

            let base64EncodedData = nsdata!.base64EncodedData()

            print("base64StoreData:\(nsdata!)")
            print("base64StoreNewData:\(base64EncodedData)")

            var vpnManager = NEVPNManager.shared()

                                vpnManager.loadFromPreferences { error in

                                    if vpnManager.`protocol` == nil{
                                        let newIPSec = NEVPNProtocolIPSec()

                                        newIPSec.serverAddress = ""
                                        newIPSec.localIdentifier = ""
                                        newIPSec.remoteIdentifier = ""
                                        newIPSec.useExtendedAuthentication = true
                                        newIPSec.identityData = base64EncodedData as! Data
                                        newIPSec.authenticationMethod = NEVPNIKEAuthenticationMethod.certificate
                                        print("VPNDATA:\(newIPSec)")

                                        if #available(iOS 9, *) {
                                        vpnManager.protocolConfiguration = newIPSec
                                        } else {
                                        vpnManager.`protocol` = newIPSec
                                        }

                                        vpnManager.isEnabled = true
                                        vpnManager.saveToPreferences(completionHandler: { (error) -> Void in
                                            if ((error) != nil) {
                                                print("VPN Preferences error: 2")
                                            }
                                            else {
                                                vpnManager.loadFromPreferences(completionHandler: { (error) in
                                                    if ((error) != nil) {
                                                        print("VPN Preferences error: 2")
                                                    }
                                                    else {
                                                        var startError: NSError?
                                                        do {
                                                            try vpnManager.connection.startVPNTunnel()
                                                        }
                                                        catch let error as NSError {
                                                            startError = error
                                                            print(startError)
                                                        }
                                                        catch {
                                                            print("Fatal Error")
                                                            fatalError()
                                                        }
                                                        if ((startError) != nil) {
                                                            print("VPN Preferences error: 3")
                                                            let alertController = UIAlertController( title: "Oops..", message: "Something went wrong while connecting to the VPN. Please try again.", preferredStyle: UIAlertControllerStyle.alert)
                                                            alertController.addAction( UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default,handler: nil))
                                                            self.present(alertController, animated: true, completion: nil)
                                                            print(startError)
                                                        }
                                                        else {
                                                            //VPNStatusDidChange(nil)
                                                            print("Start VPN")
                                                        }
                                                    }
                                                })
                                            }
                                        })
            }

        } else if let object = json as? [Any] {
            // json is an array
            for anItem in object as! [Dictionary<String, AnyObject>] {
                let industryName = anItem["VPN_data"] as! String                                               
            }
        } else {
            print("JSON is invalid")
        }
    } else {
        print("no file")
    }
} catch {
    print(error.localizedDescription)
}

} }

raOne-007 avatar Jan 02 '20 13:01 raOne-007

Hello Guys , I have able to save VPN configuration. Please tell me how to make the server address variable or get server address and what is the remote identifier for? Please tell me if anyone worked on VPN Configuration Here is my code:

func connectVPN(){
    do {
             if let file = URL(string: "example.com") {
            let data = try Data(contentsOf: file)
            let json = try JSONSerialization.jsonObject(with: data, options: [])
            if let object = json as? [String: String] {
            // json is a dictionary
            var data_VPN = object["VPN_data"]!
            //print("data:\(data_VPN)")
            let certificate = data_VPN
            let nsdata = certificate.data(using: .utf8)

            let base64EncodedData = nsdata!.base64EncodedData()

            print("base64StoreData:\(nsdata!)")
            print("base64StoreNewData:\(base64EncodedData)")

            var vpnManager = NEVPNManager.shared()

                                vpnManager.loadFromPreferences { error in

                                    if vpnManager.`protocol` == nil{
                                        let newIPSec = NEVPNProtocolIPSec()

                                        newIPSec.serverAddress = ""
                                        newIPSec.localIdentifier = ""
                                        newIPSec.remoteIdentifier = ""
                                        newIPSec.useExtendedAuthentication = true
                                        newIPSec.identityData = base64EncodedData as! Data
                                        newIPSec.authenticationMethod = NEVPNIKEAuthenticationMethod.certificate
                                        print("VPNDATA:\(newIPSec)")

                                        if #available(iOS 9, *) {
                                        vpnManager.protocolConfiguration = newIPSec
                                        } else {
                                        vpnManager.`protocol` = newIPSec
                                        }

                                        vpnManager.isEnabled = true
                                        vpnManager.saveToPreferences(completionHandler: { (error) -> Void in
                                            if ((error) != nil) {
                                                print("VPN Preferences error: 2")
                                            }
                                            else {
                                                vpnManager.loadFromPreferences(completionHandler: { (error) in
                                                    if ((error) != nil) {
                                                        print("VPN Preferences error: 2")
                                                    }
                                                    else {
                                                        var startError: NSError?
                                                        do {
                                                            try vpnManager.connection.startVPNTunnel()
                                                        }
                                                        catch let error as NSError {
                                                            startError = error
                                                            print(startError)
                                                        }
                                                        catch {
                                                            print("Fatal Error")
                                                            fatalError()
                                                        }
                                                        if ((startError) != nil) {
                                                            print("VPN Preferences error: 3")
                                                            let alertController = UIAlertController( title: "Oops..", message: "Something went wrong while connecting to the VPN. Please try again.", preferredStyle: UIAlertControllerStyle.alert)
                                                            alertController.addAction( UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default,handler: nil))
                                                            self.present(alertController, animated: true, completion: nil)
                                                            print(startError)
                                                        }
                                                        else {
                                                            //VPNStatusDidChange(nil)
                                                            print("Start VPN")
                                                        }
                                                    }
                                                })
                                            }
                                        })
            }

        } else if let object = json as? [Any] {
            // json is an array
            for anItem in object as! [Dictionary<String, AnyObject>] {
                let industryName = anItem["VPN_data"] as! String                                               
            }
        } else {
            print("JSON is invalid")
        }
    } else {
        print("no file")
    }
} catch {
    print(error.localizedDescription)
}

} }

hi I have a complete file setup but I am unable to success for configuration vpn. please share the you step for VPN Configuration Thanks,

zubairahmad2 avatar Jun 03 '21 15:06 zubairahmad2

@ss-abramchuk Actually I am totally new. I have follow your steps, in ViewController I have put all your code and follow instruction and did file configurationFileURL and serverAddress etc.. changes as per you mention. I have create object like "var providerManager = NETunnelProviderManager()".

and create PacketTunnelProvider and put all your code as it is. It's not calling any function from PacketTunnelProvider.

if possible could you please guide me that how can I use "PacketTunnelProvider" in my code and use extension. If do you have any sample code please share it.

It would be very helpful.

@harmispatel have you resolve the problem please share if you resolve these issue. thanks

zubairahmad2 avatar Jun 03 '21 15:06 zubairahmad2