mirror of
https://github.com/qinyuhang/ShadowsocksX-NG-R.git
synced 2026-10-09 21:23:53 +00:00
226 lines
8.7 KiB
Objective-C
226 lines
8.7 KiB
Objective-C
//
|
|
// ProxyConfHelper.m
|
|
// ShadowsocksX-NG
|
|
//
|
|
// Created by 邱宇舟 on 16/6/10.
|
|
// Copyright © 2016年 qiuyuzhou. All rights reserved.
|
|
//
|
|
|
|
#import "ProxyConfHelper.h"
|
|
#import "proxy_conf_helper_version.h"
|
|
|
|
#define kShadowsocksHelper @"/Library/Application Support/ShadowsocksX-NG/proxy_conf_helper"
|
|
|
|
@implementation ProxyConfHelper
|
|
|
|
GCDWebServer *webServer = nil;
|
|
|
|
+ (BOOL)isVersionOk {
|
|
NSTask *task;
|
|
task = [[NSTask alloc] init];
|
|
[task setLaunchPath:kShadowsocksHelper];
|
|
|
|
NSArray *args;
|
|
args = [NSArray arrayWithObjects:@"-v", nil];
|
|
[task setArguments: args];
|
|
|
|
NSPipe *pipe;
|
|
pipe = [NSPipe pipe];
|
|
[task setStandardOutput:pipe];
|
|
|
|
NSFileHandle *fd;
|
|
fd = [pipe fileHandleForReading];
|
|
|
|
[task launch];
|
|
|
|
NSData *data;
|
|
data = [fd readDataToEndOfFile];
|
|
|
|
NSString *str;
|
|
str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
|
|
if (![str isEqualToString:kProxyConfHelperVersion]) {
|
|
return NO;
|
|
}
|
|
return YES;
|
|
}
|
|
|
|
+ (void)install {
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
if (![fileManager fileExistsAtPath:kShadowsocksHelper] || ![self isVersionOk]) {
|
|
NSString *helperPath = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"install_helper.sh"];
|
|
NSLog(@"run install script: %@", helperPath);
|
|
NSDictionary *error;
|
|
NSString *script = [NSString stringWithFormat:@"do shell script \"bash %@\" with administrator privileges", helperPath];
|
|
NSAppleScript *appleScript = [[NSAppleScript new] initWithSource:script];
|
|
if ([appleScript executeAndReturnError:&error]) {
|
|
NSLog(@"installation success");
|
|
} else {
|
|
NSLog(@"installation failure");
|
|
}
|
|
}
|
|
}
|
|
|
|
+ (void)callHelper:(NSArray*) arguments {
|
|
NSTask *task;
|
|
task = [[NSTask alloc] init];
|
|
[task setLaunchPath:kShadowsocksHelper];
|
|
|
|
// this log is very important
|
|
NSLog(@"run shadowsocks helper: %@", kShadowsocksHelper);
|
|
[task setArguments:arguments];
|
|
|
|
NSPipe *stdoutpipe;
|
|
stdoutpipe = [NSPipe pipe];
|
|
[task setStandardOutput:stdoutpipe];
|
|
|
|
NSPipe *stderrpipe;
|
|
stderrpipe = [NSPipe pipe];
|
|
[task setStandardError:stderrpipe];
|
|
|
|
NSFileHandle *file;
|
|
file = [stdoutpipe fileHandleForReading];
|
|
|
|
[task launch];
|
|
|
|
NSData *data;
|
|
data = [file readDataToEndOfFile];
|
|
|
|
NSString *string;
|
|
string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
if (string.length > 0) {
|
|
NSLog(@"%@", string);
|
|
}
|
|
|
|
file = [stderrpipe fileHandleForReading];
|
|
data = [file readDataToEndOfFile];
|
|
string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
if (string.length > 0) {
|
|
NSLog(@"%@", string);
|
|
}
|
|
}
|
|
|
|
+ (void)addArguments4ManualSpecifyNetworkServices:(NSMutableArray*) args {
|
|
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
|
|
|
if (![defaults boolForKey:@"AutoConfigureNetworkServices"]) {
|
|
NSArray* serviceKeys = [defaults arrayForKey:@"Proxy4NetworkServices"];
|
|
if (serviceKeys) {
|
|
for (NSString* key in serviceKeys) {
|
|
[args addObject:@"--network-service"];
|
|
[args addObject:key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ (void)enablePACProxy:(NSString*) PACFilePath {
|
|
//start server here and then using the string next line
|
|
//next two lines can open gcdwebserver and work around pac file
|
|
NSString *PACURLString = [self startPACServer: PACFilePath];//hi 可以切换成定制pac文件路径来达成使用定制文件路径
|
|
NSURL* url = [NSURL URLWithString: PACURLString];
|
|
// NSString* urlString = [NSString stringWithFormat:@"%@/.ShadowsocksX-NG/gfwlist.js", NSHomeDirectory()];
|
|
// NSURL* url = [NSURL fileURLWithPath:urlString];
|
|
|
|
NSMutableArray* args = [@[@"--mode", @"auto", @"--pac-url", [url absoluteString]]mutableCopy];
|
|
|
|
[self addArguments4ManualSpecifyNetworkServices:args];
|
|
[self callHelper:args];
|
|
}
|
|
|
|
+ (void)enableGlobalProxy {
|
|
NSUInteger port = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalSocks5.ListenPort"];
|
|
|
|
NSMutableArray* args = [@[@"--mode", @"global", @"--port"
|
|
, [NSString stringWithFormat:@"%lu", (unsigned long)port]]mutableCopy];
|
|
|
|
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"LocalHTTPOn"] && [[NSUserDefaults standardUserDefaults] boolForKey:@"LocalHTTP.FollowGlobal"]) {
|
|
NSUInteger privoxyPort = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalHTTP.ListenPort"];
|
|
|
|
[args addObject:@"--privoxy-port"];
|
|
[args addObject:[NSString stringWithFormat:@"%lu", (unsigned long)privoxyPort]];
|
|
}
|
|
|
|
[self addArguments4ManualSpecifyNetworkServices:args];
|
|
[self callHelper:args];
|
|
[self stopPACServer];
|
|
}
|
|
|
|
+ (void)enableWhiteListProxy {
|
|
// 基于全局socks5代理下使用ACL文件来进行白名单代理 不需要使用pac文件
|
|
NSUInteger port = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalSocks5.ListenPort"];
|
|
|
|
NSMutableArray* args = [@[@"--mode", @"global", @"--port"
|
|
, [NSString stringWithFormat:@"%lu", (unsigned long)port]]mutableCopy];
|
|
|
|
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"LocalHTTPOn"] && [[NSUserDefaults standardUserDefaults] boolForKey:@"LocalHTTP.FollowGlobal"]) {
|
|
NSUInteger privoxyPort = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalHTTP.ListenPort"];
|
|
|
|
[args addObject:@"--privoxy-port"];
|
|
[args addObject:[NSString stringWithFormat:@"%lu", (unsigned long)privoxyPort]];
|
|
}
|
|
|
|
[self addArguments4ManualSpecifyNetworkServices:args];
|
|
[self callHelper:args];
|
|
[self stopPACServer];
|
|
}
|
|
|
|
+ (void)disableProxy:(NSString*) PACFilePath {
|
|
// 带上所有参数是为了判断是否原有代理设置是否由ssx-ng设置的。如果是用户手工设置的其他配置,则不进行清空。
|
|
// NSString* urlString = [NSString stringWithFormat:@"%@/.ShadowsocksX-NG/gfwlist.js", NSHomeDirectory()];
|
|
// NSURL* url = [NSURL fileURLWithPath:urlString];
|
|
// NSString *PACURLString = [self startPACServer: PACFilePath];//hi 可以切换成定制pac文件路径来达成使用定制文件路径
|
|
// NSURL* url = [NSURL URLWithString: PACURLString];
|
|
// NSUInteger port = [[NSUserDefaults standardUserDefaults]integerForKey:@"LocalSocks5.ListenPort"];
|
|
//
|
|
// NSMutableArray* args = [@[@"--mode", @"off"
|
|
// , @"--port", [NSString stringWithFormat:@"%lu", (unsigned long)port]
|
|
// , @"--pac-url", [url absoluteString]
|
|
// ]mutableCopy];
|
|
|
|
NSMutableArray* args = [@[@"--mode", @"off"]mutableCopy];
|
|
[self addArguments4ManualSpecifyNetworkServices:args];
|
|
[self callHelper:args];
|
|
[self stopPACServer];
|
|
}
|
|
|
|
+ (NSString*)startPACServer:(NSString*) PACFilePath {
|
|
//接受参数为以后使用定制PAC文件
|
|
NSData * originalPACData;
|
|
NSString * routerPath = @"/proxy.pac";
|
|
if ([PACFilePath isEqual: @"hi"]) {//用默认路径来代替
|
|
PACFilePath = [NSString stringWithFormat:@"%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG/gfwlist.js"];
|
|
originalPACData = [NSData dataWithContentsOfFile: [NSString stringWithFormat:@"%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG/gfwlist.js"]];
|
|
}else{//用定制路径来代替
|
|
originalPACData = [NSData dataWithContentsOfFile: [NSString stringWithFormat:@"%@/%@/%@", NSHomeDirectory(), @".ShadowsocksX-NG", PACFilePath]];
|
|
routerPath = [NSString stringWithFormat:@"/%@",PACFilePath];
|
|
}
|
|
[self stopPACServer];
|
|
webServer = [[GCDWebServer alloc] init];
|
|
[webServer addHandlerForMethod:@"GET" path: routerPath requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request) {
|
|
return [GCDWebServerDataResponse responseWithData: originalPACData contentType:@"application/x-ns-proxy-autoconfig"];
|
|
}
|
|
];
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
NSString * address = [defaults stringForKey:@"PacServer.ListenAddress"];
|
|
int port = (short)[defaults integerForKey:@"PacServer.ListenPort"];
|
|
|
|
// NSMutableDictionary* options = [NSMutableDictionary dictionary];
|
|
// [options setObject:[NSNumber numberWithInteger:port] forKey:GCDWebServerOption_Port];
|
|
// [options setObject:@YES forKey:@"BindToLocalhost"];
|
|
//
|
|
// [webServer startWithOptions:options error:NULL];
|
|
|
|
[webServer startWithOptions:@{@"BindToLocalhost":@YES, @"Port":@(port)} error:nil];
|
|
|
|
return [NSString stringWithFormat:@"%@%@:%d%@",@"http://",address,port,routerPath];
|
|
}
|
|
|
|
+ (void)stopPACServer {
|
|
if ([webServer isRunning]) {
|
|
[webServer stop];
|
|
}
|
|
}
|
|
|
|
@end
|