182 lines
6.7 KiB
Objective-C
182 lines
6.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
|
||
|
||
|
||
+ (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];
|
||
|
||
[self addArguments4ManualSpecifyNetworkServices:args];
|
||
|
||
[self callHelper:args];
|
||
}
|
||
|
||
+ (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];
|
||
[self addArguments4ManualSpecifyNetworkServices:args];
|
||
[self callHelper:args];
|
||
}
|
||
|
||
+ (NSString*)startPACServer:(NSString*) PACFilePath {
|
||
//接受参数为以后使用定制PAC文件
|
||
NSData * originalPACData;
|
||
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]];
|
||
}
|
||
GCDWebServer *webServer = [[GCDWebServer alloc] init];
|
||
[webServer addHandlerForMethod:@"GET" path:@"/proxy.pac" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request) {
|
||
return [GCDWebServerDataResponse responseWithData: originalPACData contentType:@"application/x-ns-proxy-autoconfig"];
|
||
}
|
||
];
|
||
int port = 8090;
|
||
[webServer startWithPort:port bonjourName:@"webserver"];
|
||
return @"http://127.0.0.1:8090/proxy.pac";//为以后的定制PAC文件做准备
|
||
}
|
||
|
||
+ (void)stopPACServer {
|
||
//原版似乎没有处理这个,本来设计计划如果切换到全局模式或者手动模式就关掉webserver 似乎没有这个必要了?
|
||
}
|
||
|
||
@end
|