Skip to content

Commit

Permalink
Move Validator class & Mode enum to Utils.swift.
Browse files Browse the repository at this point in the history
  • Loading branch information
yangziy committed Sep 27, 2018
1 parent b617e83 commit 47c0216
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 130 deletions.
132 changes: 6 additions & 126 deletions ShadowsocksX-NG/HTTPUserProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class HTTPUserProxy{
static let shard = HTTPUserProxy()

let adapter = APIAdapter()
let v = Validator()

let server = GCDWebServer()
let api_port:UInt = 9528
Expand Down Expand Up @@ -111,7 +110,7 @@ class HTTPUserProxy{
if var server = ((request as? GCDWebServerURLEncodedFormRequest)?.arguments) as? [String: Any] {
if (server["ServerPort"] != nil) {
server["ServerPort"] = UInt16(server["ServerPort"] as! String)
if (Validator.integrity(server) && Validator.existAttributes(server)) { // validate
if (Validator.profile(server)) { // validate
self.adapter.addServer(server: server)
return GCDWebServerResponse();
}
Expand Down Expand Up @@ -173,7 +172,7 @@ class HTTPUserProxy{
func addHandler_setMode() {
server.addHandler(forMethod: "PUT", path: "/mode", request: GCDWebServerURLEncodedFormRequest.self, processBlock: {request in
if let mode_str = (request as? GCDWebServerURLEncodedFormRequest)?.arguments["Mode"] as? String{
if let mode = APIAdapter.Mode(rawValue: mode_str) {
if let mode = ProxyType(rawValue: mode_str) {
self.adapter.setMode(mode: mode);

return GCDWebServerResponse()
Expand All @@ -185,8 +184,6 @@ class HTTPUserProxy{
}

class APIAdapter {
enum Mode:String {case auto="auto", global="global", manual="manual"};

let SerMgr = ServerProfileManager.instance
let defaults = UserDefaults.standard
let appdeleget = NSApplication.shared.delegate as! AppDelegate
Expand Down Expand Up @@ -281,21 +278,21 @@ class APIAdapter {
self.appdeleget.updateServersMenu()
}

func getMode()->Mode {
func getMode()->ProxyType {
let mode_str = self.defaults.string(forKey: "ShadowsocksRunningMode");
switch mode_str {
case "auto": return .auto
case "auto": return .pac
case "global": return .global;
case "manual": return .manual
default:fatalError()
}
}

func setMode(mode:Mode) {
func setMode(mode:ProxyType) {
let defaults = UserDefaults.standard

switch mode{
case .auto:defaults.setValue("auto", forKey: "ShadowsocksRunningMode")
case .pac:defaults.setValue("auto", forKey: "ShadowsocksRunningMode")
case .global:defaults.setValue("global", forKey: "ShadowsocksRunningMode")
case .manual:defaults.setValue("manual", forKey: "ShadowsocksRunningMode")
}
Expand All @@ -304,120 +301,3 @@ class APIAdapter {
self.appdeleget.applyConfig()
}
}

class Validator {
static func integrity(_ data: Dictionary<String, Any>) -> Bool {
if (data["ServerHost"] == nil || data["ServerPort"] as? NSNumber == nil
|| data["Method"] == nil || data["Password"] == nil) {
return false;
}
return true;
}

static func existAttributes(_ server:Dictionary<String, Any>) -> Bool {
var result = true;

if (server["ServerHost"] != nil) {
result = result && serverHost(server["ServerHost"] as! String);
}
if (server["ServerPort"] != nil) {
result = result && serverPort(server["ServerPort"] as! uint16);
}
if (server["Method"] != nil) {
result = result && method(server["Method"] as! String);
}
if (server["Password"] != nil) {
result = result && password(server["Password"] as! String);
}
if (server["Remark"] != nil) {
result = result && remark(server["Remark"] as! String);
}
if (server["Plugin"] != nil) {
result = result && plugin(server["Plugin"] as! String);
}
if (server["PluginOptions"] != nil) {
result = result && pluginOptions(server["PluginOptions"] as! String);
}

return result;
}

static func serverHost(_ str:String) -> Bool {
return validateIpAddress(str) || validateDomainName(str);
}

static func serverPort(_ str:uint16) -> Bool {
return true;
}

static func method(_ str:String) -> Bool {
// Copy from PreferencesWindowController.swift
// Better to make valid methods enumeration type.
return [
"aes-128-gcm",
"aes-192-gcm",
"aes-256-gcm",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"bf-cfb",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
"salsa20",
"chacha20",
"chacha20-ietf",
"rc4-md5",
].contains(str);
}

static func password(_ str:String) -> Bool {
return true;
}

static func remark(_ str:String) -> Bool {
return true;
}

static func plugin(_ str:String) -> Bool {
return true;
}

static func pluginOptions(_ str:String) -> Bool {
return true;
}

// Copy from ServerProfile.swift
private static func validateIpAddress(_ ipToValidate: String) -> Bool {

var sin = sockaddr_in()
var sin6 = sockaddr_in6()

if ipToValidate.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1 {
// IPv6 peer.
return true
}
else if ipToValidate.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1 {
// IPv4 peer.
return true
}

return false;
}

// Copy from ServerProfile.swift
private static func validateDomainName(_ value: String) -> Bool {
let validHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"

if (value.range(of: validHostnameRegex, options: .regularExpression) != nil) {
return true
} else {
return false
}
}
}
123 changes: 119 additions & 4 deletions ShadowsocksX-NG/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,126 @@ extension Data {
}
}

enum ProxyType {
case pac
case global
}
enum ProxyType:String {case pac="auto", global="global", manual="manual"};

struct Globals {
static var proxyType = ProxyType.pac
}

class Validator {
// Check if a ServerProfile can be constructed from input dictionary
static func profile(_ data: Dictionary<String, Any>) -> Bool {
if (data["ServerHost"] == nil || data["ServerPort"] as? NSNumber == nil
|| data["Method"] == nil || data["Password"] == nil) {
return false;
}
return existAttributes(data);
}

static func existAttributes(_ server:Dictionary<String, Any>) -> Bool {
var result = true;

if (server["ServerHost"] != nil) {
result = result && serverHost(server["ServerHost"] as! String);
}
if (server["ServerPort"] != nil) {
result = result && serverPort(server["ServerPort"] as! uint16);
}
if (server["Method"] != nil) {
result = result && method(server["Method"] as! String);
}
if (server["Password"] != nil) {
result = result && password(server["Password"] as! String);
}
if (server["Remark"] != nil) {
result = result && remark(server["Remark"] as! String);
}
if (server["Plugin"] != nil) {
result = result && plugin(server["Plugin"] as! String);
}
if (server["PluginOptions"] != nil) {
result = result && pluginOptions(server["PluginOptions"] as! String);
}

return result;
}

static func serverHost(_ str:String) -> Bool {
return validateIpAddress(str) || validateDomainName(str);
}

static func serverPort(_ str:uint16) -> Bool {
return true;
}

static func method(_ str:String) -> Bool {
// Copy from PreferencesWindowController.swift
// Better to make valid methods enumeration type.
return [
"aes-128-gcm",
"aes-192-gcm",
"aes-256-gcm",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"bf-cfb",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
"salsa20",
"chacha20",
"chacha20-ietf",
"rc4-md5",
].contains(str);
}

static func password(_ str:String) -> Bool {
return str != "";
}

static func remark(_ str:String) -> Bool {
return true;
}

static func plugin(_ str:String) -> Bool {
return true;
}

static func pluginOptions(_ str:String) -> Bool {
return true;
}

// Copy from ServerProfile.swift
private static func validateIpAddress(_ ipToValidate: String) -> Bool {

var sin = sockaddr_in()
var sin6 = sockaddr_in6()

if ipToValidate.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1 {
// IPv6 peer.
return true
}
else if ipToValidate.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1 {
// IPv4 peer.
return true
}

return false;
}

// Copy from ServerProfile.swift
private static func validateDomainName(_ value: String) -> Bool {
let validHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"

if (value.range(of: validHostnameRegex, options: .regularExpression) != nil) {
return true
} else {
return false
}
}
}

0 comments on commit 47c0216

Please sign in to comment.