FuturraGroup/OpenVPNXor

VPN configuration are added in to device but in device it is showing connected but not refleting in to Open VPN Sever

aditya141025 opened this issue · 3 comments

Hi All,
I'm able to add the configuration file in to device and able to connect the VPN on iPhone device (iOS 16.2 version). but it is not reflecting any history in Open VPN server. Please refer the screenshot attached.
IMG_A0892F485CC1-1

and after approximate in 1 minute it gets disconnected automatically. Strange thing is that it does not reflect on any history on Server i.e. no logs history for connection or disconnection or user name on server. Could you please help what is the issue. I'll be really grateful to you.

Below is the code that I have implemented:

import Foundation
import NetworkExtension

final class VPNManager {
    
    let vpnManager = NEVPNManager.shared()
    func initVPNTunnelProviderManager() {
        self.vpnManager.loadFromPreferences { (error) -> Void in
            self.checkVPNConfiguration()
            if((error) != nil) {
                print("VPN Preferences error: 1")
            } else {
                let IKEv2Protocol = NEVPNProtocolIKEv2()
                IKEv2Protocol.username = "myusername"
                IKEv2Protocol.serverAddress = "144.202.9.42" //server tunneling Address
                IKEv2Protocol.remoteIdentifier = "securevpn.com.myserver" //Remote id
                IKEv2Protocol.localIdentifier = nil //Local id
                
                IKEv2Protocol.deadPeerDetectionRate = .low
                IKEv2Protocol.authenticationMethod = .none
                IKEv2Protocol.useExtendedAuthentication = true //if you are using sharedSecret method then make it false
                IKEv2Protocol.disconnectOnSleep = false
                
                //Set IKE SA (Security Association) Params...
                IKEv2Protocol.ikeSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES256
                IKEv2Protocol.ikeSecurityAssociationParameters.integrityAlgorithm = .SHA256
                IKEv2Protocol.ikeSecurityAssociationParameters.diffieHellmanGroup = .group14
                IKEv2Protocol.ikeSecurityAssociationParameters.lifetimeMinutes = 1440
                //IKEv2Protocol.ikeSecurityAssociationParameters.isProxy() = false
                
                //Set CHILD SA (Security Association) Params...
                IKEv2Protocol.childSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES256
                IKEv2Protocol.childSecurityAssociationParameters.integrityAlgorithm = .SHA256
                IKEv2Protocol.childSecurityAssociationParameters.diffieHellmanGroup = .group14
                IKEv2Protocol.childSecurityAssociationParameters.lifetimeMinutes = 1440
                
                let kcs = KeychainService()
                //Save password in keychain...
                kcs.save(key: "VPN_PASSWORD", value: "hSyeI1H8Wsybb5qDk5abBrJ7LCu3bPbJrax9aFG77FiiJZu3eUepLwvg9pjjEL3")
                //Load password from keychain...
                IKEv2Protocol.passwordReference = kcs.load(key: "VPN_PASSWORD")
                self.vpnManager.protocolConfiguration = IKEv2Protocol
                self.vpnManager.localizedDescription = "Quilr VPN Configuration"
                self.vpnManager.isEnabled = true
                
                self.vpnManager.isOnDemandEnabled = true
                //print(IKEv2Protocol)
                
                //Set rules
                var rules = [NEOnDemandRule]()
                let rule = NEOnDemandRuleConnect()
                rule.interfaceTypeMatch = .any
                rules.append(rule)
                
                print("SAVE TO PREFERENCES...")
                
                //SAVE TO PREFERENCES...
                self.vpnManager.saveToPreferences(completionHandler: { (error) -> Void in
                    if((error) != nil) {
                        
                        print("VPN Preferences error: 2")
                    } else {
                        
                        print("CALL LOAD TO PREFERENCES AGAIN...")
                        //CALL LOAD TO PREFERENCES AGAIN...
                        self.vpnManager.loadFromPreferences(completionHandler: { (error) in
                            if ((error) != nil) {
                                print("VPN Preferences error: 2")
                            } else {
                                var startError: NSError?
                                do {
                                    //START THE CONNECTION...
                                    try self.vpnManager.connection.startVPNTunnel()
                                } catch let error as NSError {
                                    startError = error
                                    print(startError.debugDescription)
                                } catch {
                                    print("Fatal Error")
                                    fatalError()
                                }
                                if ((startError) != nil) {
                                    print("VPN Preferences error: 3")
                                    //Show alert here
                                    print("title: Oops.., message: Something went wrong while connecting to the VPN. Please try again.")
                                    print(startError.debugDescription)
                                } else {
                                    //self.VPNStatusDidChange(nil)
                                    print("Starting VPN...")
                                    //START THE CONNECTION...
                                    self.vpnConnectionStatusChanged()
                                }
                            }
                        })
                    }
                })
            }
        }
    }

    func checkVPNConfiguration() {
        let isVPNInstalled = vpnManager.isOnDemandEnabled || vpnManager.isEnabled || (vpnManager.protocolConfiguration != nil)

        if isVPNInstalled {
            print("VPN configuration is installed on the device.")
        } else {
            print("VPN configuration is not installed on the device.")
        }
    }
    
    //MARK:- Connect VPN
    static func connectVPN() {
        VPNManager().initVPNTunnelProviderManager()
    }
    
    //MARK:- Disconnect VPN
    static func disconnectVPN() {
        VPNManager().vpnManager.connection.stopVPNTunnel()
    }
    

    func vpnConnectionStatusChanged() {

        let status = self.vpnManager.connection.status
         print("VPN connection status = \(status)")

         switch status {
             
         case NEVPNStatus.connected:
               print("connected")

         case NEVPNStatus.invalid, NEVPNStatus.disconnected :
             print("disconnected")

         case NEVPNStatus.connecting , NEVPNStatus.reasserting:
             print("connecting")

         case NEVPNStatus.disconnecting:
             print("disconnecting")

         default:
             print("Unknown VPN connection status")
         }
     }
}

and another file is (Keychain Service )

import Foundation
import UIKit
import Security

// Identifiers
let serviceIdentifier = "MySerivice"
let userAccount = "authenticatedUser"
let accessGroup = "MySerivice"

// Arguments for the keychain queries
var kSecAttrAccessGroupSwift = NSString(format: kSecClass)

let kSecClassValue = kSecClass as CFString
let kSecAttrAccountValue = kSecAttrAccount as CFString
let kSecValueDataValue = kSecValueData as CFString
let kSecClassGenericPasswordValue = kSecClassGenericPassword as CFString
let kSecAttrServiceValue = kSecAttrService as CFString
let kSecMatchLimitValue = kSecMatchLimit as CFString
let kSecReturnDataValue = kSecReturnData as CFString
let kSecMatchLimitOneValue = kSecMatchLimitOne as CFString
let kSecAttrGenericValue = kSecAttrGeneric as CFString
let kSecAttrAccessibleValue = kSecAttrAccessible as CFString


class KeychainService: NSObject {

    func save(key:String, value:String) {

        let keyData: Data = key.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue), allowLossyConversion: false)!
        let valueData: Data = value.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue), allowLossyConversion: false)!

        let keychainQuery = NSMutableDictionary();

        keychainQuery[kSecClassValue as! NSCopying] = kSecClassGenericPasswordValue
        keychainQuery[kSecAttrGenericValue as! NSCopying] = keyData
        keychainQuery[kSecAttrAccountValue as! NSCopying] = keyData
        keychainQuery[kSecAttrServiceValue as! NSCopying] = "VPN"
        keychainQuery[kSecAttrAccessibleValue as! NSCopying] = kSecAttrAccessibleAlwaysThisDeviceOnly
        keychainQuery[kSecValueData as! NSCopying] = valueData;

        // Delete any existing items
        SecItemDelete(keychainQuery as CFDictionary)

        SecItemAdd(keychainQuery as CFDictionary, nil)
    }

    func load(key: String)->Data {

        let keyData: Data = key.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue), allowLossyConversion: false)!

        let keychainQuery = NSMutableDictionary();

        keychainQuery[kSecClassValue as! NSCopying] = kSecClassGenericPasswordValue
        keychainQuery[kSecAttrGenericValue as! NSCopying] = keyData
        keychainQuery[kSecAttrAccountValue as! NSCopying] = keyData
        keychainQuery[kSecAttrServiceValue as! NSCopying] = "VPN"
        keychainQuery[kSecAttrAccessibleValue as! NSCopying] = kSecAttrAccessibleAlwaysThisDeviceOnly
        keychainQuery[kSecMatchLimit] = kSecMatchLimitOne
        keychainQuery[kSecReturnPersistentRef] = kCFBooleanTrue

        var result: AnyObject?

        let status = withUnsafeMutablePointer(to: &result) { SecItemCopyMatching(keychainQuery, UnsafeMutablePointer($0)) }

        if status == errSecSuccess {

            if let data = result as! NSData? {

                if let value = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue) {
                    //print(value)
                }
                return data as Data;
            }
        }
        return "".data(using: .utf8)!;
    }
}

In the screenshot and in the code there is a configuration for the IKEv2 protocol, this library only supports the OpenVPN protocol.

Could you please help me How can I save configuration for openVPN protocol and which protocol iOS supports for openVPN. I searched but could not find any supported protocol for open VPN.

You do not need to create it yourself, in order to get it, contact the person who set up your VPN servers.