mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Use encrypted connection to server (TLS)
This commit is contained in:
41
app/src/main/assets/cacert.pem
Normal file
41
app/src/main/assets/cacert.pem
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
|
||||||
|
IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
|
||||||
|
IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
|
||||||
|
Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
|
||||||
|
BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
|
||||||
|
MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
|
||||||
|
ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
|
||||||
|
8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
|
||||||
|
zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
|
||||||
|
fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
|
||||||
|
w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
|
||||||
|
G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
|
||||||
|
epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
|
||||||
|
laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
|
||||||
|
QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
|
||||||
|
fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
|
||||||
|
YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
|
||||||
|
ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
|
||||||
|
gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
|
||||||
|
MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
|
||||||
|
IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
|
||||||
|
dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
|
||||||
|
czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
|
||||||
|
dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
|
||||||
|
aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
|
||||||
|
AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
|
||||||
|
b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
|
||||||
|
ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
|
||||||
|
nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
|
||||||
|
18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
|
||||||
|
gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
|
||||||
|
Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
|
||||||
|
sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
|
||||||
|
SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
|
||||||
|
CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
|
||||||
|
GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
|
||||||
|
zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
|
||||||
|
omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -32,11 +32,18 @@ import org.isoron.uhabits.helpers.DatabaseHelper;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
|
|
||||||
import io.socket.client.IO;
|
import io.socket.client.IO;
|
||||||
import io.socket.client.Socket;
|
import io.socket.client.Socket;
|
||||||
import io.socket.emitter.Emitter;
|
import io.socket.emitter.Emitter;
|
||||||
@@ -50,7 +57,7 @@ public class SyncManager
|
|||||||
public static final String EVENT_FETCH = "fetch";
|
public static final String EVENT_FETCH = "fetch";
|
||||||
public static final String EVENT_FETCH_OK = "fetchOK";
|
public static final String EVENT_FETCH_OK = "fetchOK";
|
||||||
|
|
||||||
public static final String SYNC_SERVER_URL = "http://sync.loophabits.org:4000";
|
public static final String SYNC_SERVER_URL = "https://sync.loophabits.org:4000";
|
||||||
|
|
||||||
private static String GROUP_KEY;
|
private static String GROUP_KEY;
|
||||||
private static String CLIENT_ID;
|
private static String CLIENT_ID;
|
||||||
@@ -75,6 +82,8 @@ public class SyncManager
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
IO.setDefaultSSLContext(getCACertSSLContext());
|
||||||
|
|
||||||
socket = IO.socket(SYNC_SERVER_URL);
|
socket = IO.socket(SYNC_SERVER_URL);
|
||||||
|
|
||||||
logSocketEvent(socket, Socket.EVENT_CONNECT, "Connected");
|
logSocketEvent(socket, Socket.EVENT_CONNECT, "Connected");
|
||||||
@@ -100,7 +109,34 @@ public class SyncManager
|
|||||||
}
|
}
|
||||||
catch (URISyntaxException e)
|
catch (URISyntaxException e)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(e.getMessage());
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SSLContext getCACertSSLContext()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||||
|
InputStream caInput = activity.getAssets().open("cacert.pem");
|
||||||
|
Certificate ca = cf.generateCertificate(caInput);
|
||||||
|
|
||||||
|
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||||
|
ks.load(null, null);
|
||||||
|
ks.setCertificateEntry("ca", ca);
|
||||||
|
|
||||||
|
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
|
||||||
|
TrustManagerFactory.getDefaultAlgorithm());
|
||||||
|
tmf.init(ks);
|
||||||
|
|
||||||
|
SSLContext ctx = SSLContext.getInstance("TLS");
|
||||||
|
ctx.init(null, tmf.getTrustManagers(), null);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +206,7 @@ public class SyncManager
|
|||||||
}
|
}
|
||||||
catch (JSONException e)
|
catch (JSONException e)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(e.getMessage());
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,15 +226,10 @@ public class SyncManager
|
|||||||
}
|
}
|
||||||
catch (JSONException e)
|
catch (JSONException e)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(e.getMessage());
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLastSync(Long timestamp)
|
|
||||||
{
|
|
||||||
prefs.edit().putLong("lastSync", timestamp).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeCommand(JSONObject root) throws JSONException
|
private void executeCommand(JSONObject root) throws JSONException
|
||||||
{
|
{
|
||||||
Command received = CommandParser.fromJSON(root);
|
Command received = CommandParser.fromJSON(root);
|
||||||
@@ -243,7 +274,7 @@ public class SyncManager
|
|||||||
}
|
}
|
||||||
catch (JSONException e)
|
catch (JSONException e)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(e.getMessage());
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,11 +283,22 @@ public class SyncManager
|
|||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void call(Object... args)
|
public void call(Object... args)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Log.i("SyncManager", "Fetch OK");
|
Log.i("SyncManager", "Fetch OK");
|
||||||
|
|
||||||
|
JSONObject json = new JSONObject((String) args[0]);
|
||||||
|
updateLastSync(json.getLong("timestamp"));
|
||||||
|
|
||||||
emitPending();
|
emitPending();
|
||||||
readyToEmit = true;
|
readyToEmit = true;
|
||||||
}
|
}
|
||||||
|
catch (JSONException e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OnDisconnectListener implements Emitter.Listener
|
private class OnDisconnectListener implements Emitter.Listener
|
||||||
@@ -267,4 +309,9 @@ public class SyncManager
|
|||||||
readyToEmit = false;
|
readyToEmit = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateLastSync(Long timestamp)
|
||||||
|
{
|
||||||
|
prefs.edit().putLong("lastSync", timestamp).apply();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user