PIAHotspotHelper.swift 6.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
//
//  PIAHotspotHelper.swift
//  PIA VPN
//
//  Created by Jose Antonio Blaya Garcia on 18/12/2018.
//  Copyright © 2018 London Trust Media. All rights reserved.
//

import Foundation
import NetworkExtension
import PIALibrary
import SwiftyBeaver

private let log = SwiftyBeaver.self

public protocol PIAHotspotHelperDelegate: class {

    /**
     Refreshes the available WiFi networks.
     
     - Parameter callback: Returns a refreshed list of available SSIDs as `String`.
     */
    func refreshAvailableNetworks(_ networks: [String]?)

}

class PIAHotspotHelper {
    
    private var delegate: PIAHotspotHelperDelegate?
    
    init(withDelegate delegate: PIAHotspotHelperDelegate? = nil) {
        self.delegate = delegate
    }
    
    /**
     Returns the current WiFi SSID.
     
     - Returns: SSID as `String`.
     */
    public func currentWiFiNetwork() -> String? {
        return UIDevice.current.WiFiSSID
    }
    
    /**
     Configures the HotspotHelper API to perform actions depending of the command.
     
     - Returns: true if correctly configured.
     */
    public func configureHotspotHelper() -> Bool {
        
51
        let options: [String: NSObject] = [kNEHotspotHelperOptionDisplayName : self.hotspotHelperMessage() as NSObject]
52 53
        let queue: DispatchQueue = DispatchQueue(label: "com.privateinternetaccess.hotspot", attributes: DispatchQueue.Attributes.concurrent)
        NEHotspotHelper.supportedNetworkInterfaces()
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
        if Client.preferences.nmtRulesEnabled {
            return NEHotspotHelper.register(options: options,
                                            queue: queue) { [weak self] (cmd: NEHotspotHelperCommand) in
                                                
                                                if let weakSelf = self {
                                                    if cmd.commandType == .filterScanList {
                                                        log.info("filtering ssid list")
                                                        var availableList: [String] = []
                                                        var unsecuredList: [NEHotspotNetwork] = []
                                                        for element in cmd.networkList! {
                                                            if !element.ssid.isEmpty,
                                                                !availableList.contains(element.ssid) {
                                                                availableList.append(element.ssid)
                                                            }
                                                            if !element.isSecure {
                                                                element.setConfidence(.high)
                                                                unsecuredList.append(element)
                                                            }
72
                                                        }
73 74 75 76 77
                                                        weakSelf.saveCurrentNetworkList(availableNetworks: availableList)
                                                        let response = cmd.createResponse(NEHotspotHelperResult.success)
                                                        if !Client.providers.vpnProvider.isVPNConnected {
                                                            response.setNetworkList(unsecuredList)
                                                            log.info("present PIA message for unprotected networks")
78
                                                        }
79
                                                        response.deliver()
80
                                                    }
81
                                                    
82
                                                }
83 84 85 86
                                                
            }
        } else {
            return false
87 88 89 90
        }
        
    }
    
91 92 93 94 95 96 97 98 99
    private func hotspotHelperMessage() -> String {
        if Client.preferences.nmtRulesEnabled,
            Client.preferences.useWiFiProtection {
            return L10n.Hotspothelper.Display.Protected.name
        } else {
            return L10n.Hotspothelper.Display.name
        }
    }
    
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
    private func saveCurrentNetworkList(availableNetworks: [String]) {
        let preferences = Client.preferences.editable()
        preferences.availableNetworks = availableNetworks
        preferences.commit()
    }
    
    /**
     List of available networks.
     
     - Returns: Array of available SSID.
     */
    public func retrieveCurrentNetworkList() -> [String] {
        var availableNetworks = Client.preferences.availableNetworks
        if let ssid = UIDevice.current.WiFiSSID,
            !availableNetworks.contains(ssid) {
            availableNetworks.append(ssid)
        }
        return availableNetworks
    }
    
    /**
     List of trusted networks.
     
     - Returns: Array of trusted SSID.
     */
    public func trustedNetworks() -> [String] {
        return Client.preferences.trustedNetworks
    }
    
    /**
     Saves the WiFi network.
     
     - Parameter ssid: SSID as `String`.
     */
    public func saveTrustedNetwork(_ ssid: String) {
        var trustedNetworks = Client.preferences.trustedNetworks
        if !trustedNetworks.contains(ssid) {
            trustedNetworks.append(ssid)
        }
        let preferences = Client.preferences.editable()
        preferences.trustedNetworks = trustedNetworks
        preferences.commit()
    }
    
    /**
     Removes the WiFi networks.
     
     - Parameter ssid: SSID as `String`.
     */
    public func removeTrustedNetwork(_ ssid: String) {
        let trustedNetworks = Client.preferences.trustedNetworks
        let newTrustedNetworks = trustedNetworks.filter { $0 != ssid }
        let preferences = Client.preferences.editable()
        preferences.trustedNetworks = newTrustedNetworks
        preferences.commit()
    }
    
    /**
     Remove all elements from the trusted network list.
     */
    public func clearTrustedNetworkList() {
        var trustedNetworks = Client.preferences.trustedNetworks
        trustedNetworks.removeAll()
        let preferences = Client.preferences.editable()
        preferences.trustedNetworks = trustedNetworks
        preferences.commit()
    }
    
    private func tryToConnectVPNForAllNetworks() {
        if Client.preferences.shouldConnectForAllNetworks {
            //Connect the VPN
            if !Client.providers.vpnProvider.isVPNConnected {
                Macros.dispatch(after: .milliseconds(200)) {
                    Client.providers.vpnProvider.connect(nil)
                }
            }
        }
    }
    
}