1//
2// TORConfiguration.m
3// Tor
4//
5// Created by Conrad Kramer on 8/10/15.
6//
7
8#import "TORConfiguration.h"
9
10NS_ASSUME_NONNULL_BEGIN
11
12@implementation TORConfiguration
13
14- (NSMutableDictionary *)options
15{
16 if (!_options) _options = [NSMutableDictionary new];
17
18 return _options;
19}
20
21- (NSMutableArray *)arguments
22{
23 if (!_arguments) _arguments = [NSMutableArray new];
24
25 return _arguments;
26}
27
28- (nullable NSURL *)controlPortFile
29{
30 return [self.dataDirectory URLByAppendingPathComponent:@"controlport"];
31}
32
33- (nullable NSURL *)serviceAuthDirectory
34{
35 return [self.hiddenServiceDirectory URLByAppendingPathComponent:@"authorized_clients"];
36}
37
38- (BOOL)isLocked
39{
40 NSURL *url = [self.dataDirectory URLByAppendingPathComponent:@"lock"];
41 NSString *path = url.path;
42
43 if (!path || !url.isFileURL) return false;
44
45 return [NSFileManager.defaultManager fileExistsAtPath:path];
46}
47
48- (nullable NSData *)cookie
49{
50 NSURL *url = [self.dataDirectory URLByAppendingPathComponent:@"control_auth_cookie"];
51
52 if (!url || !url.isFileURL) return nil;
53
54 return [[NSData alloc] initWithContentsOfURL:url];
55}
56
57- (NSString *)valueOf:(NSString *)key
58{
59 for (NSString *dictKey in self.options.allKeys) {
60 if ([dictKey caseInsensitiveCompare:key] == NSOrderedSame) {
61 return self.options[dictKey];
62 }
63 }
64
65 key = [[NSString alloc] initWithFormat:@"--%@", key];
66
67 for (NSString *arg in self.arguments) {
68 if ([arg caseInsensitiveCompare:key] == NSOrderedSame) {
69 NSUInteger i = [self.arguments indexOfObject:arg];
70
71 if (i + 1 < self.arguments.count) {
72 return self.arguments[i + 1];
73 }
74 }
75 }
76
77 return nil;
78}
79
80- (NSArray<NSString *> *)compile
81{
82 NSMutableArray<NSString *> *arguments = [NSMutableArray new];
83
84 if (self.ignoreMissingTorrc) {
85 [arguments addObjectsFromArray:@[@"--allow-missing-torrc", @"--ignore-missing-torrc"]];
86 }
87
88 if (self.avoidDiskWrites) {
89 [arguments addObjectsFromArray:@[@"--AvoidDiskWrites", @"1"]];
90 }
91
92 if (self.clientOnly) {
93 [arguments addObjectsFromArray:@[@"--ClientOnly", @"1"]];
94 }
95
96 NSString *dataDir = self.dataDirectory.path;
97 if (self.dataDirectory.isFileURL && dataDir) {
98 [arguments addObjectsFromArray:@[@"--DataDirectory", dataDir]];
99 }
100
101 NSString *cacheDir = self.cacheDirectory.path;
102 if (self.cacheDirectory.isFileURL && cacheDir) {
103 [arguments addObjectsFromArray:@[@"--CacheDirectory", cacheDir]];
104 }
105
106 if (self.cookieAuthentication) {
107 [arguments addObjectsFromArray:@[@"--CookieAuthentication", @"1"]];
108 }
109
110 NSString *controlPortFile = self.controlPortFile.path;
111 if (self.autoControlPort && self.controlPortFile.isFileURL && controlPortFile) {
112 [arguments addObjectsFromArray:@[@"--ControlPort", @"auto", @"--ControlPortWriteToFile", controlPortFile]];
113 }
114
115 NSString *controlSocket = self.controlSocket.path;
116 if (self.controlSocket.isFileURL && controlSocket) {
117 [arguments addObjectsFromArray:@[@"--ControlSocket", controlSocket]];
118 }
119
120 NSString *socksPath = self.socksURL.path;
121 if (self.socksURL.isFileURL && socksPath) {
122 [arguments addObjectsFromArray:@[@"--SocksPort", [NSString stringWithFormat:@"unix:%@", socksPath]]];
123 }
124
125 if (self.socksPort > 0) {
126 [arguments addObjectsFromArray:@[@"--SocksPort", [NSString stringWithFormat:@"%lu", (unsigned long)self.socksPort]]];
127 }
128
129 if (self.dnsPort > 0) {
130 [arguments addObjectsFromArray:@[@"--DnsPort", [NSString stringWithFormat:@"%lu", (unsigned long)self.dnsPort]]];
131 }
132
133 NSString *clientAuthDir = self.clientAuthDirectory.path;
134 if (self.clientAuthDirectory.isFileURL && clientAuthDir) {
135 [arguments addObjectsFromArray:@[@"--ClientOnionAuthDir", clientAuthDir]];
136 }
137
138 NSString *hiddenServiceDir = self.hiddenServiceDirectory.path;
139 if (!self.clientOnly && self.hiddenServiceDirectory.isFileURL && hiddenServiceDir) {
140 [arguments addObjectsFromArray:@[@"--HiddenServiceDir", hiddenServiceDir]];
141 }
142
143 NSString *geoipFile = self.geoipFile.path;
144 if (self.geoipFile.isFileURL && geoipFile) {
145 [arguments addObjectsFromArray:@[@"--GeoIPFile", geoipFile]];
146 }
147
148 NSString *geoip6File = self.geoip6File.path;
149 if (self.geoip6File.isFileURL && geoip6File) {
150 [arguments addObjectsFromArray:@[@"--GeoIPv6File", geoip6File]];
151 }
152
153 NSString *logfile = self.logfile.path;
154 if (self.logfile.isFileURL && logfile) {
155 [arguments addObjectsFromArray:@[@"--Log", [NSString stringWithFormat:@"notice file %@", logfile]]];
156 }
157
158 [arguments addObjectsFromArray:self.arguments];
159
160 for (NSString *key in self.options.allKeys) {
161 [arguments addObject:[NSString stringWithFormat:@"--%@", key]];
162
163 NSString *value = self.options[key];
164 if (value) [arguments addObject:value];
165 }
166
167 return arguments;
168}
169
170@end
171
172NS_ASSUME_NONNULL_END