Создать VPN-соединение - PullRequest
       10

Создать VPN-соединение

0 голосов
/ 26 октября 2018

Я совершенно новичок в macos-development и swift, поэтому, пожалуйста, потерпите меня ...

Я пытаюсь создать VPN-соединение в приложении Какао. Я основал код на macosvpn: https://github.com/halo/macosvpn/blob/master/macosvpn/Classes/VPNServiceCreator.swift

Это то, что я имею до сих пор:

    func createVPNService() {
        let options = ["" : ""]
        let prefs = SCPreferencesCreate(nil, "TheVPN" as CFString, nil)

        // These variables will hold references to our new interfaces
        let initialTopInterface: SCNetworkInterface!
        let initialBottomInterface: SCNetworkInterface!

        // L2TP on top of IPv4
        initialBottomInterface = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceTypeL2TP)
        // PPP on top of L2TP
        initialTopInterface = SCNetworkInterfaceCreateWithInterface(initialBottomInterface!, kSCNetworkInterfaceTypePPP)

        let service = SCNetworkServiceCreate(prefs!, initialTopInterface!)
        SCNetworkServiceSetName(service!, ("Service Name" as CFString))
        // Because, if we would like to modify the interface, we first need to freshly fetch it from the service
        // See https://lists.apple.com/archives/macnetworkprog/2013/Apr/msg00016.html
        let topInterface = SCNetworkServiceGetInterface(service!)

        SCNetworkInterfaceSetConfiguration(topInterface!, options as CFDictionary)
        // Now let's apply the shared secret to the IPSec part of the L2TP/IPSec Interface
        let thingy:CFString = "IPSec" as CFString
        SCNetworkInterfaceSetExtendedConfiguration(topInterface!, thingy, options as CFDictionary)
        SCNetworkServiceEstablishDefaultConfiguration(service!)
        let networkSet = SCNetworkSetCopyCurrent(prefs!)

        let serviceProtocol = SCNetworkServiceCopyProtocol(service!, kSCNetworkProtocolTypeIPv4)
        SCNetworkProtocolSetConfiguration(serviceProtocol!, options as CFDictionary)
        SCNetworkSetAddService(networkSet!, service!)

        if !SCPreferencesCommitChanges(prefs!) {
            print("Error: Could not commit preferences. (Code \(SCError()))")
        }
        if !SCPreferencesApplyChanges(prefs!) {
            print("Error: Could not apply changes. (Code \(SCError()))")
        }
    }

Когда я запускаю эту программу, сетевая служба не создается.

Понятия не имею, какие опции и префы должны быть на самом деле? Теперь они более или менее пусты.

Кроме того, SCPreferencesCommitChanges и SCPreferencesApplyChanges завершаются ошибкой с кодом 1003. Я полагаю, что для работы им нужны привилегии root, и я не смог понять, как получить привилегии root.

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 26 октября 2018

Я наконец понял, как создать VPN-соединение / сервис.Но я все еще должен выяснить, как следует использовать опции и префы.

SCPreferencesCreate был заменен на SCPreferencesCreateWithAuthorization и некоторый код авторизации ранее.Это обновленный код.

    func createVPNConnection() {
        let flags : AuthorizationFlags = [.interactionAllowed, .extendRights, .preAuthorize]
        var authRef: AuthorizationRef?
        AuthorizationCreate(nil, nil, flags, &authRef)

        let options = ["" : ""]
        let prefs = SCPreferencesCreateWithAuthorization(nil, "TheVPN" as CFString, nil, authRef)
        // These variables will hold references to our new interfaces
        let initialTopInterface: SCNetworkInterface!
        let initialBottomInterface: SCNetworkInterface!

        // L2TP on top of IPv4
        initialBottomInterface = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceTypeL2TP)
        // PPP on top of L2TP
        initialTopInterface = SCNetworkInterfaceCreateWithInterface(initialBottomInterface!, kSCNetworkInterfaceTypePPP)

        let service = SCNetworkServiceCreate(prefs!, initialTopInterface!)
        SCNetworkServiceSetName(service!, ("Test Service Name" as CFString))
        // Because, if we would like to modify the interface, we first need to freshly fetch it from the service
        // See https://lists.apple.com/archives/macnetworkprog/2013/Apr/msg00016.html
        let topInterface = SCNetworkServiceGetInterface(service!)

        // Let's apply all configuration to the PPP interface
        // Specifically, the servername, account username and password
        SCNetworkInterfaceSetConfiguration(topInterface!, options as CFDictionary)

        // Now let's apply the shared secret to the IPSec part of the L2TP/IPSec Interface
        let thingy:CFString = "IPSec" as CFString
        SCNetworkInterfaceSetExtendedConfiguration(topInterface!, thingy, options as CFDictionary)
        SCNetworkServiceEstablishDefaultConfiguration(service!)
        let networkSet = SCNetworkSetCopyCurrent(prefs!)
        let serviceProtocol = SCNetworkServiceCopyProtocol(service!, kSCNetworkProtocolTypeIPv4)
        SCNetworkProtocolSetConfiguration(serviceProtocol!, options as CFDictionary)
        SCNetworkSetAddService(networkSet!, service!)

        if !SCPreferencesCommitChanges(prefs!) {
             print("Error: Could not commit preferences. (Code \(SCError()))")
        }
        if !SCPreferencesApplyChanges(prefs!) {
             print("Error: Could not apply changes. (Code \(SCError()))")
        }
    }
...