diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 571824f..509bb35 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -467,7 +467,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0730; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -678,6 +678,7 @@ baseConfigurationReference = 054C3E84057CD06DB85D99E7AD207F48 /* Pods-proxy_conf_helper.debug.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; @@ -717,6 +718,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.9; MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "${PRODUCT_BUNDLE_IDENTIFIER}"; PRODUCT_NAME = Alamofire; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -747,6 +749,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.9; MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = "${PRODUCT_BUNDLE_IDENTIFIER}"; PRODUCT_NAME = Alamofire; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -795,6 +798,7 @@ baseConfigurationReference = 774723B57789DD1DBE95EC5F0BCBD551 /* BRLOptionParser.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; @@ -816,6 +820,7 @@ baseConfigurationReference = A5055B8EFFFBEDE50909E935D4BCA446 /* Pods-proxy_conf_helper.release.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; @@ -873,6 +878,7 @@ baseConfigurationReference = 774723B57789DD1DBE95EC5F0BCBD551 /* BRLOptionParser.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; diff --git a/Pods/Target Support Files/Alamofire/Info.plist b/Pods/Target Support Files/Alamofire/Info.plist index ebdce25..99b3951 100644 --- a/Pods/Target Support Files/Alamofire/Info.plist +++ b/Pods/Target Support Files/Alamofire/Info.plist @@ -2,25 +2,25 @@ - CFBundleDevelopmentRegion - en - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - ${PRODUCT_BUNDLE_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - FMWK - CFBundleShortVersionString - 3.4.0 - CFBundleSignature - ???? - CFBundleVersion - ${CURRENT_PROJECT_VERSION} - NSPrincipalClass - + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 3.4.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + diff --git a/ShadowsocksX-NG/Base.lproj/AdvPreferencesWindowController.xib b/ShadowsocksX-NG/Base.lproj/AdvPreferencesWindowController.xib index 7b76e43..e222c3d 100644 --- a/ShadowsocksX-NG/Base.lproj/AdvPreferencesWindowController.xib +++ b/ShadowsocksX-NG/Base.lproj/AdvPreferencesWindowController.xib @@ -1,5 +1,5 @@ - + diff --git a/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib b/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib index 8142d87..4a8296f 100644 --- a/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib +++ b/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib @@ -7,6 +7,10 @@ + + + + @@ -24,16 +28,16 @@ - + - + - + - + @@ -84,13 +88,13 @@ - + - + - + @@ -98,7 +102,7 @@ - + @@ -109,7 +113,7 @@ - + @@ -126,7 +130,7 @@ - + @@ -134,7 +138,7 @@ - + @@ -142,7 +146,7 @@ - + @@ -153,7 +157,7 @@ - + @@ -161,7 +165,7 @@ - + @@ -169,7 +173,7 @@ - + @@ -177,7 +181,7 @@ - + @@ -195,45 +199,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + @@ -241,6 +340,35 @@ + + @@ -284,44 +412,16 @@ - - + - - + + @@ -336,7 +436,7 @@ DQ - + diff --git a/ShadowsocksX-NG/Base.lproj/UserRulesController.xib b/ShadowsocksX-NG/Base.lproj/UserRulesController.xib index 08a10c6..e1b94bd 100644 --- a/ShadowsocksX-NG/Base.lproj/UserRulesController.xib +++ b/ShadowsocksX-NG/Base.lproj/UserRulesController.xib @@ -16,7 +16,7 @@ - + @@ -51,17 +51,17 @@ Gw - + - + - + - + @@ -72,7 +72,7 @@ Gw - + diff --git a/ShadowsocksX-NG/LaunchAgentUtils.swift b/ShadowsocksX-NG/LaunchAgentUtils.swift index ca0deac..c9d61f1 100644 --- a/ShadowsocksX-NG/LaunchAgentUtils.swift +++ b/ShadowsocksX-NG/LaunchAgentUtils.swift @@ -8,7 +8,7 @@ import Foundation -let SS_LOCAL_VERSION = "2.4.6" +let SS_LOCAL_VERSION = "2.4.8" let APP_SUPPORT_DIR = "/Library/Application Support/ShadowsocksX-NG/" let LAUNCH_AGENT_DIR = "/Library/LaunchAgents/" let LAUNCH_AGENT_CONF_NAME = "com.qiuyuzhou.shadowsocksX-NG.local.plist" diff --git a/ShadowsocksX-NG/PreferencesWindowController.swift b/ShadowsocksX-NG/PreferencesWindowController.swift index 6cff2ce..64841c3 100644 --- a/ShadowsocksX-NG/PreferencesWindowController.swift +++ b/ShadowsocksX-NG/PreferencesWindowController.swift @@ -19,6 +19,11 @@ class PreferencesWindowController: NSWindowController @IBOutlet weak var portTextField: NSTextField! @IBOutlet weak var methodTextField: NSComboBox! + @IBOutlet weak var ProtocolTextField: NSComboBox! + @IBOutlet weak var ProtocolParamTextField: NSTextField! + @IBOutlet weak var ObfsTextField: NSComboBox! + @IBOutlet weak var ObfsParamTextField: NSTextField! + @IBOutlet weak var passwordTextField: NSTextField! @IBOutlet weak var remarkTextField: NSTextField! @@ -53,7 +58,20 @@ class PreferencesWindowController: NSWindowController "rc4", "table", ]) - + ProtocolTextField.addItemsWithObjectValues([ + "origin", + "verify_simple", + "verify_sha1", + "auth_simple", + "auth_sha1", + "auth_sha1_v2", + ]) + ObfsTextField.addItemsWithObjectValues([ + "palin", + "http_simple", + "tls1.0_session_auth", + "tls1.2_ticket_auth", + ]) profilesTableView.reloadData() updateProfileBoxVisible() } diff --git a/ShadowsocksX-NG/SWBApplication.m b/ShadowsocksX-NG/SWBApplication.m index 171af4a..4ae63d2 100644 --- a/ShadowsocksX-NG/SWBApplication.m +++ b/ShadowsocksX-NG/SWBApplication.m @@ -28,7 +28,7 @@ return; } else if ([[event charactersIgnoringModifiers] isEqualToString:@"z"]) { - if ([self sendAction:@selector(undo:) to:nil from:self]) + if ([self sendAction:@selector(undo) to:nil from:self]) return; } else if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) { @@ -38,7 +38,7 @@ } else if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == (NSCommandKeyMask | NSShiftKeyMask)) { if ([[event charactersIgnoringModifiers] isEqualToString:@"Z"]) { - if ([self sendAction:@selector(redo:) to:nil from:self]) + if ([self sendAction:@selector(redo) to:nil from:self]) return; } } diff --git a/ShadowsocksX-NG/SWBQRCodeWindowController.xib b/ShadowsocksX-NG/SWBQRCodeWindowController.xib index 623ae20..fa2f1ad 100644 --- a/ShadowsocksX-NG/SWBQRCodeWindowController.xib +++ b/ShadowsocksX-NG/SWBQRCodeWindowController.xib @@ -1,5 +1,5 @@ - + diff --git a/ShadowsocksX-NG/ServerProfile.swift b/ShadowsocksX-NG/ServerProfile.swift index c71d717..05c618c 100644 --- a/ShadowsocksX-NG/ServerProfile.swift +++ b/ShadowsocksX-NG/ServerProfile.swift @@ -19,6 +19,10 @@ class ServerProfile: NSObject { var password:String = "" var remark:String = "" var ota: Bool = false // onetime authentication + var ssrProtocol:String = "" + var ssrProtocolParam:String = "" + var ssrObfs:String = "" + var ssrObfsParam:String = "" override init() { uuid = NSUUID().UUIDString @@ -41,6 +45,18 @@ class ServerProfile: NSObject { if let ota = data["OTA"] { profile.ota = ota as! Bool } + if let ssrProtocol = data["ssrProtocol"]{ + profile.ssrProtocol = ssrProtocol as! String + } + if let ssrProtocolParam = data["ssrProtocolParam"]{ + profile.ssrProtocolParam = ssrProtocolParam as! String + } + if let ssrObfs = data["ssrObfs"]{ + profile.ssrObfs = ssrObfs as! String + } + if let ssrObfsParam = data["ssrObfsParam"]{ + profile.ssrObfsParam = ssrObfsParam as! String + } } if let id = data["Id"] as? String { @@ -63,6 +79,10 @@ class ServerProfile: NSObject { d["Password"] = password d["Remark"] = remark d["OTA"] = ota + d["ssrProtocol"] = ssrProtocol + d["ssrProtocolParam"] = ssrProtocolParam + d["ssrObfs"] = ssrObfs + d["ssrObfsParam"] = ssrObfsParam return d } @@ -77,6 +97,12 @@ class ServerProfile: NSObject { conf["local_address"] = defaults.stringForKey("LocalSocks5.ListenAddress") conf["timeout"] = NSNumber(unsignedInt: UInt32(defaults.integerForKey("LocalSocks5.Timeout"))) conf["auth"] = NSNumber(bool: ota) + if(!ssrObfs.isEmpty){ + conf["ssrProtocol"] = ssrProtocol + conf["ssrProtocolParam"] = ssrProtocolParam + conf["ssrObfs"] = ssrObfs + conf["ssrObfsParam"] = ssrObfsParam + } return conf } @@ -117,16 +143,39 @@ class ServerProfile: NSObject { return false } + if (ssrProtocol.isEmpty && !ssrObfs.isEmpty)||(!ssrProtocol.isEmpty && ssrObfs.isEmpty){ + return false + } + return true } func URL() -> NSURL? { - let parts = "\(method):\(password)@\(serverHost):\(serverPort)" - let base64String = parts.dataUsingEncoding(NSUTF8StringEncoding)? - .base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) - if var s = base64String { - s = s.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "=")) - return NSURL(string: "ss://\(s)") + if(ssrObfs==""){ + let parts = "\(method):\(password)@\(serverHost):\(serverPort)" + let base64String = parts.dataUsingEncoding(NSUTF8StringEncoding)? + .base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) + if var s = base64String { + s = s.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "=")) + return NSURL(string: "ss://\(s)") + } + }else{ + let firstParts = "\(serverHost):\(serverPort):\(ssrProtocol):\(method):\(ssrObfs):" + let secondParts = "\(password)" + //base64(abc.xyz:12345:auth_sha1_v2:rc4-md5:tls1.2_ticket_auth:{base64(password)}/?obfsparam={base64(混淆参数(网址))}&remarks={base64(节点名称)}) + let base64PasswordString = secondParts.dataUsingEncoding(NSUTF8StringEncoding)? + .base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) + + let base64ssrObfsParamString = ssrObfsParam.dataUsingEncoding(NSUTF8StringEncoding)? + .base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) + + let base64RemarkString = remark.dataUsingEncoding(NSUTF8StringEncoding)? + .base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) + + var s = firstParts + base64PasswordString! + "/?" + "obfsparam=" + base64ssrObfsParamString! + "&remarks=" + base64RemarkString! + s = (s.dataUsingEncoding(NSUTF8StringEncoding)? + .base64EncodedStringWithOptions(NSDataBase64EncodingOptions()))! + return NSURL(string: "ssr://\(s)") } return nil } diff --git a/ShadowsocksX-NG/Utils.m b/ShadowsocksX-NG/Utils.m index d6f3402..c5c633a 100644 --- a/ShadowsocksX-NG/Utils.m +++ b/ShadowsocksX-NG/Utils.m @@ -73,6 +73,9 @@ void ScanQRCodeOnScreen() { } // 解析SS URL,如果成功则返回一个与ServerProfile类兼容的dict +// 或SSR URL,ServerProfile类已经默认添加SSR参数,默认放空,如果URL为SSR://则改变解析方法 +// ss:// + base64(method:password@domain:port) +// ssr:// + base64(abc.xyz:12345:auth_sha1_v2:rc4-md5:tls1.2_ticket_auth:{base64(password)}/?obfsparam={base64(混淆参数(网址))}&remarks={base64(节点名称)}) NSDictionary* ParseSSURL(NSURL* url) { if (!url.host) { return nil; @@ -81,53 +84,58 @@ NSDictionary* ParseSSURL(NSURL* url) { NSString *urlString = [url absoluteString]; int i = 0; NSString *errorReason = nil; - while(i < 2) { - if (i == 1) { - NSString* host = url.host; - if ([host length]%4!=0) { - int n = 4 - [host length]%4; - if (1==n) { - host = [host stringByAppendingString:@"="]; - } else if (2==n) { - host = [host stringByAppendingString:@"=="]; + if([[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL ] hasPrefix:@"ss://"]){ + while(i < 2) { + if (i == 1) { + NSString* host = url.host; + if ([host length]%4!=0) { + int n = 4 - [host length]%4; + if (1==n) { + host = [host stringByAppendingString:@"="]; + } else if (2==n) { + host = [host stringByAppendingString:@"=="]; + } } + NSData *data = [[NSData alloc] initWithBase64EncodedString:host options:0]; + NSString *decodedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + urlString = decodedString; } - NSData *data = [[NSData alloc] initWithBase64EncodedString:host options:0]; - NSString *decodedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - urlString = decodedString; + i++; + urlString = [urlString stringByReplacingOccurrencesOfString:@"ss://" withString:@"" options:NSAnchoredSearch range:NSMakeRange(0, urlString.length)]; + NSRange firstColonRange = [urlString rangeOfString:@":"]; + NSRange lastColonRange = [urlString rangeOfString:@":" options:NSBackwardsSearch]; + NSRange lastAtRange = [urlString rangeOfString:@"@" options:NSBackwardsSearch]; + if (firstColonRange.length == 0) { + errorReason = @"colon not found"; + continue; + } + if (firstColonRange.location == lastColonRange.location) { + errorReason = @"only one colon"; + continue; + } + if (lastAtRange.length == 0) { + errorReason = @"at not found"; + continue; + } + if (!((firstColonRange.location < lastAtRange.location) && (lastAtRange.location < lastColonRange.location))) { + errorReason = @"wrong position"; + continue; + } + NSString *method = [urlString substringWithRange:NSMakeRange(0, firstColonRange.location)]; + NSString *password = [urlString substringWithRange:NSMakeRange(firstColonRange.location + 1, lastAtRange.location - firstColonRange.location - 1)]; + NSString *IP = [urlString substringWithRange:NSMakeRange(lastAtRange.location + 1, lastColonRange.location - lastAtRange.location - 1)]; + NSString *port = [urlString substringWithRange:NSMakeRange(lastColonRange.location + 1, urlString.length - lastColonRange.location - 1)]; + + + return @{@"ServerHost": IP, + @"ServerPort": @([port integerValue]), + @"Method": method, + @"Password": password, + }; } - i++; - urlString = [urlString stringByReplacingOccurrencesOfString:@"ss://" withString:@"" options:NSAnchoredSearch range:NSMakeRange(0, urlString.length)]; - NSRange firstColonRange = [urlString rangeOfString:@":"]; - NSRange lastColonRange = [urlString rangeOfString:@":" options:NSBackwardsSearch]; - NSRange lastAtRange = [urlString rangeOfString:@"@" options:NSBackwardsSearch]; - if (firstColonRange.length == 0) { - errorReason = @"colon not found"; - continue; - } - if (firstColonRange.location == lastColonRange.location) { - errorReason = @"only one colon"; - continue; - } - if (lastAtRange.length == 0) { - errorReason = @"at not found"; - continue; - } - if (!((firstColonRange.location < lastAtRange.location) && (lastAtRange.location < lastColonRange.location))) { - errorReason = @"wrong position"; - continue; - } - NSString *method = [urlString substringWithRange:NSMakeRange(0, firstColonRange.location)]; - NSString *password = [urlString substringWithRange:NSMakeRange(firstColonRange.location + 1, lastAtRange.location - firstColonRange.location - 1)]; - NSString *IP = [urlString substringWithRange:NSMakeRange(lastAtRange.location + 1, lastColonRange.location - lastAtRange.location - 1)]; - NSString *port = [urlString substringWithRange:NSMakeRange(lastColonRange.location + 1, urlString.length - lastColonRange.location - 1)]; + + }else if ([[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL ] hasPrefix:@"ssr://"]){ - - return @{@"ServerHost": IP, - @"ServerPort": @([port integerValue]), - @"Method": method, - @"Password": password, - }; } - return nil; + return nil; } diff --git a/ShadowsocksX-NG/install_ss_local.sh b/ShadowsocksX-NG/install_ss_local.sh index dc9cbaa..41d78f9 100755 --- a/ShadowsocksX-NG/install_ss_local.sh +++ b/ShadowsocksX-NG/install_ss_local.sh @@ -8,10 +8,10 @@ cd `dirname "${BASH_SOURCE[0]}"` -mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6" -cp -f ss-local "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6/" +mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.8" +cp -f ss-local "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.8/" rm -f "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local" -ln -s "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6/ss-local" "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local" +ln -s "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.8/ss-local" "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local" cp -f libcrypto.1.0.0.dylib "$HOME/Library/Application Support/ShadowsocksX-NG/" diff --git a/ShadowsocksX-NG/ss-local b/ShadowsocksX-NG/ss-local index c254766..68206e0 100755 Binary files a/ShadowsocksX-NG/ss-local and b/ShadowsocksX-NG/ss-local differ diff --git a/ShadowsocksX-NG/zh-Hans.lproj/PreferencesWindowController.strings b/ShadowsocksX-NG/zh-Hans.lproj/PreferencesWindowController.strings index afd97be..7158303 100644 --- a/ShadowsocksX-NG/zh-Hans.lproj/PreferencesWindowController.strings +++ b/ShadowsocksX-NG/zh-Hans.lproj/PreferencesWindowController.strings @@ -34,3 +34,18 @@ /* Class = "NSButtonCell"; title = "OK"; ObjectID = "zPE-oD-PwK"; */ "zPE-oD-PwK.title" = "确定"; + +/* Class = "NSTextFieldCell"; title = "SSR Settings (Left empty if not sure what it is"; ObjectID = "Vtp-4J-er7.title";*/ +"Vtp-4J-er7.title" = "SSR设置,不清楚请留空"; + +/* Class = "NSTextFieldCell"; title = "Obfs"; ObjectID = "Vtp-4J-er7.title";*/ +"aQj-D7-XWZ.title" = "混淆" + +/* Class = "NSTextFieldCell"; title = "Obfs Param"; ObjectID = "Vtp-4J-er7.title";*/ +"g7c-fW-7J4.title" = "混淆参数" + +/* Class = "NSTextFieldCell"; title = "Protocol"; ObjectID = "nmk-Ue-wYb,title";*/ +"nmk-Ue-wYb,title" = "协议" + +/* Class = "NSTextFieldCell"; title = "Protocol Param"; ObjectID = "Vtp-4J-er7.title";*/ +"dCk-qx-L1X.title" = "协议参数"