SimpleTunnelServices/FilterUtilities.swift
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
This file contains the FilterUtilities class. FilterUtilities objects contain functions and data that is used by both the SimpleTunnel UI and the SimpleTunnel content filter providers. |
*/ |
import Foundation |
import NetworkExtension |
/// Content Filter actions. |
public enum FilterRuleAction : Int, CustomStringConvertible { |
case block = 1 |
case allow = 2 |
case needMoreRulesAndBlock = 3 |
case needMoreRulesAndAllow = 4 |
case needMoreRulesFromDataAndBlock = 5 |
case needMoreRulesFromDataAndAllow = 6 |
case examineData = 7 |
case redirectToSafeURL = 8 |
case remediate = 9 |
public var description: String { |
switch self { |
case .block: return "Block" |
case .examineData: return "Examine Data" |
case .needMoreRulesAndAllow: return "Ask for more rules, then allow" |
case .needMoreRulesAndBlock: return "Ask for more rules, then block" |
case .needMoreRulesFromDataAndAllow: return "Ask for more rules, examine data, then allow" |
case .needMoreRulesFromDataAndBlock: return "Ask for more rules, examine data, then block" |
case .redirectToSafeURL: return "Redirect" |
case .remediate: return "Remediate" |
case .allow: return "Allow" |
} |
} |
} |
/// A class containing utility properties and functions for Content Filtering. |
open class FilterUtilities { |
// MARK: Properties |
/// A reference to the SimpleTunnel user defaults. |
open static let defaults = UserDefaults(suiteName: "group.com.example.apple-samplecode.SimpleTunnel") |
// MARK: Initializers |
/// Get rule parameters for a flow from the SimpleTunnel user defaults. |
open class func getRule(_ flow: NEFilterFlow) -> (FilterRuleAction, String, [String: AnyObject]) { |
let hostname = FilterUtilities.getFlowHostname(flow) |
guard !hostname.isEmpty else { return (.allow, hostname, [:]) } |
guard let hostNameRule = (defaults?.object(forKey: "rules") as AnyObject).object(forKey: hostname) as? [String: AnyObject] else { |
simpleTunnelLog("\(hostname) is set for NO RULES") |
return (.allow, hostname, [:]) |
} |
guard let ruleTypeInt = hostNameRule["kRule"] as? Int, |
let ruleType = FilterRuleAction(rawValue: ruleTypeInt) |
else { return (.allow, hostname, [:]) } |
return (ruleType, hostname, hostNameRule) |
} |
/// Get the hostname from a browser flow. |
open class func getFlowHostname(_ flow: NEFilterFlow) -> String { |
guard let browserFlow : NEFilterBrowserFlow = flow as? NEFilterBrowserFlow, |
let url = browserFlow.url, |
let hostname = url.host |
, flow is NEFilterBrowserFlow |
else { return "" } |
return hostname |
} |
/// Download a fresh set of rules from the rules server. |
open class func fetchRulesFromServer(_ serverAddress: String?) { |
simpleTunnelLog("fetch rules called") |
guard serverAddress != nil else { return } |
simpleTunnelLog("Fetching rules from \(serverAddress)") |
guard let infoURL = URL(string: "http://\(serverAddress!)/rules/") else { return } |
simpleTunnelLog("Rules url is \(infoURL)") |
let content: String |
do { |
content = try String(contentsOf: infoURL, encoding: String.Encoding.utf8) |
} |
catch { |
simpleTunnelLog("Failed to fetch the rules from \(infoURL)") |
return |
} |
let contentArray = content.components(separatedBy: "<br/>") |
simpleTunnelLog("Content array is \(contentArray)") |
var urlRules = [String: [String: AnyObject]]() |
for rule in contentArray { |
if rule.isEmpty { |
continue |
} |
let ruleArray = rule.components(separatedBy: " ") |
guard !ruleArray.isEmpty else { continue } |
var redirectKey = "SafeYes" |
var remediateKey = "Remediate1" |
var remediateButtonKey = "RemediateButton1" |
var actionString = "9" |
let urlString = ruleArray[0] |
let ruleArrayCount = ruleArray.count |
if ruleArrayCount > 1 { |
actionString = ruleArray[1] |
} |
if ruleArrayCount > 2 { |
redirectKey = ruleArray[2] |
} |
if ruleArrayCount > 3 { |
remediateKey = ruleArray[3] |
} |
if ruleArrayCount > 4 { |
remediateButtonKey = ruleArray[4] |
} |
urlRules[urlString] = [ |
"kRule" : actionString as AnyObject, |
"kRedirectKey" : redirectKey as AnyObject, |
"kRemediateKey" : remediateKey as AnyObject, |
"kRemediateButtonKey" : remediateButtonKey as AnyObject, |
] |
} |
defaults?.setValue(urlRules, forKey:"rules") |
} |
} |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-10-04