Skip to content

Commit

Permalink
Add socket proxy and socks5 server to app
Browse files Browse the repository at this point in the history
  • Loading branch information
remyers committed Sep 9, 2020
1 parent 128024b commit ee018e3
Show file tree
Hide file tree
Showing 30 changed files with 1,411 additions and 233 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Expand Up @@ -25,3 +25,7 @@ obj/
jni/libspeex/.deps/
*.sh
pkcs11.password
.venv/
gotenna-public-sdk/.venv/
gotenna-public-sdk/.goTenna
__pycache__
2 changes: 2 additions & 0 deletions app/build.gradle
Expand Up @@ -302,6 +302,7 @@ dependencies {
implementation 'org.apache.httpcomponents:httpclient-android:4.3.5'
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'org.jetbrains:annotations:15.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
annotationProcessor 'androidx.annotation:annotation:1.1.0'
implementation 'com.makeramen:roundedimageview:2.1.0'
Expand Down Expand Up @@ -348,6 +349,7 @@ dependencies {
exclude group: 'com.google.protobuf'
}
implementation 'com.google.guava:guava:27.0.1-android'
implementation 'org.slf4j:slf4j-api:1.7.30'

flipperImplementation 'com.facebook.flipper:flipper:0.32.2'
flipperImplementation 'com.facebook.soloader:soloader:0.8.2'
Expand Down
Expand Up @@ -10,6 +10,7 @@
import android.util.Log;
import android.os.Handler;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import com.gotenna.sdk.GoTenna;
Expand All @@ -28,40 +29,34 @@
import com.gotenna.sdk.data.GTResponse;
import com.gotenna.sdk.data.GTDeviceType;
import com.gotenna.sdk.connection.GTConnectionState;
import com.gotenna.sdk.connection.GTConnectionError;

import org.thoughtcrime.securesms.socksserver.SocksServer;
import org.thoughtcrime.securesms.mesh.models.SMSMessage;
import org.thoughtcrime.securesms.mesh.models.SendMessageInteractor;

import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.mesh.models.Message;
import org.thoughtcrime.securesms.mesh.models.SendMessageInteractor;
import org.thoughtcrime.securesms.mesh.models.TxMessage;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
import org.thoughtcrime.securesms.groups.GroupId;

import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;


// TEST TEST TEST
import org.spongycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.spongycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.ECGenParameterSpec;
import java.security.Security;
import java.util.Random;
import java.util.regex.Pattern;

import static java.lang.Math.ceil;

/**
* A singleton that manages listening for incoming messages from the SDK and parses them into
Expand All @@ -72,7 +67,7 @@
*
* @author ThomasColligan, RichardMyers
*/
public class GTMeshManager implements GTCommandCenter.GTMessageListener, GTCommand.GTCommandResponseListener, GTErrorListener
public class GTMeshManager implements GTCommandCenter.GTMessageListener, GTCommand.GTCommandResponseListener, GTErrorListener, GTConnectionManager.GTConnectionListener
{
//==============================================================================================
// Class Properties
Expand All @@ -97,12 +92,18 @@ public class GTMeshManager implements GTCommandCenter.GTMessageListener, GTComma

private final ArrayList<IncomingMessageListener> incomingMessageListeners;

private SendMessageInteractor sendMessageInteractor;
private SendMessageInteractor sendMessageInteractor;

// set in
private PendingIntent gtSentIntent;
private PendingIntent gtDeliveryIntent;

// socks4/5 proxy server
SocksServer proxyServer = null;

// LND (test) mesh socket server
MeshSocketServer meshSocketServer = null;

//==============================================================================================
// Singleton Methods
//==============================================================================================
Expand Down Expand Up @@ -136,17 +137,36 @@ public void initToken(Context context) {
applicationContext = context;
try {
GoTenna.setApplicationToken(applicationContext, GOTENNA_APP_TOKEN);
if(GoTenna.tokenIsVerified()) {
if(GoTenna.tokenIsVerified()) {
Log.d(TAG, "goTenna token is verified:" + GoTenna.tokenIsVerified());
}
gtConnectionManager = GTConnectionManager.getInstance();
startListening();

sendMessageInteractor = new SendMessageInteractor();
gtConnectionManager = GTConnectionManager.getInstance();
startListening();

sendMessageInteractor = new SendMessageInteractor();

// automatically connect to mesh
if (!isPaired()) {
connect(this);
}
}
}
catch(GTInvalidAppTokenException e) {
e.printStackTrace();
}

// forward traffic on port 1337 to the mesh Internet gateway
try {
// to create SOCKS server proxy to mesh gateway
proxyServer = new SocksServer();
proxyServer.start(8888, new MeshProxyHandlerFactory(sendMessageInteractor));

// to test LND between two mesh nodes laptop IP = 192.168.86.56, where LND node 2 listens on port 9734 for p2p connections
// meshSocketServer = new MeshSocketServer(8888, "192.168.86.56", 9734, sendMessageInteractor);
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
}

public void startListening()
Expand Down Expand Up @@ -238,29 +258,32 @@ public interface IncomingMessageListener
// derived from SmsReceiveJob.storeMessage
public Optional<MessagingDatabase.InsertResult> storeMessage(final Message gtMessage)
{
SmsDatabase database = DatabaseFactory.getSmsDatabase(applicationContext);
database.ensureMigration();
if (gtMessage instanceof SMSMessage) {
SmsDatabase database = DatabaseFactory.getSmsDatabase(applicationContext);
database.ensureMigration();

if (TextSecurePreferences.getNeedsSqlCipherMigration(applicationContext)) {
// TODO: throw new SmsReceiveJob.MigrationPendingException();
}
if (TextSecurePreferences.getNeedsSqlCipherMigration(applicationContext)) {
// TODO: throw new SmsReceiveJob.MigrationPendingException();
}

final String senderGID = "+" + Long.toString(gtMessage.getSenderGID());
Log.d(TAG, "storeMessage from sender GID:" + senderGID);

final String senderGID = "+" + Long.toString(gtMessage.getSenderGID());
Log.d(TAG, "storeMessage from sender GID:" + senderGID);

Recipient recipient = Recipient.external(applicationContext, senderGID);
RecipientId sender = recipient.getId();
IncomingTextMessage message = new IncomingTextMessage(sender, 0, System.currentTimeMillis(), gtMessage.getText(), Optional.absent(),0,false);

if (message.isSecureMessage()) {
IncomingTextMessage placeholder = new IncomingTextMessage(message, "");
Optional<MessagingDatabase.InsertResult> insertResult = database.insertMessageInbox(placeholder);
database.markAsLegacyVersion(insertResult.get().getMessageId());

return insertResult;
} else {
return database.insertMessageInbox(message);
Recipient recipient = Recipient.external(applicationContext, senderGID);
RecipientId sender = recipient.getId();
IncomingTextMessage message = new IncomingTextMessage(sender, 0, System.currentTimeMillis(), gtMessage.getText(), Optional.absent(), 0, false);

if (message.isSecureMessage()) {
IncomingTextMessage placeholder = new IncomingTextMessage(message, "");
Optional<MessagingDatabase.InsertResult> insertResult = database.insertMessageInbox(placeholder);
database.markAsLegacyVersion(insertResult.get().getMessageId());

return insertResult;
} else {
return database.insertMessageInbox(message);
}
}
return Optional.absent();
}

public boolean isPaired() {
Expand Down Expand Up @@ -303,6 +326,7 @@ public void disconnect(GTConnectionManager.GTConnectionListener listener) {
if (listener != null) {
gtConnectionManager.addGtConnectionListener(listener);
}
gtConnectionManager.addGtConnectionListener(this);
gtConnectionManager.disconnect();
}

Expand All @@ -312,6 +336,7 @@ public void connect(GTConnectionManager.GTConnectionListener listener) {
if (listener != null) {
gtConnectionManager.addGtConnectionListener(listener);
}
gtConnectionManager.addGtConnectionListener(this);
gtConnectionManager.clearConnectedGotennaAddress();
gtConnectionManager.scanAndConnect(GTDeviceType.MESH);
}
Expand Down Expand Up @@ -444,4 +469,57 @@ public void onMessageResponseReceived() {
gtSentIntent = null;
gtDeliveryIntent = null;
}

public void setGeoloc() {
// set the geoloc region to current preference
String meshRegion = TextSecurePreferences.getMeshRegion(applicationContext);
Place place = Place.valueOf((String)meshRegion);
android.util.Log.d(TAG, "Set Geoloc Region:" + place.getName());
setGeoloc(place);
}

@Override
public void onConnectionStateUpdated(@NonNull GTConnectionState gtConnectionState) {
switch (gtConnectionState) {
case CONNECTED: {
android.util.Log.d(TAG, "Connected to device.");
setGeoloc();
//meshSocketServer.startServer();
}
break;
case DISCONNECTED: {
android.util.Log.d(TAG, "Disconnected from device.");
//meshSocketServer.stopServer();
GTConnectionManager.getInstance().removeGtConnectionListener(this);
}
break;
case SCANNING: {
android.util.Log.d(TAG, "Scanning for device.");
}
break;
}
}

@Override
public void onConnectionError(@NonNull GTConnectionState connectionState, @NonNull GTConnectionError error)
{
switch (error.getErrorState())
{
case X_UPGRADE_CHECK_FAILED:
/*
This error gets passed when we failed to check if the device is goTenna X. This
could happen due to connectivity issues with the device or error checking if the
device has been remotely upgraded.
*/
//view.showXCheckError();
break;
case NOT_X_DEVICE_ERROR:
/*
This device is confirmed not to be a goTenna X device. Using error.getDetailString()
you can pull the serial number of the connected device.
*/
//view.showNotXDeviceWarning(error.getDetailString());
break;
}
}
}
@@ -0,0 +1,53 @@
package org.thoughtcrime.securesms.mesh.managers;

import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mesh.models.SendMessageInteractor;
import org.thoughtcrime.securesms.socksserver.BasicProxyHandler;
import org.thoughtcrime.securesms.socksserver.SocksConstants;
import org.thoughtcrime.securesms.socksserver.Utils;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ServerSocket;
import java.net.SocketException;

class MeshProxyHandler extends BasicProxyHandler {

// mesh socket server
private MeshSocketServer meshSocketServer = null;
private SendMessageInteractor sendMessageInteractor = null;
static private int meshSocketServerPort = 1337;
private static final int SOCKET_TIMEOUT = 600000;

public MeshProxyHandler(ServerSocket listenSocket, SendMessageInteractor sendMessageInteractor) {
super(listenSocket);
this.sendMessageInteractor = sendMessageInteractor;
try {
getClientSocket().setSoTimeout(SOCKET_TIMEOUT);
int timeout = getClientSocket().getSoTimeout();
} catch (Exception e) {
// could not change timeout
}
}

@Override
public void connectToServer(String server, int port) throws IOException {
// TODO: fix race condition incrementing port used by MeshSocketServer..
int meshPort = meshSocketServerPort++;
meshSocketServer = new MeshSocketServer(meshPort, server, port, sendMessageInteractor);
meshSocketServer.startServer();

super.connectToServer("127.0.0.1", meshPort);
int timeout = getServerSocket().getSoTimeout();
getServerSocket().setSoTimeout(SOCKET_TIMEOUT);

}

@Override
public void close() {
if (meshSocketServer != null) {
meshSocketServer.stopServer();
}
}
}

@@ -0,0 +1,19 @@
package org.thoughtcrime.securesms.mesh.managers;

import org.thoughtcrime.securesms.mesh.models.SendMessageInteractor;
import org.thoughtcrime.securesms.socksserver.ProxyHandlerFactory;

import java.net.ServerSocket;

public class MeshProxyHandlerFactory implements ProxyHandlerFactory {
private SendMessageInteractor sendMessageInteractor = null;

MeshProxyHandlerFactory(SendMessageInteractor sendMessageInteractor) {
this.sendMessageInteractor = sendMessageInteractor;
}

public MeshProxyHandler getInstance(ServerSocket listenSocket) {
return new MeshProxyHandler(listenSocket, sendMessageInteractor);
}

}

0 comments on commit ee018e3

Please sign in to comment.