Skip to content

Commit ee018e3

Browse files
committed
Add socket proxy and socks5 server to app
1 parent 128024b commit ee018e3

30 files changed

+1411
-233
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ obj/
2525
jni/libspeex/.deps/
2626
*.sh
2727
pkcs11.password
28+
.venv/
29+
gotenna-public-sdk/.venv/
30+
gotenna-public-sdk/.goTenna
31+
__pycache__

app/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ dependencies {
302302
implementation 'org.apache.httpcomponents:httpclient-android:4.3.5'
303303
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
304304
implementation 'com.github.bumptech.glide:glide:4.11.0'
305+
implementation 'org.jetbrains:annotations:15.0'
305306
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
306307
annotationProcessor 'androidx.annotation:annotation:1.1.0'
307308
implementation 'com.makeramen:roundedimageview:2.1.0'
@@ -348,6 +349,7 @@ dependencies {
348349
exclude group: 'com.google.protobuf'
349350
}
350351
implementation 'com.google.guava:guava:27.0.1-android'
352+
implementation 'org.slf4j:slf4j-api:1.7.30'
351353

352354
flipperImplementation 'com.facebook.flipper:flipper:0.32.2'
353355
flipperImplementation 'com.facebook.soloader:soloader:0.8.2'

app/src/main/java/org/thoughtcrime/securesms/mesh/managers/GTMeshManager.java

Lines changed: 115 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import android.util.Log;
1111
import android.os.Handler;
1212

13+
import androidx.annotation.NonNull;
1314
import androidx.core.content.ContextCompat;
1415

1516
import com.gotenna.sdk.GoTenna;
@@ -28,40 +29,34 @@
2829
import com.gotenna.sdk.data.GTResponse;
2930
import com.gotenna.sdk.data.GTDeviceType;
3031
import com.gotenna.sdk.connection.GTConnectionState;
32+
import com.gotenna.sdk.connection.GTConnectionError;
3133

34+
import org.thoughtcrime.securesms.socksserver.SocksServer;
3235
import org.thoughtcrime.securesms.mesh.models.SMSMessage;
33-
import org.thoughtcrime.securesms.mesh.models.SendMessageInteractor;
3436

3537
import org.thoughtcrime.securesms.database.DatabaseFactory;
3638
import org.thoughtcrime.securesms.database.MessagingDatabase;
3739
import org.thoughtcrime.securesms.database.SmsDatabase;
3840
import org.thoughtcrime.securesms.mesh.models.Message;
41+
import org.thoughtcrime.securesms.mesh.models.SendMessageInteractor;
3942
import org.thoughtcrime.securesms.mesh.models.TxMessage;
4043
import org.thoughtcrime.securesms.recipients.Recipient;
4144
import org.thoughtcrime.securesms.recipients.RecipientId;
4245
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
4346
import org.thoughtcrime.securesms.util.TextSecurePreferences;
4447
import org.whispersystems.libsignal.util.guava.Optional;
45-
import org.thoughtcrime.securesms.groups.GroupId;
4648

4749
import java.io.UnsupportedEncodingException;
50+
import java.net.ServerSocket;
4851
import java.security.MessageDigest;
4952
import java.security.NoSuchAlgorithmException;
5053
import java.util.ArrayList;
5154
import java.util.Date;
5255

5356

5457
// TEST TEST TEST
55-
import org.spongycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
56-
import org.spongycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
57-
import java.security.KeyPair;
58-
import java.security.KeyPairGenerator;
59-
import java.security.spec.ECGenParameterSpec;
6058
import java.security.Security;
6159
import java.util.Random;
62-
import java.util.regex.Pattern;
63-
64-
import static java.lang.Math.ceil;
6560

6661
/**
6762
* A singleton that manages listening for incoming messages from the SDK and parses them into
@@ -72,7 +67,7 @@
7267
*
7368
* @author ThomasColligan, RichardMyers
7469
*/
75-
public class GTMeshManager implements GTCommandCenter.GTMessageListener, GTCommand.GTCommandResponseListener, GTErrorListener
70+
public class GTMeshManager implements GTCommandCenter.GTMessageListener, GTCommand.GTCommandResponseListener, GTErrorListener, GTConnectionManager.GTConnectionListener
7671
{
7772
//==============================================================================================
7873
// Class Properties
@@ -97,12 +92,18 @@ public class GTMeshManager implements GTCommandCenter.GTMessageListener, GTComma
9792

9893
private final ArrayList<IncomingMessageListener> incomingMessageListeners;
9994

100-
private SendMessageInteractor sendMessageInteractor;
95+
private SendMessageInteractor sendMessageInteractor;
10196

10297
// set in
10398
private PendingIntent gtSentIntent;
10499
private PendingIntent gtDeliveryIntent;
105100

101+
// socks4/5 proxy server
102+
SocksServer proxyServer = null;
103+
104+
// LND (test) mesh socket server
105+
MeshSocketServer meshSocketServer = null;
106+
106107
//==============================================================================================
107108
// Singleton Methods
108109
//==============================================================================================
@@ -136,17 +137,36 @@ public void initToken(Context context) {
136137
applicationContext = context;
137138
try {
138139
GoTenna.setApplicationToken(applicationContext, GOTENNA_APP_TOKEN);
139-
if(GoTenna.tokenIsVerified()) {
140+
if(GoTenna.tokenIsVerified()) {
140141
Log.d(TAG, "goTenna token is verified:" + GoTenna.tokenIsVerified());
141-
}
142-
gtConnectionManager = GTConnectionManager.getInstance();
143-
startListening();
144142

145-
sendMessageInteractor = new SendMessageInteractor();
143+
gtConnectionManager = GTConnectionManager.getInstance();
144+
startListening();
145+
146+
sendMessageInteractor = new SendMessageInteractor();
147+
148+
// automatically connect to mesh
149+
if (!isPaired()) {
150+
connect(this);
151+
}
152+
}
146153
}
147154
catch(GTInvalidAppTokenException e) {
148155
e.printStackTrace();
149156
}
157+
158+
// forward traffic on port 1337 to the mesh Internet gateway
159+
try {
160+
// to create SOCKS server proxy to mesh gateway
161+
proxyServer = new SocksServer();
162+
proxyServer.start(8888, new MeshProxyHandlerFactory(sendMessageInteractor));
163+
164+
// to test LND between two mesh nodes laptop IP = 192.168.86.56, where LND node 2 listens on port 9734 for p2p connections
165+
// meshSocketServer = new MeshSocketServer(8888, "192.168.86.56", 9734, sendMessageInteractor);
166+
}
167+
catch (NoSuchMethodException e) {
168+
e.printStackTrace();
169+
}
150170
}
151171

152172
public void startListening()
@@ -238,29 +258,32 @@ public interface IncomingMessageListener
238258
// derived from SmsReceiveJob.storeMessage
239259
public Optional<MessagingDatabase.InsertResult> storeMessage(final Message gtMessage)
240260
{
241-
SmsDatabase database = DatabaseFactory.getSmsDatabase(applicationContext);
242-
database.ensureMigration();
261+
if (gtMessage instanceof SMSMessage) {
262+
SmsDatabase database = DatabaseFactory.getSmsDatabase(applicationContext);
263+
database.ensureMigration();
243264

244-
if (TextSecurePreferences.getNeedsSqlCipherMigration(applicationContext)) {
245-
// TODO: throw new SmsReceiveJob.MigrationPendingException();
246-
}
265+
if (TextSecurePreferences.getNeedsSqlCipherMigration(applicationContext)) {
266+
// TODO: throw new SmsReceiveJob.MigrationPendingException();
267+
}
268+
269+
final String senderGID = "+" + Long.toString(gtMessage.getSenderGID());
270+
Log.d(TAG, "storeMessage from sender GID:" + senderGID);
247271

248-
final String senderGID = "+" + Long.toString(gtMessage.getSenderGID());
249-
Log.d(TAG, "storeMessage from sender GID:" + senderGID);
250-
251-
Recipient recipient = Recipient.external(applicationContext, senderGID);
252-
RecipientId sender = recipient.getId();
253-
IncomingTextMessage message = new IncomingTextMessage(sender, 0, System.currentTimeMillis(), gtMessage.getText(), Optional.absent(),0,false);
254-
255-
if (message.isSecureMessage()) {
256-
IncomingTextMessage placeholder = new IncomingTextMessage(message, "");
257-
Optional<MessagingDatabase.InsertResult> insertResult = database.insertMessageInbox(placeholder);
258-
database.markAsLegacyVersion(insertResult.get().getMessageId());
259-
260-
return insertResult;
261-
} else {
262-
return database.insertMessageInbox(message);
272+
Recipient recipient = Recipient.external(applicationContext, senderGID);
273+
RecipientId sender = recipient.getId();
274+
IncomingTextMessage message = new IncomingTextMessage(sender, 0, System.currentTimeMillis(), gtMessage.getText(), Optional.absent(), 0, false);
275+
276+
if (message.isSecureMessage()) {
277+
IncomingTextMessage placeholder = new IncomingTextMessage(message, "");
278+
Optional<MessagingDatabase.InsertResult> insertResult = database.insertMessageInbox(placeholder);
279+
database.markAsLegacyVersion(insertResult.get().getMessageId());
280+
281+
return insertResult;
282+
} else {
283+
return database.insertMessageInbox(message);
284+
}
263285
}
286+
return Optional.absent();
264287
}
265288

266289
public boolean isPaired() {
@@ -303,6 +326,7 @@ public void disconnect(GTConnectionManager.GTConnectionListener listener) {
303326
if (listener != null) {
304327
gtConnectionManager.addGtConnectionListener(listener);
305328
}
329+
gtConnectionManager.addGtConnectionListener(this);
306330
gtConnectionManager.disconnect();
307331
}
308332

@@ -312,6 +336,7 @@ public void connect(GTConnectionManager.GTConnectionListener listener) {
312336
if (listener != null) {
313337
gtConnectionManager.addGtConnectionListener(listener);
314338
}
339+
gtConnectionManager.addGtConnectionListener(this);
315340
gtConnectionManager.clearConnectedGotennaAddress();
316341
gtConnectionManager.scanAndConnect(GTDeviceType.MESH);
317342
}
@@ -444,4 +469,57 @@ public void onMessageResponseReceived() {
444469
gtSentIntent = null;
445470
gtDeliveryIntent = null;
446471
}
472+
473+
public void setGeoloc() {
474+
// set the geoloc region to current preference
475+
String meshRegion = TextSecurePreferences.getMeshRegion(applicationContext);
476+
Place place = Place.valueOf((String)meshRegion);
477+
android.util.Log.d(TAG, "Set Geoloc Region:" + place.getName());
478+
setGeoloc(place);
479+
}
480+
481+
@Override
482+
public void onConnectionStateUpdated(@NonNull GTConnectionState gtConnectionState) {
483+
switch (gtConnectionState) {
484+
case CONNECTED: {
485+
android.util.Log.d(TAG, "Connected to device.");
486+
setGeoloc();
487+
//meshSocketServer.startServer();
488+
}
489+
break;
490+
case DISCONNECTED: {
491+
android.util.Log.d(TAG, "Disconnected from device.");
492+
//meshSocketServer.stopServer();
493+
GTConnectionManager.getInstance().removeGtConnectionListener(this);
494+
}
495+
break;
496+
case SCANNING: {
497+
android.util.Log.d(TAG, "Scanning for device.");
498+
}
499+
break;
500+
}
501+
}
502+
503+
@Override
504+
public void onConnectionError(@NonNull GTConnectionState connectionState, @NonNull GTConnectionError error)
505+
{
506+
switch (error.getErrorState())
507+
{
508+
case X_UPGRADE_CHECK_FAILED:
509+
/*
510+
This error gets passed when we failed to check if the device is goTenna X. This
511+
could happen due to connectivity issues with the device or error checking if the
512+
device has been remotely upgraded.
513+
*/
514+
//view.showXCheckError();
515+
break;
516+
case NOT_X_DEVICE_ERROR:
517+
/*
518+
This device is confirmed not to be a goTenna X device. Using error.getDetailString()
519+
you can pull the serial number of the connected device.
520+
*/
521+
//view.showNotXDeviceWarning(error.getDetailString());
522+
break;
523+
}
524+
}
447525
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.thoughtcrime.securesms.mesh.managers;
2+
3+
import org.thoughtcrime.securesms.logging.Log;
4+
import org.thoughtcrime.securesms.mesh.models.SendMessageInteractor;
5+
import org.thoughtcrime.securesms.socksserver.BasicProxyHandler;
6+
import org.thoughtcrime.securesms.socksserver.SocksConstants;
7+
import org.thoughtcrime.securesms.socksserver.Utils;
8+
9+
import java.io.IOException;
10+
import java.io.InterruptedIOException;
11+
import java.net.ServerSocket;
12+
import java.net.SocketException;
13+
14+
class MeshProxyHandler extends BasicProxyHandler {
15+
16+
// mesh socket server
17+
private MeshSocketServer meshSocketServer = null;
18+
private SendMessageInteractor sendMessageInteractor = null;
19+
static private int meshSocketServerPort = 1337;
20+
private static final int SOCKET_TIMEOUT = 600000;
21+
22+
public MeshProxyHandler(ServerSocket listenSocket, SendMessageInteractor sendMessageInteractor) {
23+
super(listenSocket);
24+
this.sendMessageInteractor = sendMessageInteractor;
25+
try {
26+
getClientSocket().setSoTimeout(SOCKET_TIMEOUT);
27+
int timeout = getClientSocket().getSoTimeout();
28+
} catch (Exception e) {
29+
// could not change timeout
30+
}
31+
}
32+
33+
@Override
34+
public void connectToServer(String server, int port) throws IOException {
35+
// TODO: fix race condition incrementing port used by MeshSocketServer..
36+
int meshPort = meshSocketServerPort++;
37+
meshSocketServer = new MeshSocketServer(meshPort, server, port, sendMessageInteractor);
38+
meshSocketServer.startServer();
39+
40+
super.connectToServer("127.0.0.1", meshPort);
41+
int timeout = getServerSocket().getSoTimeout();
42+
getServerSocket().setSoTimeout(SOCKET_TIMEOUT);
43+
44+
}
45+
46+
@Override
47+
public void close() {
48+
if (meshSocketServer != null) {
49+
meshSocketServer.stopServer();
50+
}
51+
}
52+
}
53+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.thoughtcrime.securesms.mesh.managers;
2+
3+
import org.thoughtcrime.securesms.mesh.models.SendMessageInteractor;
4+
import org.thoughtcrime.securesms.socksserver.ProxyHandlerFactory;
5+
6+
import java.net.ServerSocket;
7+
8+
public class MeshProxyHandlerFactory implements ProxyHandlerFactory {
9+
private SendMessageInteractor sendMessageInteractor = null;
10+
11+
MeshProxyHandlerFactory(SendMessageInteractor sendMessageInteractor) {
12+
this.sendMessageInteractor = sendMessageInteractor;
13+
}
14+
15+
public MeshProxyHandler getInstance(ServerSocket listenSocket) {
16+
return new MeshProxyHandler(listenSocket, sendMessageInteractor);
17+
}
18+
19+
}

0 commit comments

Comments
 (0)