Skip to content

Commit 8d3be4d

Browse files
committed
Merge pull request #36 from yaronyg/master
Upgraded binaries to Tor 2.5.10 and Android to SDK 21
2 parents 5578555 + 0cca8b6 commit 8d3be4d

File tree

22 files changed

+298
-190
lines changed

22 files changed

+298
-190
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ local.properties
2121

2222
# Proguard folder generated by Eclipse
2323
proguard/
24+
25+
# intellij
26+
.idea/

README.md

Lines changed: 136 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,131 @@ __How__: We are really just a thin Java wrapper around the Tor OP binaries and j
1010

1111
__Who__: This work is part of the [Thali Project](http://www.thaliproject.org/mediawiki/index.php?title=Main_Page) and is being actively developed by Yaron Y. Goland assigned to the Microsoft Open Technologies Hub. We absolutely need your help! Please see the FAQ below if you would like to help!
1212

13-
To use the library:
13+
# How do I use this library?
14+
For now you get to build this yourself. Eventually, when it has enough testing, I might consider publishing it to some maven repository.
1415

15-
1. Install local Maven
16-
2. Clone the repo.
17-
3. In your gradle.properties file (I usually keep mine in the .gradle sub-directory of my home directory, gradle knows to look there) put in the following properties:
16+
1. Install local maven (seriously, if you don't do this, nothing else will work)
17+
2. Clone this repo
18+
3. Install the JDK and if you are using Android, the Android SDK as well
19+
4. Navigate to the 'universal' sub-directory and run 'gradlew install'
1820

21+
## Android
22+
If you are going to use this library with Android then go to the 'android' sub-directory and run 'gradlew install'.
23+
24+
Now everything should be built and installed into your local maven.
25+
26+
In your Android project add the following to dependencies in build.gradle:
27+
```groovy
28+
compile 'com.msopentech.thali:ThaliOnionProxyAndroid:0.0.2'
29+
compile 'org.slf4j:slf4j-android:1.7.7'
1930
```
20-
systemProp.MAVEN_UPLOAD_REPO_URL=System.getProperty('user.home') + '.m2/repository'
21-
systemProp.MAVEN_UPLOAD_VERSION=0.0.0
31+
32+
Also add mavenLocal() to your repositories in build.gradle (remember, this is the root level repositories, NOT repositories under buildscript).
33+
34+
While this code doesn't do much, using it is kind of a pain because of all the ceremony in Java land. So if you are going to host a Tor hidden service on your device or if you want to open connections to the Internet via Tor then there are a variety of things you need to know. My recommendation is that you open android/src/androidTest/java/com/msopentech/thali/toronionproxy/TorOnionProxySmokeTest.java and look up the method testHiddenServiceRecycleTime and start reading.
35+
36+
But everyone wants sample code so here is some sample code that will start a hidden service and open a socket to it.
37+
38+
```Java
39+
String fileStorageLocation = "torfiles";
40+
OnionProxyManager onionProxyManager =
41+
new AndroidOnionProxyManager(this.getApplicationContext(), fileStorageLocation);
42+
int totalSecondsPerTorStartup = 4 * 60;
43+
int totalTriesPerTorStartup = 5;
44+
45+
// Start the Tor Onion Proxy
46+
if (onionProxyManager.startWithRepeat(totalSecondsPerTorStartup, totalTriesPerTorStartup) == false) {
47+
Log.e("TorTest", "Couldn't start Tor!");
48+
return;
49+
}
50+
51+
// Start a hidden service listener
52+
int hiddenServicePort = 80;
53+
int localPort = 9343;
54+
String onionAddress = onionProxyManager.publishHiddenService(hiddenServicePort, localPort);
55+
56+
// It can taken anywhere from 30 seconds to a few minutes for Tor to start properly routing
57+
// requests to to a hidden service. So you generally want to try to test connect to it a
58+
// few times. But after the previous call the Tor Onion Proxy will route any requests
59+
// to the returned onionAddress and hiddenServicePort to 127.0.0.1:localPort. So, for example,
60+
// you could just pass localPort into the NanoHTTPD constructor and have a HTTP server listening
61+
// to that port.
62+
63+
// Connect via the TOR network
64+
// In this case we are trying to connect to the hidden service but any IP/DNS address and port can be
65+
// used here.
66+
Socket clientSocket =
67+
Utilities.socks4aSocketConnection(onionAddress, hiddenServicePort, "127.0.0.1", localPort);
68+
69+
// Now the socket is open but note that it can take some time before the Tor network has everything
70+
// connected and connection requests can fail for spurious reasons (especially when connecting to
71+
// hidden services) so have lots of retry logic.
2272
```
2373

24-
These are the values you need to publish to your local maven.
74+
## Java
75+
If you are going to use this library with Java then go to the 'java' sub-directory and run 'gradlew install'.
76+
77+
I would also recommend running 'gradlew test'. This will make sure you are properly set up and will copy your test files which I recommend reading.
2578

26-
4. Then run './gradlew uploadArchives' on Universal.
27-
5. Then run './gradlew build' on either the Android or Java project depending on your needs. The Android project contains an ARM binary. The Java project contains binaries for Linux, Mac and Windows.
79+
Now everything should be build and installed into your local maven.
2880

29-
Note that the Java project requires an additional JAR file that you can find in Universal/libs. Alternatively if you use Maven and uploadArchives then we will install the JAR file in maven local and you can just refer to it that way. For example, one of our Java projects has the following in its gradle
81+
Now go to your build.gradle file (or equivalent) and make sure you add:
82+
```groovy
83+
apply plugin: 'maven'
84+
```
3085

86+
Then go to your repositories and add:
3187
```groovy
32-
compile 'com.msopentech.thali:ThaliOnionProxyJava:0.0.0'
33-
compile 'com.msopentech.thali:BriarJtorctl:0.0.0'
88+
mavenLocal()
3489
```
3590

36-
Those using Android don't need to worry about the additional JAR since it gets packaged automatically with the Android AAR.
91+
Then go to dependencies and add in:
92+
```groovy
93+
compile 'com.msopentech.thali:ThaliOnionProxyJava:0.0.2'
94+
compile 'com.msopentech.thali:BriarJtorctl:0.0.2'
95+
compile 'org.slf4j:slf4j-simple:1.7.7'
96+
```
3797

38-
The main class of interest is the OnionProxyManager. You can create this on Android using the AndroidOnionProxyManager and in Java using the (no points for guessing) JavaOnionProxyManager. See the OnionProxyManager class in universal for details on supported methods and such.
98+
As discussed above, the code in this library is pretty trivial. But using it is hard because of the complexities of Tor and Java. For those in Java land please go to java\src\test\java\com\msopentech\thali\toronionproxy\TorOnionProxySmokeTest and check out testHiddenServiceRecycleTime().
99+
100+
But here is some sample code to get you started.
101+
102+
```Java
103+
String fileStorageLocation = "torfiles";
104+
OnionProxyManager onionProxyManager = new JavaOnionProxyManager(
105+
new JavaOnionProxyContext(
106+
Files.createTempDirectory(fileStorageLocation).toFile()));
107+
108+
int totalSecondsPerTorStartup = 4 * 60;
109+
int totalTriesPerTorStartup = 5;
110+
111+
// Start the Tor Onion Proxy
112+
if (onionProxyManager.startWithRepeat(totalSecondsPerTorStartup, totalTriesPerTorStartup) == false) {
113+
return;
114+
}
115+
116+
// Start a hidden service listener
117+
int hiddenServicePort = 80;
118+
int localPort = 9343;
119+
String onionAddress = onionProxyManager.publishHiddenService(hiddenServicePort, localPort);
120+
121+
// It can taken anywhere from 30 seconds to a few minutes for Tor to start properly routing
122+
// requests to to a hidden service. So you generally want to try to test connect to it a
123+
// few times. But after the previous call the Tor Onion Proxy will route any requests
124+
// to the returned onionAddress and hiddenServicePort to 127.0.0.1:localPort. So, for example,
125+
// you could just pass localPort into the NanoHTTPD constructor and have a HTTP server listening
126+
// to that port.
127+
128+
// Connect via the TOR network
129+
// In this case we are trying to connect to the hidden service but any IP/DNS address and port can be
130+
// used here.
131+
Socket clientSocket =
132+
Utilities.socks4aSocketConnection(onionAddress, hiddenServicePort, "127.0.0.1", localPort);
133+
134+
// Now the socket is open but note that it can take some time before the Tor network has everything
135+
// connected and connection requests can fail for spurious reasons (especially when connecting to
136+
// hidden services) so have lots of retry logic.
137+
```
39138

40139
# Acknowledgements
41140
A huge thanks to Michael Rogers and the Briar project. This project started by literally copying their code (yes, I asked first) which handled things in Android and then expanding it to deal with Java. We are also using Briar's fork of JTorCtl until their patches are accepted by the Guardian Project.
@@ -53,10 +152,13 @@ On top of universal are the java and android projects. They contain code specifi
53152
Note however that shared files like the jtorctl-briar, geoip and torrc are kept in Universal and we use a gradle task to copy them into the android and java projects.
54153

55154
One further complication are tests. Hard experience has taught that putting tests into universal doesn't work well because it means we have to write custom wrappers for each test in android and java in order to run them. So instead the tests live primarily in the android project and we use a gradle task to copy them over to the Java project. This lets us share identical tests but it means that all edits to tests have to happen in the android project. Any changes made to shared test code in the java project will be lost. This should not be an issue for anyone but a dev actually working on Tor_Onion_Proxy_Library, to users its irrelevant.
155+
56156
## What is the maturity of the code in this project?
57-
Well the release version is currently 0.0.0 so that should say something. This is an alpha. We have (literally) one test. Obviously we need a heck of a lot more coverage. But we have run that test and it does actually work which means that the Tor OP is being run and is available.
157+
Well the release version is currently 0.0.2 so that should say something. This is an alpha. We have (literally) one test. Obviously we need a heck of a lot more coverage. But we have run that test and it does actually work which means that the Tor OP is being run and is available.
158+
58159
## Can I run multiple programs next to each other that use this library?
59160
Yes, they won't interfere with each other. We use dynamic ports for both the control and socks channel.
161+
60162
## Can I help with the project?
61163
ABSOLUTELY! You will need to sign a [Contributor License Agreement](https://cla.msopentech.com/) before submitting your pull request. To complete the Contributor License Agreement (CLA), you will need to submit a request via the form and then electronically sign the Contributor License Agreement when you receive the email containing the link to the document. This needs to only be done once for any Microsoft Open Technologies OSS project.
62164

@@ -67,14 +169,27 @@ git config user.email YourAlias@YourDomain
67169
```
68170

69171
What we most need help with right now is test coverage. But we also have a bunch of features we would like to add. See our issues for a list.
172+
70173
## Where does jtorctl-briar.jar come from?
71174
This is a fork of jtorctl with some fixes from Briar. So we got it out of Briar's depot. The plan is that jtorctl is supposed to accept Briar's changes and then we will start to build jtorctl ourselves from the Tor depot directly.
175+
72176
## Where did the binaries for the Tor OP come from?
73-
I grabbed the ARM binary from Briar's depot but I believe they got it from Guardian. We really need to start building that ourselves.
177+
### Android
178+
The ARM binary for Android came from the OrBot distribution available at https://guardianproject.info/releases/. I take the latest PIE release qualify APK, unzip it and go to res/raw and then decompress tor.mp3 and go into bin and copy out the tor executable file and put it into android/src/main/assets
179+
180+
### Windows
181+
I download the Expert Bundle for Windows from https://www.torproject.org/download/download.html.en and took tor.exe, libeay32.dll, libevent-2-0-5.dll, libgcc_s_sjlj-1.dll and ssleay32.dll from the Tor directory. I then need to zip them all together into a file called tor.zip and stick them into java/src/main/resources/native/windows/x86.
182+
183+
### Linux
184+
I download the 32 bit Tor Browser Bundle for Linux from https://www.torproject.org/download/download.html.en and then unzipped and untared it and navigated to tor-browser_en-US\Browser\TorBrowser\Tor\ and copied out the tor and libevent-2.0.so.5 files. Note that for stupid reasons I really should fix I currently need to zip these files together into a file called tor.zip before sticking them into java/src/main/resources/native/linux/x86.
185+
186+
I then do the same thing but this time with the 64 bit download and put the results into the x64 linux sub-directory.
187+
188+
### OS/X
189+
I download the OS/X Tor Browser bundle from https://www.torproject.org/download/download.html.en and using 7Zip opened my way into the dmg file inside of 0.unknown partition\TorBrowser.app\TorBrowser\Tor and copied out tor.real and libevent-2.0.5.dylib. And, as with Linux, I then need to zip those two files together into a file called tor.zip and put that into java/src/main/resources/native/osx/x64.
74190

75-
I grabbed the Windows tor.exe file from Tor's expert bundle. I had to install it and then went into the install files, found tor.exe and extracted it.
76-
I grabbed the OS/X and Linux (both 32 and 64 bit) from the Tor Browser Bundles for those platforms. Note that the Mac version consists of the tor.real and libevent-2.0.5.dylib files. The Linux versions consists of the tor and libevent-2.0.so.5 files.
191+
## Where did the geoip and geoip6 files come from?
192+
I took them from the Data/Tor directory of the Windows Expert Bundle (see previous question).
77193

78-
And yes, we really should just build this all ourselves.
79-
## Where did the geoip file come from?
80-
I'm pretty sure it came from the Windows Expert Bundle.
194+
## Why does the Android code require minSdkVersion 16?!?!?! Why so high?
195+
The issue is the tor executable that I get from Guardian. To run on Lollipop the executable has to be PIE. But PIE support only started with SDK 16. So if I'm going to ship a PIE executable I have to set minSdkVersion to 16. But!!!!! Guardian actually also builds a non-PIE version of the executable. So if you have a use case that requires support for an SDK less than 16 PLEASE PLEASE PLEASE send mail to the [Thali Mailing list](https://pairlist10.pair.net/mailman/listinfo/thali-talk). We absolutely can fix this. We just haven't had a good reason to. So please give us one!

android/build.gradle

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,34 @@ See the Apache 2 License for the specific language governing permissions and lim
1313

1414
buildscript {
1515
repositories {
16+
mavenLocal()
1617
mavenCentral()
1718
}
1819
dependencies {
19-
classpath 'com.android.tools.build:gradle:0.10.+'
20-
classpath 'com.github.dcendents:android-maven-plugin:1.1'
20+
classpath 'com.android.tools.build:gradle:1.0.1'
21+
classpath 'com.github.dcendents:android-maven-plugin:1.2'
2122
}
2223
}
2324

24-
apply plugin: 'android-library'
25+
apply plugin: 'com.android.library'
2526
apply plugin: 'android-maven'
2627

27-
version = System.getProperty('MAVEN_UPLOAD_VERSION')
28+
version = "0.0.2"
2829
group = 'com.msopentech.thali'
2930
archivesBaseName = 'ThaliOnionProxyAndroid'
3031

3132
repositories {
3233
mavenLocal()
3334
mavenCentral()
34-
maven { url "http://thaliartifactory.cloudapp.net/artifactory/libs-snapshot" }
35-
maven { url "http://thaliartifactory.cloudapp.net/artifactory/libs-release" }
3635
}
3736

3837
android {
39-
compileSdkVersion 19
40-
buildToolsVersion "19.0.1"
38+
compileSdkVersion 21
39+
buildToolsVersion "21.1.2"
4140

4241
defaultConfig {
43-
minSdkVersion 1
44-
targetSdkVersion 19
42+
minSdkVersion 16 // Please see the readme if you need Sdk support below 16
43+
targetSdkVersion 21
4544
}
4645

4746
// Needed to work around https://code.google.com/p/android/issues/detail?id=61573#c14
@@ -57,31 +56,11 @@ android {
5756
dependencies {
5857
compile fileTree(dir: '../universal/libs', include: '*.jar')
5958
compile 'org.slf4j:slf4j-api:1.7.7'
60-
compile 'com.msopentech.thali:ThaliOnionProxyUniversal:' + System.getProperty('MAVEN_UPLOAD_VERSION')
59+
compile 'com.msopentech.thali:ThaliOnionProxyUniversal:' + version
6160

6261
androidTestCompile 'org.slf4j:slf4j-android:1.7.7'
6362
}
6463

65-
uploadArchives {
66-
repositories {
67-
mavenDeployer {
68-
repository(url: System.getProperty('MAVEN_UPLOAD_REPO_URL')) {
69-
authentication(userName: System.getProperty('MAVEN_UPLOAD_USERNAME'), password: System.getProperty('MAVEN_UPLOAD_PASSWORD'))
70-
}
71-
72-
pom.project {
73-
licenses {
74-
license {
75-
name 'Apache 2.0'
76-
url 'https://thali.codeplex.com/SourceControl/latest#license.txt'
77-
distribution 'repo'
78-
}
79-
}
80-
}
81-
}
82-
}
83-
}
84-
8564
task sourcesJar(type: Jar) {
8665
classifier = 'sources'
8766
from android.sourceSets.main.java.srcDirs

android/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip

0 commit comments

Comments
 (0)