forked from sinuos-zz/shadowsocks-iOS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShadowsocksRunner.m
More file actions
139 lines (122 loc) · 5.57 KB
/
ShadowsocksRunner.m
File metadata and controls
139 lines (122 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// Created by clowwindy on 14-2-27.
// Copyright (c) 2014 clowwindy. All rights reserved.
//
#import "ShadowsocksRunner.h"
#import "local.h"
@implementation ShadowsocksRunner {
}
+ (BOOL)settingsAreNotComplete {
if ((![ShadowsocksRunner isUsingPublicServer]) && ([[NSUserDefaults standardUserDefaults] stringForKey:kShadowsocksIPKey] == nil ||
[[NSUserDefaults standardUserDefaults] stringForKey:kShadowsocksPortKey] == nil ||
[[NSUserDefaults standardUserDefaults] stringForKey:kShadowsocksPasswordKey] == nil)) {
return YES;
} else {
return NO;
}
}
+ (BOOL)runProxy {
if (![ShadowsocksRunner settingsAreNotComplete]) {
local_main();
return YES;
} else {
#ifdef DEBUG
NSLog(@"warning: settings are not complete");
#endif
return NO;
}
}
+ (void)reloadConfig {
if (![ShadowsocksRunner settingsAreNotComplete]) {
if ([ShadowsocksRunner isUsingPublicServer]) {
set_config("106.186.124.182", "8911", "Shadowsocks", "aes-128-cfb");
memcpy(shadowsocks_key, "\x45\xd1\xd9\x9e\xbd\xf5\x8c\x85\x34\x55\xdd\x65\x46\xcd\x06\xd3", 16);
} else {
NSString *v = [[NSUserDefaults standardUserDefaults] objectForKey:kShadowsocksEncryptionKey];
if (!v) {
v = @"aes-256-cfb";
}
set_config([[[NSUserDefaults standardUserDefaults] stringForKey:kShadowsocksIPKey] cStringUsingEncoding:NSUTF8StringEncoding], [[[NSUserDefaults standardUserDefaults] stringForKey:kShadowsocksPortKey] cStringUsingEncoding:NSUTF8StringEncoding], [[[NSUserDefaults standardUserDefaults] stringForKey:kShadowsocksPasswordKey] cStringUsingEncoding:NSUTF8StringEncoding], [v cStringUsingEncoding:NSUTF8StringEncoding]);
}
}
}
+ (BOOL)openSSURL:(NSURL *)url {
if (!url.host) {
return NO;
}
NSString *urlString = [url absoluteString];
int i = 0;
NSString *errorReason = nil;
while(i < 2) {
if (i == 1) {
NSData *data = [[NSData alloc] initWithBase64Encoding:url.host];
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)];
[ShadowsocksRunner saveConfigForKey:kShadowsocksIPKey value:IP];
[ShadowsocksRunner saveConfigForKey:kShadowsocksPortKey value:port];
[ShadowsocksRunner saveConfigForKey:kShadowsocksPasswordKey value:password];
[ShadowsocksRunner saveConfigForKey:kShadowsocksEncryptionKey value:method];
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:kShadowsocksUsePublicServer];
[ShadowsocksRunner reloadConfig];
return YES;
}
NSLog(@"%@", errorReason);
return NO;
}
+(NSURL *)generateSSURL {
if ([ShadowsocksRunner isUsingPublicServer]) {
return nil;
}
NSString *parts = [NSString stringWithFormat:@"%@:%@@%@:%@",
[ShadowsocksRunner configForKey:kShadowsocksEncryptionKey],
[ShadowsocksRunner configForKey:kShadowsocksPasswordKey],
[ShadowsocksRunner configForKey:kShadowsocksIPKey],
[ShadowsocksRunner configForKey:kShadowsocksPortKey]];
NSString *base64String = [[parts dataUsingEncoding:NSUTF8StringEncoding] base64Encoding];
NSString *urlString = [NSString stringWithFormat:@"ss://%@", base64String];
return [NSURL URLWithString:urlString];
}
+ (void)saveConfigForKey:(NSString *)key value:(NSString *)value {
[[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
}
+ (NSString *)configForKey:(NSString *)key {
return [[NSUserDefaults standardUserDefaults] objectForKey:key];
}
+ (void)setUsingPublicServer:(BOOL)use {
[[NSUserDefaults standardUserDefaults] setBool:use forKey:kShadowsocksUsePublicServer];
}
+ (BOOL)isUsingPublicServer {
NSNumber *usePublicServer = [[NSUserDefaults standardUserDefaults] objectForKey:kShadowsocksUsePublicServer];
if (usePublicServer != nil) {
return [usePublicServer boolValue];
} else {
return YES;
}
}
@end