-
Notifications
You must be signed in to change notification settings - Fork 98
/
OnionProxyContext.java
210 lines (176 loc) · 6.83 KB
/
OnionProxyContext.java
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
Copyright (c) Microsoft Open Technologies, Inc.
All Rights Reserved
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache 2 License for the specific language governing permissions and limitations under the License.
*/
package com.msopentech.thali.toronionproxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* Provides context information about the environment. Implementating classes provide logic for setting up
* the specific environment
*/
abstract public class OnionProxyContext {
protected static final Logger LOG = LoggerFactory.getLogger(OnionProxyContext.class);
/**
* Tor configuration info used for running and installing tor
*/
protected final TorConfig config;
private final Object dataDirLock = new Object();
private final Object dnsLock = new Object();
private final Object cookieLock = new Object();
private final Object hostnameLock = new Object();
private final TorSettings settings;
/**
* Constructs instance of <code>OnionProxyContext</code> with specified configDir. Use this constructor when
* all tor files (including the executable) are under a single directory. Currently, this is used with installers
* that assemble all necessary files into one location.
*
* @param configDir
* @throws IllegalArgumentException if specified config in null
*/
public OnionProxyContext(File configDir) {
this(new TorConfig.Builder(configDir).build(), null);
}
/**
* Constructs instance of <code>OnionProxyContext</code> with the specified torConfig. Typically this constructor
* will be used when tor is currently installed on the system, with the tor executable and config files in different
* locations.
*
* @param torConfig tor configuration info used for running and installing tor
* @throws IllegalArgumentException if specified config in null
*/
public OnionProxyContext(TorConfig torConfig, TorSettings settings) {
if (torConfig == null) {
throw new IllegalArgumentException("torConfig is null");
}
this.config = torConfig;
this.settings = settings == null ? new DefaultSettings() : settings;
}
/**
* Gets tor configuration info used for running and installing tor
*
* @return tor config info
*/
public final TorConfig getConfig() {
return config;
}
/**
* Creates the configured tor data directory
*
* @return true is directory already exists or has been successfully created, otherwise false
*/
public final boolean createDataDir() {
synchronized (dataDirLock) {
return config.getDataDir().exists() || config.getDataDir().mkdirs();
}
}
/**
* Deletes the configured tor data directory
*/
public final void deleteDataDir() {
synchronized (dataDirLock) {
for (File file : config.getDataDir().listFiles()) {
if (file.isDirectory()) {
if (!file.getAbsolutePath().equals(config.getHiddenServiceDir().getAbsolutePath())) {
FileUtilities.recursiveFileDelete(file);
}
} else {
if (!file.delete()) {
throw new RuntimeException("Could not delete file " + file.getAbsolutePath());
}
}
}
}
}
/**
* Creates an empty cookie auth file
*
* @return true if cookie file is created, otherwise false
*/
public final boolean createCookieAuthFile() {
synchronized (cookieLock) {
File cookieAuthFile = config.getCookieAuthFile();
if (!cookieAuthFile.getParentFile().exists() &&
!cookieAuthFile.getParentFile().mkdirs()) {
LOG.warn("Could not create cookieFile parent directory");
return false;
}
try {
return (cookieAuthFile.exists() || cookieAuthFile.createNewFile());
} catch (IOException e) {
LOG.warn("Could not create cookieFile");
return false;
}
}
}
public final boolean createHostnameFile() {
synchronized (hostnameLock) {
File hostnameFile = config.getHostnameFile();
if (!hostnameFile.getParentFile().exists() &&
!hostnameFile.getParentFile().mkdirs()) {
LOG.warn("Could not create hostnameFile parent directory");
return false;
}
try {
return (hostnameFile.exists() || hostnameFile.createNewFile());
} catch (IOException e) {
LOG.warn("Could not create hostnameFile");
return false;
}
}
}
public final File createGoogleNameserverFile() throws IOException {
synchronized (dnsLock) {
File file = config.getResolveConf();
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
writer.write("nameserver 8.8.8.8\n");
writer.write("nameserver 8.8.4.4\n");
writer.close();
return file;
}
}
/**
* Creates an observer for the configured cookie auth file
*
* @return write observer for cookie auth file
*/
public final WriteObserver createCookieAuthFileObserver() throws IOException {
synchronized (cookieLock) {
return generateWriteObserver(config.getCookieAuthFile());
}
}
/**
* Creates an observer for the configured hostname file
*
* @return write observer for hostname file
*/
public final WriteObserver createHostnameDirObserver() throws IOException {
synchronized (hostnameLock) {
return generateWriteObserver(config.getHostnameFile());
}
}
public final TorSettings getSettings() {
return settings;
}
public final TorConfigBuilder newConfigBuilder() {
return new TorConfigBuilder(this);
}
/**
* Returns the system process id of the process running this onion proxy
*
* @return process id
*/
public abstract String getProcessId();
public abstract WriteObserver generateWriteObserver(File file) throws IOException;
public abstract TorInstaller getInstaller();
}