From 95e0ab7b29924d581a1bd4a5fc5237d7a3439111 Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Thu, 4 Jul 2019 13:27:38 +0200 Subject: [PATCH 01/19] (chore) migrate to Android Studio and update compile SDK version Signed-off-by: Balint Kovacs --- .idea/encodings.xml | 4 + .idea/gradle.xml | 18 +++ .idea/misc.xml | 41 +++++ .idea/modules.xml | 8 + .idea/modules/SSLDroid.iml | 141 ++++++++++++++++++ .idea/runConfigurations.xml | 12 ++ .idea/vcs.xml | 6 + AndroidManifest.xml | 12 +- assets/ssldroid_logo.svg | 1 + build.gradle | 22 ++- gradle/wrapper/gradle-wrapper.properties | 4 +- res/xml/ssldroid_backup_rules.xml | 6 + src/hu/blint/ssldroid/Relay.java | 2 +- src/hu/blint/ssldroid/SSLDroid.java | 33 ++-- .../blint/ssldroid/SSLDroidProvisioning.java | 6 + 15 files changed, 286 insertions(+), 30 deletions(-) create mode 100644 .idea/encodings.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/modules/SSLDroid.iml create mode 100644 .idea/runConfigurations.xml create mode 100644 .idea/vcs.xml create mode 100644 res/xml/ssldroid_backup_rules.xml create mode 100644 src/hu/blint/ssldroid/SSLDroidProvisioning.java diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..2d5721d --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..a0fceb0 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,41 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..dfd7a29 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/SSLDroid.iml b/.idea/modules/SSLDroid.iml new file mode 100644 index 0000000..d1bee72 --- /dev/null +++ b/.idea/modules/SSLDroid.iml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 36d852d..2c6ff0f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,16 +1,18 @@ - + xmlns:tools="http://schemas.android.com/tools" + package="hu.blint.ssldroid" + android:versionCode="10" + android:versionName="1.3" + tools:ignore="GoogleAppIndexingWarning"> + - - + diff --git a/assets/ssldroid_logo.svg b/assets/ssldroid_logo.svg index 15f98e6..ae11aad 100644 --- a/assets/ssldroid_logo.svg +++ b/assets/ssldroid_logo.svg @@ -1,6 +1,7 @@ + // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... // This moves them out of them default location under src//... which would - // conflict with src/ being used by the main source set. + // conflict with src/ being used bythe main source set. // Adding new build types or product flavors should be accompanied // by a similar customization. debug.setRoot('build-types/debug') release.setRoot('build-types/release') } + defaultConfig { + minSdkVersion 16 + targetSdkVersion 29 + } } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b223032..44fe5ba 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Jul 25 01:04:55 EDT 2015 +#Thu Jul 04 10:15:24 CEST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip diff --git a/res/xml/ssldroid_backup_rules.xml b/res/xml/ssldroid_backup_rules.xml new file mode 100644 index 0000000..0aae6b7 --- /dev/null +++ b/res/xml/ssldroid_backup_rules.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/hu/blint/ssldroid/Relay.java b/src/hu/blint/ssldroid/Relay.java index 4fa59a4..6ec55d7 100644 --- a/src/hu/blint/ssldroid/Relay.java +++ b/src/hu/blint/ssldroid/Relay.java @@ -9,7 +9,7 @@ public class Relay extends Thread { /** - * + * */ private final TcpProxyServerThread tcpProxyServerThread; private InputStream in; diff --git a/src/hu/blint/ssldroid/SSLDroid.java b/src/hu/blint/ssldroid/SSLDroid.java index 0870de3..507813c 100644 --- a/src/hu/blint/ssldroid/SSLDroid.java +++ b/src/hu/blint/ssldroid/SSLDroid.java @@ -14,7 +14,7 @@ public class SSLDroid extends Service { final String TAG = "SSLDroid"; - TcpProxy tp[]; + TcpProxy[] tp; private SSLDroidDbAdapter dbHelper; @Override @@ -62,7 +62,6 @@ public void onCreate() { } } - cursor.deactivate(); cursor.close(); dbHelper.close(); createNotification(0, true, "SSLDroid is running", "Started and serving "+tunnelcount+" tunnels"); @@ -113,22 +112,24 @@ public void removeNotification(int id) { public void createNotification(int id, boolean persistent, String title, String text) { NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - Notification notification = new Notification(R.drawable.icon, - "SSLDroid startup", System.currentTimeMillis()); - // if requested, make the notification persistent, e.g. not clearable by the user at all, - // automatically hide on displaying the main activity otherwise - if (persistent == true) - notification.flags |= Notification.FLAG_NO_CLEAR; - else - notification.flags |= Notification.FLAG_AUTO_CANCEL; - - notification.flags |= Notification.FLAG_ONGOING_EVENT; - notification.priority = Notification.PRIORITY_MIN; - notification.tickerText = null; - + Notification.Builder builder = new Notification.Builder(SSLDroid.this); Intent intent = new Intent(this, SSLDroidGui.class); PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0); - notification.setLatestEventInfo(this, title, text, activity); + if (persistent == true) { + builder.setAutoCancel(false); + builder.setPriority(Notification.PRIORITY_MAX); + } + else + builder.setAutoCancel(true); + builder.setTicker("SSLDroid startup"); + builder.setContentTitle(title); + builder.setContentText(text); + builder.setSmallIcon(R.drawable.icon); + builder.setContentIntent(activity); + builder.setOngoing(true); + builder.setNumber(100); + + Notification notification = builder.build(); notificationManager.notify(id, notification); } } diff --git a/src/hu/blint/ssldroid/SSLDroidProvisioning.java b/src/hu/blint/ssldroid/SSLDroidProvisioning.java new file mode 100644 index 0000000..285ef9c --- /dev/null +++ b/src/hu/blint/ssldroid/SSLDroidProvisioning.java @@ -0,0 +1,6 @@ +package hu.blint.ssldroid; + +import android.app.Activity; + +public class SSLDroidProvisioning extends Activity { +} From fc069e209c9e00174bbe71a77a9646b1def946fa Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Fri, 7 Aug 2015 09:16:06 +0200 Subject: [PATCH 02/19] SNI: make Server Name Indication usage optional --- res/layout/tunnel_details.xml | 11 ++++++- res/values/strings.xml | 1 + src/hu/blint/ssldroid/SSLDroid.java | 7 ++++- .../blint/ssldroid/SSLDroidTunnelDetails.java | 16 ++++++++-- src/hu/blint/ssldroid/TcpProxy.java | 7 +++-- .../blint/ssldroid/TcpProxyServerThread.java | 29 +++++++------------ .../blint/ssldroid/db/SSLDroidDbAdapter.java | 16 +++++----- .../blint/ssldroid/db/SSLDroidDbHelper.java | 13 +++++---- 8 files changed, 61 insertions(+), 39 deletions(-) diff --git a/res/layout/tunnel_details.xml b/res/layout/tunnel_details.xml index f65472b..3c718f7 100644 --- a/res/layout/tunnel_details.xml +++ b/res/layout/tunnel_details.xml @@ -70,8 +70,17 @@ android:layout_weight="1" android:inputType="textEmailAddress" /> + + + + + - \ No newline at end of file + diff --git a/res/values/strings.xml b/res/values/strings.xml index efa961c..360af38 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9,6 +9,7 @@ Apply PKCS12 pass + Use SNI Tunnel name Add tunnel Stop service diff --git a/src/hu/blint/ssldroid/SSLDroid.java b/src/hu/blint/ssldroid/SSLDroid.java index 507813c..d4cc784 100644 --- a/src/hu/blint/ssldroid/SSLDroid.java +++ b/src/hu/blint/ssldroid/SSLDroid.java @@ -49,8 +49,13 @@ public void onCreate() { .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSPASS)); String caFile = cursor.getString(cursor .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_CACERTFILE)); + boolean useSNI = true; + int useSNIrepr = cursor.getInt(cursor.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_USE_SNI)); + if (useSNIrepr == 0) + useSNI = false; + try { - tp[i] = new TcpProxy(tunnelName, listenPort, targetHost, targetPort, keyFile, keyPass, caFile); + tp[i] = new TcpProxy(tunnelName, listenPort, targetHost, targetPort, keyFile, keyPass, caFile, useSNI); tp[i].serve(); Log.d(TAG, "Tunnel: "+tunnelName+" "+listenPort+" "+targetHost+" "+targetPort+" "+keyFile); } catch (Exception e) { diff --git a/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java b/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java index be538b7..b3ea214 100644 --- a/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java +++ b/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java @@ -34,6 +34,7 @@ import android.util.Log; import android.view.View; import android.widget.Button; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.Toast; import hu.blint.ssldroid.db.SSLDroidDbAdapter; @@ -160,6 +161,7 @@ public void onClick(View view) { private EditText pkcsfile; private EditText pkcspass; private EditText cacertfile; + private CheckBox usesni; private Long rowId; private Boolean doClone = false; private SSLDroidDbAdapter dbHelper; @@ -179,6 +181,7 @@ protected void onCreate(Bundle bundle) { pkcsfile = (EditText) findViewById(R.id.pkcsfile); pkcspass = (EditText) findViewById(R.id.pkcspass); cacertfile = (EditText) findViewById(R.id.cacertfile); + usesni = (CheckBox) findViewById(R.id.usesni); Button pickFile = (Button) findViewById(R.id.pickFile); Button pickCaFile = (Button) findViewById(R.id.pickCaFile); @@ -318,6 +321,12 @@ private void populateFields() { .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSPASS))); cacertfile.setText(Tunnel.getString(Tunnel .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_CACERTFILE))); + if (Tunnel.getInt(Tunnel.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_USE_SNI)) != 0){ + usesni.setChecked(true); + } + else{ + usesni.setChecked(false); + } } } @@ -397,6 +406,9 @@ private void saveState() { String sPkcsfile = pkcsfile.getText().toString(); String sPkcspass = pkcspass.getText().toString(); String sCacertfile = cacertfile.getText().toString(); + Integer sUsesni = 1; + if (!usesni.isChecked()) + sUsesni = 0; //make sure that we have all of our values correctly set if (sName.length() == 0) { @@ -414,13 +426,13 @@ private void saveState() { if (rowId == null || doClone) { long id = dbHelper.createTunnel(sName, sLocalport, sRemotehost, - sRemoteport, sPkcsfile, sPkcspass, sCacertfile); + sRemoteport, sPkcsfile, sPkcspass, sCacertfile, sUsesni); if (id > 0) { rowId = id; } } else { dbHelper.updateTunnel(rowId, sName, sLocalport, sRemotehost, sRemoteport, - sPkcsfile, sPkcspass, sCacertfile); + sPkcsfile, sPkcspass, sCacertfile, sUsesni); } Log.d("SSLDroid", "Saving settings..."); diff --git a/src/hu/blint/ssldroid/TcpProxy.java b/src/hu/blint/ssldroid/TcpProxy.java index 0c1cb56..87c5506 100644 --- a/src/hu/blint/ssldroid/TcpProxy.java +++ b/src/hu/blint/ssldroid/TcpProxy.java @@ -13,9 +13,10 @@ public class TcpProxy { String tunnelHost; int tunnelPort; String keyFile, keyPass, caCertFile; + boolean useSNI; TcpProxyServerThread server = null; - public TcpProxy(String tunnelName, int listenPort, String targetHost, int targetPort, String keyFile, String keyPass, String caCertFile) { + public TcpProxy(String tunnelName, int listenPort, String targetHost, int targetPort, String keyFile, String keyPass, String caCertFile, boolean useSNI) { this.tunnelName = tunnelName; this.listenPort = listenPort; this.tunnelHost = targetHost; @@ -23,11 +24,13 @@ public TcpProxy(String tunnelName, int listenPort, String targetHost, int target this.keyFile = keyFile; this.keyPass = keyPass; this.caCertFile = caCertFile; + this.useSNI = useSNI; } public void serve() throws IOException { server = new TcpProxyServerThread(this.tunnelName, this.listenPort, this.tunnelHost, - this.tunnelPort, this.keyFile, this.keyPass, this.caCertFile); + this.tunnelPort, this.keyFile, this.keyPass, + this.caCertFile, this.useSNI); server.start(); } diff --git a/src/hu/blint/ssldroid/TcpProxyServerThread.java b/src/hu/blint/ssldroid/TcpProxyServerThread.java index 7b3516e..11159ab 100644 --- a/src/hu/blint/ssldroid/TcpProxyServerThread.java +++ b/src/hu/blint/ssldroid/TcpProxyServerThread.java @@ -26,6 +26,8 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; +import android.annotation.TargetApi; +import android.os.Build; import android.util.Log; public class TcpProxyServerThread extends Thread { @@ -35,13 +37,16 @@ public class TcpProxyServerThread extends Thread { String tunnelHost; int tunnelPort; String keyFile, keyPass, caFile; + boolean useSNI; Relay inRelay, outRelay; ServerSocket ss = null; int sessionid = 0; private SSLSocketFactory sslSocketFactory; private X509Certificate caCert; - public TcpProxyServerThread(String tunnelName, int listenPort, String tunnelHost, int tunnelPort, String keyFile, String keyPass, String caFile) { + public TcpProxyServerThread(String tunnelName, int listenPort, String tunnelHost, + int tunnelPort, String keyFile, String keyPass, String caFile + boolean useSNI) { this.tunnelName = tunnelName; this.listenPort = listenPort; this.tunnelHost = tunnelHost; @@ -66,25 +71,9 @@ public TcpProxyServerThread(String tunnelName, int listenPort, String tunnelHost } catch (IOException ex) { } } } + this.useSNI = useSNI; } - // Create a trust manager that does not validate certificate chains - // TODO: handle this somehow properly (popup if cert is untrusted?) - // TODO: cacert + crl should be configurable - /*TrustManager[] trustAllCerts = new TrustManager[] { - new X509TrustManager() { - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return null; - } - public void checkClientTrusted( - java.security.cert.X509Certificate[] certs, String authType) { - } - public void checkServerTrusted( - java.security.cert.X509Certificate[] certs, String authType) { - } - } - };*/ - // FIXME: https://stackoverflow.com/questions/6629473/validate-x-509-certificate-agains-concrete-ca-java TrustManager[] trustCaCert = new TrustManager[] { new X509TrustManager() { @@ -208,7 +197,8 @@ public void run() { try { final SSLSocketFactory sf = getSocketFactory(this.keyFile, this.keyPass, this.sessionid); st = (SSLSocket) sf.createSocket(this.tunnelHost, this.tunnelPort); - setSNIHost(sf, (SSLSocket) st, this.tunnelHost); + if (this.useSNI) + setSNIHost(sf, (SSLSocket) st, this.tunnelHost); ((SSLSocket) st).startHandshake(); } catch (IOException e) { Log.d("SSLDroid", tunnelName+"/"+sessionid+": SSL failure: " + e.toString()); @@ -247,6 +237,7 @@ public void run() { } } + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) private void setSNIHost(final SSLSocketFactory factory, final SSLSocket socket, final String hostname) { if (factory instanceof android.net.SSLCertificateSocketFactory && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { ((android.net.SSLCertificateSocketFactory)factory).setHostname(socket, hostname); diff --git a/src/hu/blint/ssldroid/db/SSLDroidDbAdapter.java b/src/hu/blint/ssldroid/db/SSLDroidDbAdapter.java index f48576a..df6ced5 100644 --- a/src/hu/blint/ssldroid/db/SSLDroidDbAdapter.java +++ b/src/hu/blint/ssldroid/db/SSLDroidDbAdapter.java @@ -17,6 +17,7 @@ public class SSLDroidDbAdapter { public static final String KEY_PKCSFILE = "pkcsfile"; public static final String KEY_PKCSPASS = "pkcspass"; public static final String KEY_CACERTFILE = "cacertfile"; + public static final String KEY_USE_SNI = "usesni"; public static final String KEY_STATUS_NAME = "name"; public static final String KEY_STATUS_VALUE = "value"; private static final String DATABASE_TABLE = "tunnels"; @@ -45,9 +46,9 @@ public void close() { * rowId for that note, otherwise return a -1 to indicate failure. */ public long createTunnel(String name, int localport, String remotehost, int remoteport, - String pkcsfile, String pkcspass, String cacertfile) { + String pkcsfile, String pkcspass, String cacertfile, int usesni) { ContentValues initialValues = createContentValues(name, localport, remotehost, - remoteport, pkcsfile, pkcspass, cacertfile); + remoteport, pkcsfile, pkcspass, cacertfil, usesni); return database.insert(DATABASE_TABLE, null, initialValues); } @@ -56,9 +57,9 @@ public long createTunnel(String name, int localport, String remotehost, int remo * Update the tunnel */ public boolean updateTunnel(long rowId, String name, int localport, String remotehost, - int remoteport, String pkcsfile, String pkcspass, String cacertfile) { + int remoteport, String pkcsfile, String pkcspass, String cacertfile, int usesni) { ContentValues updateValues = createContentValues(name, localport, remotehost, - remoteport, pkcsfile, pkcspass, cacertfile); + remoteport, pkcsfile, pkcspass, cacertfile, usesni); return database.update(DATABASE_TABLE, updateValues, KEY_ROWID + "=" + rowId, null) > 0; @@ -79,7 +80,7 @@ public boolean deleteTunnel(long rowId) { public Cursor fetchAllTunnels() { return database.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_NAME, KEY_LOCALPORT, KEY_REMOTEHOST, KEY_REMOTEPORT, KEY_PKCSFILE, - KEY_PKCSPASS, KEY_CACERTFILE + KEY_PKCSPASS, KEY_CACERTFILE, KEY_USE_SNI }, null, null, null, null, null); } @@ -124,7 +125,7 @@ public boolean delStopStatus() { public Cursor fetchTunnel(long rowId) throws SQLException { Cursor mCursor = database.query(true, DATABASE_TABLE, new String[] { KEY_ROWID, KEY_NAME, KEY_LOCALPORT, KEY_REMOTEHOST, KEY_REMOTEPORT, - KEY_PKCSFILE, KEY_PKCSPASS, KEY_CACERTFILE + KEY_PKCSFILE, KEY_PKCSPASS, KEY_CACERTFILE, KEY_USE_SNI }, KEY_ROWID + "=" + rowId, null, null, null, null, null); if (mCursor != null) { @@ -134,7 +135,7 @@ public Cursor fetchTunnel(long rowId) throws SQLException { } private ContentValues createContentValues(String name, int localport, String remotehost, int remoteport, - String pkcsfile, String pkcspass, String cacertfile) { + String pkcsfile, String pkcspass, String cacertfile, int usesni) { ContentValues values = new ContentValues(); values.put(KEY_NAME, name); values.put(KEY_LOCALPORT, localport); @@ -143,7 +144,6 @@ private ContentValues createContentValues(String name, int localport, String rem values.put(KEY_REMOTEPORT, remoteport); values.put(KEY_PKCSFILE, pkcsfile); values.put(KEY_PKCSPASS, pkcspass); - values.put(KEY_CACERTFILE, cacertfile); return values; } } diff --git a/src/hu/blint/ssldroid/db/SSLDroidDbHelper.java b/src/hu/blint/ssldroid/db/SSLDroidDbHelper.java index 7a8083f..e7cb80f 100644 --- a/src/hu/blint/ssldroid/db/SSLDroidDbHelper.java +++ b/src/hu/blint/ssldroid/db/SSLDroidDbHelper.java @@ -12,7 +12,7 @@ public class SSLDroidDbHelper extends SQLiteOpenHelper { // Database creation sql statement private static final String DATABASE_CREATE = "CREATE TABLE IF NOT EXISTS tunnels (_id integer primary key autoincrement, " + "name text not null, localport integer not null, remotehost text not null, " - + "remoteport integer not null, pkcsfile text not null, pkcspass text, cacertfile text );"; + + "remoteport integer not null, pkcsfile text not null, pkcspass text, cacertfile text, usesni integer not null );"; private static final String STATUS_CREATE = "CREATE TABLE IF NOT EXISTS status (name text, value text);"; public SSLDroidDbHelper(Context context) { @@ -29,14 +29,15 @@ public void onCreate(SQLiteDatabase database) { // Method is called during an update of the database, e.g. if you increase // the database version @Override - public void onUpgrade(SQLiteDatabase database, int oldVersion, - int newVersion) { + public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) { Log.w(SSLDroidDbHelper.class.getName(), - "Upgrading database from version " + oldVersion + " to " - + newVersion + ", which will add a status table"); + "Upgrading database from version " + oldVersion + " to " + + newVersion + ", which will add a status table"); database.execSQL("CREATE TABLE IF NOT EXISTS status (name text, value text);"); - if (oldVersion < 3) + if (oldVersion < 3) { database.execSQL("ALTER TABLE tunnels ADD cacertfile text;"); + database.execSQL("ALTER TABLE tunnels ADD COLUMN usesni integer not null default 1;"); + } onCreate(database); } } From 2aadfe65c820b3e0698b0de990c3a1c9bdde5388 Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Sat, 25 Jul 2015 00:18:51 +0200 Subject: [PATCH 03/19] random: raise PRNG entropy level as described in https://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html Signed-off-by: blint@blint.hu --- src/hu/blint/ssldroid/PRNGFixes.java | 340 +++++++++++++++++++++++++++ src/hu/blint/ssldroid/SSLDroid.java | 3 + 2 files changed, 343 insertions(+) create mode 100644 src/hu/blint/ssldroid/PRNGFixes.java diff --git a/src/hu/blint/ssldroid/PRNGFixes.java b/src/hu/blint/ssldroid/PRNGFixes.java new file mode 100644 index 0000000..7cc36b9 --- /dev/null +++ b/src/hu/blint/ssldroid/PRNGFixes.java @@ -0,0 +1,340 @@ +package hu.blint.ssldroid; + +/* + * This software is provided 'as-is', without any express or implied + * warranty. In no event will Google be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, as long as the origin is not misrepresented. + */ + +import android.os.Build; +import android.os.Process; +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.SecureRandomSpi; +import java.security.Security; + +/** + * Fixes for the output of the default PRNG having low entropy. + * + * The fixes need to be applied via {@link #apply()} before any use of Java + * Cryptography Architecture primitives. A good place to invoke them is in the + * application's {@code onCreate}. + */ +public final class PRNGFixes { + + private static final int VERSION_CODE_JELLY_BEAN = 16; + private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18; + private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL = + getBuildFingerprintAndDeviceSerial(); + + /** Hidden constructor to prevent instantiation. */ + private PRNGFixes() {} + + /** + * Applies all fixes. + * + * @throws SecurityException if a fix is needed but could not be applied. + */ + public static void apply() { + applyOpenSSLFix(); + installLinuxPRNGSecureRandom(); + } + + /** + * Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the + * fix is not needed. + * + * @throws SecurityException if the fix is needed but could not be applied. + */ + private static void applyOpenSSLFix() throws SecurityException { + if ((Build.VERSION.SDK_INT < VERSION_CODE_JELLY_BEAN) + || (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) { + // No need to apply the fix + return; + } + + try { + // Mix in the device- and invocation-specific seed. + Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto") + .getMethod("RAND_seed", byte[].class) + .invoke(null, generateSeed()); + + // Mix output of Linux PRNG into OpenSSL's PRNG + int bytesRead = (Integer) Class.forName( + "org.apache.harmony.xnet.provider.jsse.NativeCrypto") + .getMethod("RAND_load_file", String.class, long.class) + .invoke(null, "/dev/urandom", 1024); + if (bytesRead != 1024) { + throw new IOException( + "Unexpected number of bytes read from Linux PRNG: " + + bytesRead); + } + } catch (Exception e) { + throw new SecurityException("Failed to seed OpenSSL PRNG", e); + } + } + + /** + * Installs a Linux PRNG-backed {@code SecureRandom} implementation as the + * default. Does nothing if the implementation is already the default or if + * there is not need to install the implementation. + * + * @throws SecurityException if the fix is needed but could not be applied. + */ + private static void installLinuxPRNGSecureRandom() + throws SecurityException { + if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) { + // No need to apply the fix + return; + } + + // Install a Linux PRNG-based SecureRandom implementation as the + // default, if not yet installed. + Provider[] secureRandomProviders = + Security.getProviders("SecureRandom.SHA1PRNG"); + if ((secureRandomProviders == null) + || (secureRandomProviders.length < 1) + || (!LinuxPRNGSecureRandomProvider.class.equals( + secureRandomProviders[0].getClass()))) { + Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1); + } + + // Assert that new SecureRandom() and + // SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed + // by the Linux PRNG-based SecureRandom implementation. + SecureRandom rng1 = new SecureRandom(); + if (!LinuxPRNGSecureRandomProvider.class.equals( + rng1.getProvider().getClass())) { + throw new SecurityException( + "new SecureRandom() backed by wrong Provider: " + + rng1.getProvider().getClass()); + } + + SecureRandom rng2; + try { + rng2 = SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + throw new SecurityException("SHA1PRNG not available", e); + } + if (!LinuxPRNGSecureRandomProvider.class.equals( + rng2.getProvider().getClass())) { + throw new SecurityException( + "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" + + " Provider: " + rng2.getProvider().getClass()); + } + } + + /** + * {@code Provider} of {@code SecureRandom} engines which pass through + * all requests to the Linux PRNG. + */ + private static class LinuxPRNGSecureRandomProvider extends Provider { + + static final long serialVersionUID = 1L; + + public LinuxPRNGSecureRandomProvider() { + super("LinuxPRNG", + 1.0, + "A Linux-specific random number provider that uses" + + " /dev/urandom"); + // Although /dev/urandom is not a SHA-1 PRNG, some apps + // explicitly request a SHA1PRNG SecureRandom and we thus need to + // prevent them from getting the default implementation whose output + // may have low entropy. + put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName()); + put("SecureRandom.SHA1PRNG ImplementedIn", "Software"); + } + } + + /** + * {@link SecureRandomSpi} which passes all requests to the Linux PRNG + * ({@code /dev/urandom}). + */ + public static class LinuxPRNGSecureRandom extends SecureRandomSpi { + + /* + * IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed + * are passed through to the Linux PRNG (/dev/urandom). Instances of + * this class seed themselves by mixing in the current time, PID, UID, + * build fingerprint, and hardware serial number (where available) into + * Linux PRNG. + * + * Concurrency: Read requests to the underlying Linux PRNG are + * serialized (on sLock) to ensure that multiple threads do not get + * duplicated PRNG output. + */ + + static final long serialVersionUID = 1L; + + private static final File URANDOM_FILE = new File("/dev/urandom"); + + private static final Object sLock = new Object(); + + /** + * Input stream for reading from Linux PRNG or {@code null} if not yet + * opened. + * + * @GuardedBy("sLock") + */ + private static DataInputStream sUrandomIn; + + /** + * Output stream for writing to Linux PRNG or {@code null} if not yet + * opened. + * + * @GuardedBy("sLock") + */ + private static OutputStream sUrandomOut; + + /** + * Whether this engine instance has been seeded. This is needed because + * each instance needs to seed itself if the client does not explicitly + * seed it. + */ + private boolean mSeeded; + + @Override + protected void engineSetSeed(byte[] bytes) { + try { + OutputStream out; + synchronized (sLock) { + out = getUrandomOutputStream(); + } + out.write(bytes); + out.flush(); + } catch (IOException e) { + // On a small fraction of devices /dev/urandom is not writable. + // Log and ignore. + Log.w(PRNGFixes.class.getSimpleName(), + "Failed to mix seed into " + URANDOM_FILE); + } finally { + mSeeded = true; + } + } + + @Override + protected void engineNextBytes(byte[] bytes) { + if (!mSeeded) { + // Mix in the device- and invocation-specific seed. + engineSetSeed(generateSeed()); + } + + try { + DataInputStream in; + synchronized (sLock) { + in = getUrandomInputStream(); + } + synchronized (in) { + in.readFully(bytes); + } + } catch (IOException e) { + throw new SecurityException( + "Failed to read from " + URANDOM_FILE, e); + } + } + + @Override + protected byte[] engineGenerateSeed(int size) { + byte[] seed = new byte[size]; + engineNextBytes(seed); + return seed; + } + + private DataInputStream getUrandomInputStream() { + synchronized (sLock) { + if (sUrandomIn == null) { + // NOTE: Consider inserting a BufferedInputStream between + // DataInputStream and FileInputStream if you need higher + // PRNG output performance and can live with future PRNG + // output being pulled into this process prematurely. + try { + sUrandomIn = new DataInputStream( + new FileInputStream(URANDOM_FILE)); + } catch (IOException e) { + throw new SecurityException("Failed to open " + + URANDOM_FILE + " for reading", e); + } + } + return sUrandomIn; + } + } + + private OutputStream getUrandomOutputStream() throws IOException { + synchronized (sLock) { + if (sUrandomOut == null) { + sUrandomOut = new FileOutputStream(URANDOM_FILE); + } + return sUrandomOut; + } + } + } + + /** + * Generates a device- and invocation-specific seed to be mixed into the + * Linux PRNG. + */ + private static byte[] generateSeed() { + try { + ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream(); + DataOutputStream seedBufferOut = + new DataOutputStream(seedBuffer); + seedBufferOut.writeLong(System.currentTimeMillis()); + seedBufferOut.writeLong(System.nanoTime()); + seedBufferOut.writeInt(Process.myPid()); + seedBufferOut.writeInt(Process.myUid()); + seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL); + seedBufferOut.close(); + return seedBuffer.toByteArray(); + } catch (IOException e) { + throw new SecurityException("Failed to generate seed", e); + } + } + + /** + * Gets the hardware serial number of this device. + * + * @return serial number or {@code null} if not available. + */ + private static String getDeviceSerialNumber() { + // We're using the Reflection API because Build.SERIAL is only available + // since API Level 9 (Gingerbread, Android 2.3). + try { + return (String) Build.class.getField("SERIAL").get(null); + } catch (Exception ignored) { + return null; + } + } + + private static byte[] getBuildFingerprintAndDeviceSerial() { + StringBuilder result = new StringBuilder(); + String fingerprint = Build.FINGERPRINT; + if (fingerprint != null) { + result.append(fingerprint); + } + String serial = getDeviceSerialNumber(); + if (serial != null) { + result.append(serial); + } + try { + return result.toString().getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 encoding not supported"); + } + } +} diff --git a/src/hu/blint/ssldroid/SSLDroid.java b/src/hu/blint/ssldroid/SSLDroid.java index d4cc784..feabdca 100644 --- a/src/hu/blint/ssldroid/SSLDroid.java +++ b/src/hu/blint/ssldroid/SSLDroid.java @@ -20,6 +20,9 @@ public class SSLDroid extends Service { @Override public void onCreate() { + //initialize secure random Generation + PRNGFixes.apply(); + dbHelper = new SSLDroidDbAdapter(this); dbHelper.open(); Cursor cursor = dbHelper.fetchAllTunnels(); From d2bf4e1e4dd6cd8b2a4ad6ee25f6ea6812f434dd Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Fri, 5 Jul 2019 08:43:20 +0200 Subject: [PATCH 04/19] chore(warnings): fix the meaningful static analyzer warnings Signed-off-by: Balint Kovacs --- .idea/caches/build_file_checksums.ser | Bin 0 -> 288 bytes .idea/inspectionProfiles/Project_Default.xml | 36 + .idea/misc.xml | 2 +- .idea/modules/SSLDroid.iml | 1 + .idea/workspace.xml | 701 ++++++++++++++++++ local.properties | 11 + res/layout/tunnel_details.xml | 2 +- .../blint/ssldroid/BootStartupReceiver.java | 2 +- .../blint/ssldroid/NetworkChangeReceiver.java | 2 +- src/hu/blint/ssldroid/PRNGFixes.java | 12 +- src/hu/blint/ssldroid/Relay.java | 14 +- src/hu/blint/ssldroid/SSLDroid.java | 63 +- src/hu/blint/ssldroid/SSLDroidGui.java | 13 +- src/hu/blint/ssldroid/SSLDroidReadLogs.java | 10 +- .../blint/ssldroid/SSLDroidTunnelDetails.java | 55 +- src/hu/blint/ssldroid/TcpProxy.java | 21 +- .../blint/ssldroid/TcpProxyServerThread.java | 40 +- .../blint/ssldroid/db/SSLDroidDbAdapter.java | 27 +- .../blint/ssldroid/db/SSLDroidDbHelper.java | 4 +- 19 files changed, 886 insertions(+), 130 deletions(-) create mode 100644 .idea/caches/build_file_checksums.ser create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/workspace.xml create mode 100644 local.properties diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser new file mode 100644 index 0000000000000000000000000000000000000000..57cfdc9afafba635dda117775066688b99d8c561 GIT binary patch literal 288 zcmZ4UmVvdnh`~NNKUXg?FQq6yGexf?KR>5fFEb@IQ7^qHF(oHeub?PDD>b=9F91S2 zm1gFoxMk*~I%lLNXBU^|7Q2L-Ts|(GuF1r}uGBYr_F>vMNC#JY1CYR(Fc`|U8WE7 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index a0fceb0..ca4d8dc 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -2,7 +2,7 @@ - + - + \ No newline at end of file diff --git a/.idea/modules/SSLDroid.iml b/.idea/modules/SSLDroid.iml index d0b41c8..ec1c101 100644 --- a/.idea/modules/SSLDroid.iml +++ b/.idea/modules/SSLDroid.iml @@ -87,6 +87,7 @@ + @@ -105,9 +106,11 @@ + + @@ -117,6 +120,8 @@ + + diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 9099dcc..52d9886 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,24 +5,22 @@ + + + + - + - + + - - - - - - - @@ -75,54 +73,98 @@ - + - - + + + + + - + - - + + + + + + + + + + + + + + + + - + + - + - - + + - + + - - + + - - + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + @@ -149,11 +191,19 @@ databasepath deactivate usesni + startService + id, + startser C:\Users\blint_dev\StudioProjects\SSLDroid + + + + + @@ -164,27 +214,28 @@ - - - - + + + + + - + - + @@ -192,7 +243,8 @@ - + + @@ -219,17 +271,16 @@ - - + - + - + - + @@ -430,8 +481,8 @@ - - + + @@ -439,13 +490,12 @@ - - + + - + - @@ -455,6 +505,7 @@ + @@ -559,14 +610,6 @@ - - - - - - - - @@ -601,20 +644,6 @@ - - - - - - - - - - - - - - @@ -634,16 +663,23 @@ - + - - - - - + + + + + + + + + + + + @@ -651,49 +687,80 @@ - + - - + + - + - - + + + + + + + + + - - - + + + + + - + - - + + + + + - + + - - + + - - + + + + + + + + + + + + + + + + + + + + diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 2c6ff0f..c137f86 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -12,6 +12,7 @@ + @@ -28,10 +29,13 @@ - - + + - + diff --git a/src/hu/blint/ssldroid/BootStartupReceiver.java b/src/hu/blint/ssldroid/BootStartupReceiver.java index 1de0b7f..fc8f710 100644 --- a/src/hu/blint/ssldroid/BootStartupReceiver.java +++ b/src/hu/blint/ssldroid/BootStartupReceiver.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.database.Cursor; +import android.os.Build; import android.util.Log; public class BootStartupReceiver extends BroadcastReceiver { @@ -32,13 +33,14 @@ private boolean isStopped(Context context){ @Override public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { - Intent i = new Intent(); - i.setAction("hu.blint.ssldroid.SSLDroid"); - if (!isStopped(context)) + Intent i = new Intent(context, SSLDroid.class); + if (!isStopped(context)) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(i); + } else { context.startService(i); - else - Log.w("SSLDroid", "Not starting service as directed by explicit stop"); - } + } + else + Log.w("SSLDroid", "Not starting service as directed by explicit stop"); } } \ No newline at end of file diff --git a/src/hu/blint/ssldroid/NetworkChangeReceiver.java b/src/hu/blint/ssldroid/NetworkChangeReceiver.java index 1efde12..e2108af 100644 --- a/src/hu/blint/ssldroid/NetworkChangeReceiver.java +++ b/src/hu/blint/ssldroid/NetworkChangeReceiver.java @@ -7,6 +7,7 @@ import android.database.Cursor; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.Build; import android.util.Log; public class NetworkChangeReceiver extends BroadcastReceiver { @@ -37,20 +38,21 @@ public void onReceive(Context context, Intent intent) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE ); NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo(); if ( activeNetInfo == null ) { - Intent i = new Intent(); - i.setAction("hu.blint.ssldroid.SSLDroid"); + Intent i = new Intent(context, SSLDroid.class); context.stopService(i); return; } Log.d("SSLDroid", activeNetInfo.toString()); if (activeNetInfo.isAvailable()) { - Intent i = new Intent(); - i.setAction("hu.blint.ssldroid.SSLDroid"); - context.stopService(i); + Intent i = new Intent(context, SSLDroid.class); if (!isStopped(context)) - context.startService(i); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(i); + } else { + context.startService(i); + } else - Log.w("SSLDroid", "Not starting service as directed by explicit stop"); + Log.w("SSLDroid", "Not starting service as directed by explicit stop"); } } } diff --git a/src/hu/blint/ssldroid/SSLDroid.java b/src/hu/blint/ssldroid/SSLDroid.java index 6ee9c7b..6a23ba1 100644 --- a/src/hu/blint/ssldroid/SSLDroid.java +++ b/src/hu/blint/ssldroid/SSLDroid.java @@ -19,10 +19,11 @@ public class SSLDroid extends Service { private TcpProxy[] tp; private SSLDroidDbAdapter dbHelper = new SSLDroidDbAdapter(this); - @Override - public void onCreate() { - //initialize secure random Generation - PRNGFixes.apply(); + private int NOTIFICATION_ID = 137; + + public int startServing() { + //initialize secure random Generation + PRNGFixes.apply(); dbHelper.open(); Cursor cursor = dbHelper.fetchAllTunnels(); @@ -31,7 +32,7 @@ public void onCreate() { //skip start if the db is empty yet if (tunnelcount == 0) - return; + return 0; tp = new TcpProxy[tunnelcount]; @@ -39,15 +40,15 @@ public void onCreate() { for (i=0; i= Build.VERSION_CODES.O) { + startForeground(NOTIFICATION_ID, builder.build()); + } + else + displayNotification(builder); } @Override @@ -109,24 +126,21 @@ public void onDestroy() { } catch (Exception e) { Log.d("SSLDroid", "Error stopping service: " + e.toString()); } - removeNotification(0); + removeNotification(); Log.d(TAG, "SSLDroid Service Stopped"); } - private void removeNotification(int id) { + private void removeNotification() { NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); assert notificationManager != null; - notificationManager.cancel(id); + notificationManager.cancel(NOTIFICATION_ID); } - private void createNotification(int id, boolean persistent, String title, String text) { - + private Notification.Builder createNotification(boolean persistent, String title, String text) { Context context = getApplicationContext(); Intent mainIntent = new Intent(context, SSLDroidGui.class); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, mainIntent, 0); - NotificationManager notificationManager = - (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); Notification.Builder builder = new Notification.Builder(context); builder.setSmallIcon(R.drawable.icon) .setContentTitle(title) @@ -137,14 +151,14 @@ private void createNotification(int id, boolean persistent, String title, String .setPriority(Notification.PRIORITY_HIGH); if (persistent) builder.setOngoing(true); + NotificationManager notificationManager = + (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { String channelId = "REMINDERS"; - NotificationChannel channel = new NotificationChannel(channelId, - "Reminder", - NotificationManager.IMPORTANCE_DEFAULT); + NotificationChannel channel = new NotificationChannel(channelId,"Reminder", NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channel); builder.setChannelId(channelId); } - notificationManager.notify(id, builder.build()); + return builder; } } diff --git a/src/hu/blint/ssldroid/SSLDroidGui.java b/src/hu/blint/ssldroid/SSLDroidGui.java index 8768988..90e98f8 100644 --- a/src/hu/blint/ssldroid/SSLDroidGui.java +++ b/src/hu/blint/ssldroid/SSLDroidGui.java @@ -3,6 +3,7 @@ import android.app.ListActivity; import android.content.Intent; import android.database.Cursor; +import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.ContextMenu; @@ -64,7 +65,12 @@ public boolean onMenuItemSelected(int featureId, MenuItem item) { case R.id.startservice: Log.d("SSLDroid", "Starting service"); dbHelper.delStopStatus(); - startService(new Intent(this, SSLDroid.class)); + Intent i = new Intent(this, SSLDroid.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + this.startForegroundService(i); + } else { + this.startService(i); + } return true; case R.id.readlogs: readLogs(); @@ -91,7 +97,12 @@ public boolean onOptionsItemSelected(MenuItem item) { case R.id.startservice: Log.d("SSLDroid", "Starting service"); dbHelper.delStopStatus(); - startService(new Intent(this, SSLDroid.class)); + Intent i = new Intent(this, SSLDroid.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + this.startForegroundService(i); + } else { + this.startService(i); + } return true; case R.id.readlogs: readLogs(); diff --git a/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java b/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java index 9ff29d8..183a919 100644 --- a/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java +++ b/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java @@ -29,6 +29,7 @@ import android.database.Cursor; import android.net.ConnectivityManager; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.util.Log; @@ -425,6 +426,7 @@ private void saveState() { return; } + Log.d("SSLDroid", "Saving settings..."); if (rowId == null || doClone) { long id = dbHelper.createTunnel(sName, sLocalport, sRemotehost, sRemoteport, sPkcsfile, sPkcspass, sCacertfile, sUsesni); @@ -435,13 +437,16 @@ private void saveState() { dbHelper.updateTunnel(rowId, sName, sLocalport, sRemotehost, sRemoteport, sPkcsfile, sPkcspass, sCacertfile, sUsesni); } - Log.d("SSLDroid", "Saving settings..."); //restart the service - stopService(new Intent(this, SSLDroid.class)); - startService(new Intent(this, SSLDroid.class)); Log.d("SSLDroid", "Restarting service after settings save..."); - + stopService(new Intent(this, SSLDroid.class)); + Intent i = new Intent(this, SSLDroid.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + this.startForegroundService(i); + } else { + this.startService(i); + } } } From cbede1e91e7a023217b1648586f417ccc1ceb628 Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Tue, 9 Jul 2019 17:18:32 +0200 Subject: [PATCH 07/19] feat(platform): update boot and network change detection to support new platforms and API --- .idea/caches/build_file_checksums.ser | Bin 288 -> 288 bytes .idea/misc.xml | 2 +- .idea/workspace.xml | 239 +++++++++--------- AndroidManifest.xml | 9 +- build.gradle | 2 +- .../blint/ssldroid/BootStartupReceiver.java | 62 ++--- .../blint/ssldroid/NetworkChangeReceiver.java | 59 ++--- .../blint/ssldroid/NetworkChangeService.java | 63 +++++ src/hu/blint/ssldroid/SSLDroid.java | 65 ++++- .../blint/ssldroid/SSLDroidTunnelDetails.java | 47 ++-- .../blint/ssldroid/TcpProxyServerThread.java | 2 +- 11 files changed, 320 insertions(+), 230 deletions(-) create mode 100644 src/hu/blint/ssldroid/NetworkChangeService.java diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 57cfdc9afafba635dda117775066688b99d8c561..62df05c1ca09b1236f81da614b66b5ebdaa846ae 100644 GIT binary patch delta 32 qcmV+*0N?+h0-yqrm;}>mME8-La}nrB5&goUoI4YD9tnctP@j12fewxU delta 32 qcmV+*0N?+h0-yqrm;}C!^&XL&a}mKa2*BN>%a^AGE*y84_cVC!n-0bR diff --git a/.idea/misc.xml b/.idea/misc.xml index c37309e..ca4d8dc 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -35,7 +35,7 @@ - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 52d9886..2b60fb5 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -7,20 +7,21 @@ - + + - + - + @@ -73,10 +74,10 @@ - + - - + + @@ -84,75 +85,35 @@ - - + + - - + + + + + - - - - - - - + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -160,15 +121,6 @@ - - - - - - - - - @@ -194,6 +146,7 @@ startService id, startser + ssldroid C:\Users\blint_dev\StudioProjects\SSLDroid @@ -215,20 +168,22 @@ - - - - - - + + + + + + + + @@ -243,8 +198,6 @@ - - @@ -272,12 +225,14 @@ + + - + @@ -469,9 +424,8 @@ - - + @@ -489,13 +443,13 @@ - - + + - + @@ -593,9 +547,6 @@ - - - @@ -663,104 +614,146 @@ - + + + + + + + + + + - - + + - + - - + + + + + - - - - + - - + + + + + - + + - - + + - + - - + + - + + + + + - - + + - + + - - + + - + + + + + + + + + + + - - + + - - + - - + + - - + + - - + - - + + + + + - - + + + + + + + + + + + + + + + diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c137f86..84e43a8 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -29,6 +29,10 @@ + - - - - - diff --git a/build.gradle b/build.gradle index 65800ff..bc47555 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ android { release.setRoot('build-types/release') } defaultConfig { - minSdkVersion 16 + minSdkVersion 21 targetSdkVersion 29 } } \ No newline at end of file diff --git a/src/hu/blint/ssldroid/BootStartupReceiver.java b/src/hu/blint/ssldroid/BootStartupReceiver.java index fc8f710..7b7346d 100644 --- a/src/hu/blint/ssldroid/BootStartupReceiver.java +++ b/src/hu/blint/ssldroid/BootStartupReceiver.java @@ -1,46 +1,50 @@ package hu.blint.ssldroid; -import hu.blint.ssldroid.db.SSLDroidDbAdapter; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.database.Cursor; +import android.content.IntentFilter; import android.os.Build; import android.util.Log; public class BootStartupReceiver extends BroadcastReceiver { - - private boolean isStopped(Context context){ - boolean stopped = false; - SSLDroidDbAdapter dbHelper; - dbHelper = new SSLDroidDbAdapter(context); - dbHelper.open(); - Cursor cursor = dbHelper.getStopStatus(); - int tunnelcount = cursor.getCount(); - Log.d("SSLDroid", "Tunnelcount: "+tunnelcount); - - //don't start if the stop status field is available - if (tunnelcount != 0){ - stopped = true; + public void createNetworkChangeListener(Context context){ + if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + context.registerReceiver(new NetworkChangeReceiver(null), new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")); + } + else { + Intent startServiceIntent = new Intent(context, NetworkChangeService.class); + context.startService(startServiceIntent); + Log.d("SSLDroid", "Scheduling network change monitor job"); + JobInfo myJob = new JobInfo.Builder(0, new ComponentName(context, NetworkChangeService.class)) + .setRequiresCharging(true) + .setMinimumLatency(1000) + .setOverrideDeadline(2000) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setPersisted(true) + .build(); + + JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); + jobScheduler.schedule(myJob); } - - cursor.close(); - dbHelper.close(); - - return stopped; } - + @Override public void onReceive(Context context, Intent intent) { + if (intent.getAction() != Intent.ACTION_BOOT_COMPLETED) + return; + + createNetworkChangeListener(context); + Intent i = new Intent(context, SSLDroid.class); - if (!isStopped(context)) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.startForegroundService(i); - } else { - context.startService(i); - } - else - Log.w("SSLDroid", "Not starting service as directed by explicit stop"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(i); + } else { + context.startService(i); + } } } \ No newline at end of file diff --git a/src/hu/blint/ssldroid/NetworkChangeReceiver.java b/src/hu/blint/ssldroid/NetworkChangeReceiver.java index e2108af..16d6aa7 100644 --- a/src/hu/blint/ssldroid/NetworkChangeReceiver.java +++ b/src/hu/blint/ssldroid/NetworkChangeReceiver.java @@ -1,59 +1,32 @@ package hu.blint.ssldroid; -import hu.blint.ssldroid.db.SSLDroidDbAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.database.Cursor; import android.net.ConnectivityManager; import android.net.NetworkInfo; -import android.os.Build; -import android.util.Log; public class NetworkChangeReceiver extends BroadcastReceiver { - private boolean isStopped(Context context){ - boolean stopped = false; - SSLDroidDbAdapter dbHelper; - dbHelper = new SSLDroidDbAdapter(context); - dbHelper.open(); - Cursor cursor = dbHelper.getStopStatus(); + private ConnectivityReceiverListener mConnectivityReceiverListener; - int tunnelcount = cursor.getCount(); - Log.d("SSLDroid", "Tunnelcount: "+tunnelcount); - - //don't start if the stop status field is available - if (tunnelcount != 0){ - stopped = true; - } - - cursor.close(); - dbHelper.close(); - - return stopped; + NetworkChangeReceiver(ConnectivityReceiverListener listener) { + mConnectivityReceiverListener = listener; } - + @Override public void onReceive(Context context, Intent intent) { - ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE ); - NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo(); - if ( activeNetInfo == null ) { - Intent i = new Intent(context, SSLDroid.class); - context.stopService(i); - return; - } - Log.d("SSLDroid", activeNetInfo.toString()); - if (activeNetInfo.isAvailable()) { - Intent i = new Intent(context, SSLDroid.class); - if (!isStopped(context)) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.startForegroundService(i); - } else { - context.startService(i); - } - else - Log.w("SSLDroid", "Not starting service as directed by explicit stop"); - } + mConnectivityReceiverListener.onNetworkConnectionChanged(isConnected(context)); + } + + public static boolean isConnected(Context context) { + ConnectivityManager cm = (ConnectivityManager) + context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); } -} + public interface ConnectivityReceiverListener { + void onNetworkConnectionChanged(boolean isConnected); + } +} \ No newline at end of file diff --git a/src/hu/blint/ssldroid/NetworkChangeService.java b/src/hu/blint/ssldroid/NetworkChangeService.java new file mode 100644 index 0000000..31715cc --- /dev/null +++ b/src/hu/blint/ssldroid/NetworkChangeService.java @@ -0,0 +1,63 @@ +package hu.blint.ssldroid; + +import android.app.job.JobParameters; +import android.app.job.JobService; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Build; +import android.util.Log; + +public class NetworkChangeService extends JobService implements + NetworkChangeReceiver.ConnectivityReceiverListener { + + private static final String TAG = "SSLDroid"; + + private NetworkChangeReceiver mConnectivityReceiver; + + @Override + public void onCreate() { + super.onCreate(); + Log.i(TAG, "Service created"); + mConnectivityReceiver = new NetworkChangeReceiver(this); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.i(TAG, "onStartCommand"); + return START_NOT_STICKY; + } + + + @Override + public boolean onStartJob(JobParameters params) { + Log.i(TAG, "onStartJob" + mConnectivityReceiver); + registerReceiver(mConnectivityReceiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")); + return true; + } + + @Override + public boolean onStopJob(JobParameters params) { + Log.i(TAG, "onStopJob"); + unregisterReceiver(mConnectivityReceiver); + return true; + } + + @Override + public void onNetworkConnectionChanged(boolean isConnected) { + Context context = getBaseContext(); + if ( !isConnected ) { + Intent i = new Intent(context, SSLDroid.class); + context.stopService(i); + } + else { + Intent i = new Intent(context, SSLDroid.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(i); + } else { + context.startService(i); + } + } + } +} + diff --git a/src/hu/blint/ssldroid/SSLDroid.java b/src/hu/blint/ssldroid/SSLDroid.java index 6a23ba1..0e3bfa3 100644 --- a/src/hu/blint/ssldroid/SSLDroid.java +++ b/src/hu/blint/ssldroid/SSLDroid.java @@ -1,9 +1,17 @@ package hu.blint.ssldroid; -import hu.blint.ssldroid.TcpProxy; -import android.app.*; +import android.app.AlertDialog; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -11,6 +19,7 @@ import android.os.Build; import android.os.IBinder; import android.util.Log; + import hu.blint.ssldroid.db.SSLDroidDbAdapter; public class SSLDroid extends Service { @@ -89,14 +98,64 @@ public int startServing() { return tunnelcount; } + private boolean isStopped(){ + Context context = getBaseContext(); + boolean stopped = false; + SSLDroidDbAdapter dbHelper; + dbHelper = new SSLDroidDbAdapter(context); + dbHelper.open(); + Cursor cursor = dbHelper.getStopStatus(); + + int tunnelcount = cursor.getCount(); + Log.d("SSLDroid", "Stoppedcount: "+tunnelcount); + + //don't start if the stop status field is available + if (tunnelcount != 0){ + stopped = true; + } + + cursor.close(); + dbHelper.close(); + + return stopped; + } + public void displayNotification(Notification.Builder builder) { NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(NOTIFICATION_ID, builder.build()); } + public void createNetworkChangeListener(){ + Context context = getBaseContext(); + if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + context.registerReceiver(new NetworkChangeReceiver(null), new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")); + } + else { + Intent startServiceIntent = new Intent(context, NetworkChangeService.class); + context.startService(startServiceIntent); + Log.d("SSLDroid", "Scheduling network change monitor job"); + JobInfo myJob = new JobInfo.Builder(0, new ComponentName(context, NetworkChangeService.class)) + .setRequiresCharging(true) + .setMinimumLatency(1000) + .setOverrideDeadline(2000) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setPersisted(true) + .build(); + + JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); + jobScheduler.schedule(myJob); + } + } + @Override public void onCreate() { + if (isStopped()) { + Log.w("SSLDroid", "Not starting service as directed by explicit stop"); + return; + } int tunnelcount = this.startServing(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + createNetworkChangeListener(); Notification.Builder builder = createNotification(true, "SSLDroid is running", "Started and serving "+tunnelcount+" tunnel(s)"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForeground(NOTIFICATION_ID, builder.build()); @@ -112,7 +171,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { @Override public IBinder onBind(Intent intent) { - return null; + return null; } @Override diff --git a/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java b/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java index 183a919..08c6066 100644 --- a/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java +++ b/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java @@ -47,28 +47,27 @@ public class SSLDroidTunnelDetails extends Activity { private final class SSLDroidTunnelHostnameChecker extends AsyncTask { + @Override + protected Boolean doInBackground(String... params) { + ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); + String hostname = params[0]; - @Override - protected Boolean doInBackground(String... params) { - ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); - String hostname = params[0]; - - if ( conMgr.getActiveNetworkInfo() != null || conMgr.getActiveNetworkInfo().isAvailable()) { - try { - InetAddress hostAddress = InetAddress.getByName(hostname); - if (hostAddress.getHostAddress() != "") - return true; - } catch (UnknownHostException e) { - return false; - } - } - return true; - } - protected void onPostExecute(Boolean result) { - if (!result) { - Toast.makeText(getBaseContext(), "Remote host not found, please recheck...", Toast.LENGTH_LONG).show(); - } - } + if ( conMgr.getActiveNetworkInfo() != null || conMgr.getActiveNetworkInfo().isAvailable()) { + try { + InetAddress hostAddress = InetAddress.getByName(hostname); + if (hostAddress.getHostAddress() != "") + return true; + } catch (UnknownHostException e) { + return false; + } + } + return true; + } + protected void onPostExecute(Boolean result) { + if (!result) { + Toast.makeText(getBaseContext(), "Remote host not found, please recheck...", Toast.LENGTH_LONG).show(); + } + } } private final class SSLDroidTunnelValidator implements View.OnClickListener { @@ -115,9 +114,9 @@ public void onClick(View view) { return; } else { - //if we have interwebs access, the remote host should exist - String hostname = remotehost.getText().toString(); - new SSLDroidTunnelHostnameChecker().execute(hostname); + //if we have interwebs access, the remote host should exist + String hostname = remotehost.getText().toString(); + new SSLDroidTunnelHostnameChecker().execute(hostname); } //remote port validation diff --git a/src/hu/blint/ssldroid/TcpProxyServerThread.java b/src/hu/blint/ssldroid/TcpProxyServerThread.java index caa582e..f52c0d1 100644 --- a/src/hu/blint/ssldroid/TcpProxyServerThread.java +++ b/src/hu/blint/ssldroid/TcpProxyServerThread.java @@ -239,7 +239,7 @@ public void run() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) private void setSNIHost(final SSLSocketFactory factory, final SSLSocket socket, final String hostname) { - if (factory instanceof android.net.SSLCertificateSocketFactory && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { + if (factory instanceof android.net.SSLCertificateSocketFactory) { ((android.net.SSLCertificateSocketFactory)factory).setHostname(socket, hostname); } else { try { From 817680eee9ecbf78ab230e56562ce952aaff1ee6 Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Tue, 9 Jul 2019 19:39:11 +0200 Subject: [PATCH 08/19] fix(rebase): fix conflict resolution errors --- .idea/workspace.xml | 154 +++++++++--------- .../blint/ssldroid/SSLDroidTunnelDetails.java | 1 - .../blint/ssldroid/db/SSLDroidDbAdapter.java | 4 +- .../blint/ssldroid/db/SSLDroidDbHelper.java | 6 +- 4 files changed, 84 insertions(+), 81 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 2b60fb5..4784e94 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -11,17 +11,10 @@ - - - - - - - - - + + @@ -76,16 +69,13 @@ - - - - - + + - + @@ -98,10 +88,28 @@ - + + + + + + + + + + - - + + + + + + + + + + + @@ -109,14 +117,20 @@ + + + + + + + + + - - - - - + + @@ -147,6 +161,7 @@ id, startser ssldroid + Upgrading C:\Users\blint_dev\StudioProjects\SSLDroid @@ -167,10 +182,8 @@ @@ -198,6 +213,9 @@ + + + @@ -224,15 +242,12 @@ + - - + + @@ -439,6 +404,7 @@ + @@ -450,7 +416,7 @@ - + @@ -463,13 +429,13 @@ - + - + @@ -669,13 +635,6 @@ - - - - - - - @@ -706,28 +665,14 @@ - + - - - - - - - - - - - - - - - + @@ -737,27 +682,48 @@ - + - - + + + + + + + + + - - + + - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 360af38..c1fea7a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -17,7 +17,8 @@ Start service No tunnels configured yet Delete tunnel - Pick a PKCS12 file from SD card + Pick a PKCS12 file from SD card + Pick a CA cert file from SD card No SD card present, please insert one to continue Read logs Reading log messages… diff --git a/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java b/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java index 8a3dc6b..e5a06c2 100644 --- a/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java +++ b/src/hu/blint/ssldroid/SSLDroidTunnelDetails.java @@ -189,12 +189,12 @@ protected void onCreate(Bundle bundle) { pickFile.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { - pickFileSimple(pkcsfile, pkcspass); + pickFileSimple(getResources().getString(R.string.key_file_pick), pkcsfile, pkcspass); } }); pickCaFile.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { - pickFileSimple(cacertfile, null); + pickFileSimple(getResources().getString(R.string.ca_file_pick), cacertfile, null); } }); @@ -224,7 +224,7 @@ private List getFileNames(File url) return names; } - private void showFiles(final List names, final File baseurl, final EditText editBox, final View nextView) { + private void showFiles(final String title, final List names, final File baseurl, final EditText editBox, final View nextView) { final String[] namesList = new String[names.size()]; // = names.toArray(new String[] {}); ListIterator filelist = names.listIterator(); int i = 0; @@ -240,7 +240,7 @@ private void showFiles(final List names, final File baseurl, final EditTex // prompt user to select any file from the sdcard root new AlertDialog.Builder(SSLDroidTunnelDetails.this) - .setTitle(R.string.file_pick) + .setTitle(title) .setItems(namesList, new OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { File name = names.get(arg1); @@ -248,7 +248,7 @@ public void onClick(DialogInterface arg0, int arg1) { List names_ = getFileNames(name); Collections.sort(names_); if (names_.size() > 0) { - showFiles(names_, baseurl, editBox, nextView); + showFiles(title, names_, baseurl, editBox, nextView); } else Toast.makeText(getBaseContext(), "Empty directory", Toast.LENGTH_LONG).show(); @@ -273,7 +273,7 @@ public void onClick(DialogInterface arg0, int arg1) { List names_ = getFileNames(grandparentfile); Collections.sort(names_); if (names_.size() > 0) { - showFiles(names_, baseurl, editBox, nextView); + showFiles(title, names_, baseurl, editBox, nextView); } } } @@ -283,7 +283,7 @@ public void onClick(DialogInterface arg0, int arg1) { } //pick a file from /sdcard, courtesy of ConnectBot - private void pickFileSimple(final EditText editBox, final View nextView) { + private void pickFileSimple(final String title, final EditText editBox, final View nextView) { // build list of all files in sdcard root final File sdcard = Environment.getExternalStorageDirectory(); Log.d("SSLDroid", "SD Card location: "+sdcard.toString()); @@ -301,7 +301,7 @@ private void pickFileSimple(final EditText editBox, final View nextView) { List names; names = getFileNames(sdcard); Collections.sort(names); - showFiles(names, sdcard, editBox, nextView); + showFiles(title, names, sdcard, editBox, nextView); } private void populateFields() { From 77e7528877b64efa337f44c0cab6568fd3f118bf Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Mon, 7 Apr 2025 13:28:16 +0200 Subject: [PATCH 10/19] feat(platform): update to AndroidStudio Meerkat's toolchain --- .idea/AndroidProjectSystem.xml | 6 + .idea/caches/deviceStreaming.xml | 607 +++++++++++++++++++++++ .idea/compiler.xml | 6 + .idea/deploymentTargetSelector.xml | 10 + .idea/gradle.xml | 7 +- .idea/migrations.xml | 10 + .idea/misc.xml | 2 +- .idea/modules.xml | 4 +- .idea/modules/SSLDroid.androidTest.iml | 28 ++ .idea/modules/SSLDroid.iml | 147 ------ .idea/modules/SSLDroid.main.iml | 40 ++ .idea/modules/SSLDroid.unitTest.iml | 22 + .idea/runConfigurations.xml | 8 + .idea/workspace.xml | 287 ++++++----- build.gradle | 12 +- gradle.properties | 2 + gradle/wrapper/gradle-wrapper.properties | 2 +- local.properties | 9 +- 18 files changed, 918 insertions(+), 291 deletions(-) create mode 100644 .idea/AndroidProjectSystem.xml create mode 100644 .idea/caches/deviceStreaming.xml create mode 100644 .idea/compiler.xml create mode 100644 .idea/deploymentTargetSelector.xml create mode 100644 .idea/migrations.xml create mode 100644 .idea/modules/SSLDroid.androidTest.iml delete mode 100644 .idea/modules/SSLDroid.iml create mode 100644 .idea/modules/SSLDroid.main.iml create mode 100644 .idea/modules/SSLDroid.unitTest.iml create mode 100644 gradle.properties diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml new file mode 100644 index 0000000..9e9ba09 --- /dev/null +++ b/.idea/caches/deviceStreaming.xml @@ -0,0 +1,607 @@ + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..99efb15 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 2d5721d..5156c77 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,18 +1,19 @@ + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index ca4d8dc..838eaf4 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -35,7 +35,7 @@ - + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index dfd7a29..4febf2d 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,9 @@ - + + + \ No newline at end of file diff --git a/.idea/modules/SSLDroid.androidTest.iml b/.idea/modules/SSLDroid.androidTest.iml new file mode 100644 index 0000000..e077899 --- /dev/null +++ b/.idea/modules/SSLDroid.androidTest.iml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/SSLDroid.iml b/.idea/modules/SSLDroid.iml deleted file mode 100644 index ec1c101..0000000 --- a/.idea/modules/SSLDroid.iml +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/SSLDroid.main.iml b/.idea/modules/SSLDroid.main.iml new file mode 100644 index 0000000..011d20d --- /dev/null +++ b/.idea/modules/SSLDroid.main.iml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/SSLDroid.unitTest.iml b/.idea/modules/SSLDroid.unitTest.iml new file mode 100644 index 0000000..fabb573 --- /dev/null +++ b/.idea/modules/SSLDroid.unitTest.iml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml index 7f68460..72f00ed 100644 --- a/.idea/runConfigurations.xml +++ b/.idea/runConfigurations.xml @@ -3,6 +3,14 @@ + + + + + + + + + + + + + + + + - - + + + - + - + - + + + @@ -45,20 +66,24 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - da - databaseőat - databaseőa - databaseő - database - databasep - databasepa - databasepat - databasepath - deactivate - usesni - startService - id, - startser - ssldroid - Upgrading - gra - pick - title - - - C:\Users\blint_dev\StudioProjects\SSLDroid - - - - - - - - - - - - { - "customColor": "", - "associatedIndex": 1 -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -