Server override option

Signed-off-by: Tad <tad@spotco.us>
This commit is contained in:
Tad 2022-04-03 21:19:10 -04:00
parent aebe653025
commit 108dab063d
9 changed files with 70 additions and 25 deletions

1
.idea/misc.xml generated
View file

@ -4,6 +4,7 @@
<option name="filePathToZoomLevelMap"> <option name="filePathToZoomLevelMap">
<map> <map>
<entry key="app/src/main/res/layout/activity_main.xml" value="0.9348958333333334" /> <entry key="app/src/main/res/layout/activity_main.xml" value="0.9348958333333334" />
<entry key="app/src/main/res/menu/menu_main.xml" value="0.3723958333333333" />
</map> </map>
</option> </option>
</component> </component>

View file

@ -6,8 +6,8 @@ android {
applicationId "us.spotco.malwarescanner" applicationId "us.spotco.malwarescanner"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 29 targetSdkVersion 29
versionCode 79 versionCode 80
versionName "2.23" versionName "2.24"
resConfigs "en", "af", "de", "es", "fr", "it", "pt", "ru" resConfigs "en", "af", "de", "es", "fr", "it", "pt", "ru"
} }
buildTypes { buildTypes {

View file

@ -36,8 +36,6 @@ import java.text.DateFormat;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
class Database { class Database {
@ -49,9 +47,6 @@ class Database {
private static boolean databaseCurrentlyLoading = false; private static boolean databaseCurrentlyLoading = false;
public final static ConcurrentLinkedQueue<SignatureDatabase> signatureDatabases = new ConcurrentLinkedQueue<>(); public final static ConcurrentLinkedQueue<SignatureDatabase> signatureDatabases = new ConcurrentLinkedQueue<>();
public final static String baseURL = "https://divested.dev/MalwareScannerSignatures/";
public final static String baseURLOnion = "https://hypatiagbf5vp3ba.onion/MalwareScannerSignatures/"; //TODO: Setup the .onion
public final static HashMap<String, String> signaturesMD5 = new HashMap<>(); public final static HashMap<String, String> signaturesMD5 = new HashMap<>();
public final static HashMap<String, String> signaturesSHA1 = new HashMap<>(); public final static HashMap<String, String> signaturesSHA1 = new HashMap<>();
public final static HashMap<String, String> signaturesSHA256 = new HashMap<>(); public final static HashMap<String, String> signaturesSHA256 = new HashMap<>();
@ -77,9 +72,12 @@ class Database {
public static void updateDatabase(Context context, ConcurrentLinkedQueue<SignatureDatabase> signatureDatabases) { public static void updateDatabase(Context context, ConcurrentLinkedQueue<SignatureDatabase> signatureDatabases) {
initDatabase(context); initDatabase(context);
log.append(context.getString(R.string.main_database_updating, signatureDatabases.size() + "") + "\n"); log.append(context.getString(R.string.main_database_updating, signatureDatabases.size() + "") + "\n");
if(!Utils.getDatabaseURL(context).equals(Utils.DATABASE_URL_DEFAULT)) {
log.append(context.getString(R.string.main_database_override, Utils.getDatabaseURL(context)) + "\n");
}
for (SignatureDatabase signatureDatabase : signatureDatabases) { for (SignatureDatabase signatureDatabase : signatureDatabases) {
boolean onionRouting = prefs.getBoolean("ONION_ROUTING", false); boolean onionRouting = prefs.getBoolean("ONION_ROUTING", false);
new Downloader().executeOnExecutor(Utils.getThreadPoolExecutor(), onionRouting, signatureDatabase.getUrl(), databasePath + "/" + signatureDatabase.getName()); new Downloader().executeOnExecutor(Utils.getThreadPoolExecutor(), onionRouting, signatureDatabase.getUrl(), databasePath + "/" + signatureDatabase.getName(), signatureDatabase.getBaseUrl());
} }
} }
@ -90,25 +88,26 @@ class Database {
signatureDatabases.clear(); signatureDatabases.clear();
prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE); prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);
String baseURL = Utils.getDatabaseURL(context);
if (prefs.getBoolean("SIGNATURES_TARGETEDTHREATS", true)) { if (prefs.getBoolean("SIGNATURES_TARGETEDTHREATS", true)) {
signatureDatabases.add(new SignatureDatabase(baseURL + "targetedthreats.hdb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "targetedthreats.hdb.gz"));
signatureDatabases.add(new SignatureDatabase(baseURL + "targetedthreats.hsb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "targetedthreats.hsb.gz"));
} }
if (prefs.getBoolean("SIGNATURES_ESET", true)) { if (prefs.getBoolean("SIGNATURES_ESET", true)) {
signatureDatabases.add(new SignatureDatabase(baseURL + "eset.hdb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "eset.hdb.gz"));
signatureDatabases.add(new SignatureDatabase(baseURL + "eset.hsb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "eset.hsb.gz"));
} }
if (prefs.getBoolean("SIGNATURES_CLAMAV-MAIN", false)) { if (prefs.getBoolean("SIGNATURES_CLAMAV-MAIN", false)) {
signatureDatabases.add(new SignatureDatabase(baseURL + "main.hdb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "main.hdb.gz"));
signatureDatabases.add(new SignatureDatabase(baseURL + "main.hsb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "main.hsb.gz"));
} }
if (prefs.getBoolean("SIGNATURES_CLAMAV-DAILY", false)) { if (prefs.getBoolean("SIGNATURES_CLAMAV-DAILY", false)) {
signatureDatabases.add(new SignatureDatabase(baseURL + "daily.hdb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "daily.hdb.gz"));
signatureDatabases.add(new SignatureDatabase(baseURL + "daily.hsb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "daily.hsb.gz"));
} }
if (prefs.getBoolean("SIGNATURES_CLAMAV-ANDROID", true)) { if (prefs.getBoolean("SIGNATURES_CLAMAV-ANDROID", true)) {
signatureDatabases.add(new SignatureDatabase(baseURL + "Android.hdb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "Android.hdb.gz"));
signatureDatabases.add(new SignatureDatabase(baseURL + "Android.hsb.gz")); signatureDatabases.add(new SignatureDatabase(baseURL, "Android.hsb.gz"));
} }
} }
@ -173,11 +172,11 @@ class Database {
boolean onionRouting = (boolean) objects[0]; boolean onionRouting = (boolean) objects[0];
String url = (String) objects[1]; String url = (String) objects[1];
File out = new File((String) objects[2]); File out = new File((String) objects[2]);
String baseURL = (String) objects[3];
try { try {
HttpURLConnection connection; HttpURLConnection connection;
if (onionRouting) { if (onionRouting) {
Utils.waitUntilOrbotIsAvailable(); Utils.waitUntilOrbotIsAvailable();
//url = url.replaceAll(baseURL, baseURLOnion); //TODO: Setup the .onion
Proxy orbot = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 9050)); Proxy orbot = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 9050));
connection = (HttpURLConnection) new URL(url).openConnection(orbot); connection = (HttpURLConnection) new URL(url).openConnection(orbot);
} else { } else {

View file

@ -21,6 +21,7 @@ import android.Manifest;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
@ -29,10 +30,12 @@ import android.content.res.ColorStateList;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.text.InputType;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -215,6 +218,32 @@ public class MainActivity extends AppCompatActivity {
case R.id.mnuSelectDatabases: case R.id.mnuSelectDatabases:
selectDatabases(); selectDatabases();
break; break;
case R.id.mnuDatabaseServer:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.lblDatabaseServer));
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
input.setText(Utils.getDatabaseURL(this));
builder.setView(input);
builder.setPositiveButton(getString(R.string.lblOverride), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String newServer = input.getText().toString();
if(!newServer.endsWith("/")) {
newServer += "/";
}
prefs.edit().putString("DATABASE_SERVER", newServer).apply();
}
});
builder.setNegativeButton(getString(R.string.lblReset), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
prefs.edit().putString("DATABASE_SERVER", Utils.DATABASE_URL_DEFAULT).apply();
dialog.cancel();
}
});
builder.show();
break;
case R.id.toggleRealtime: case R.id.toggleRealtime:
Intent realtimeScanner = new Intent(getApplicationContext(), MalwareScannerService.class); Intent realtimeScanner = new Intent(getApplicationContext(), MalwareScannerService.class);
if (!item.isChecked()) { if (!item.isChecked()) {

View file

@ -19,20 +19,22 @@ package us.spotco.malwarescanner;
class SignatureDatabase { class SignatureDatabase {
private final String url; private final String baseURL;
private final String name; private final String name;
public SignatureDatabase(String url) { public SignatureDatabase(String baseURL, String name) {
this.url = url; this.baseURL = baseURL;
this.name = url.replaceAll(Database.baseURL, ""); this.name = name;
} }
public final String getUrl() { public final String getBaseUrl() {
return url; return baseURL;
} }
public final String getName() { public final String getName() {
return name; return name;
} }
public final String getUrl() { return baseURL + name; }
} }

View file

@ -37,6 +37,7 @@ class Utils {
private static Context context = null; private static Context context = null;
public final static int MAX_SCAN_SIZE = (1000 * 1000) * 80; //80MB public final static int MAX_SCAN_SIZE = (1000 * 1000) * 80; //80MB
public final static int MAX_SCAN_SIZE_REALTIME = MAX_SCAN_SIZE / 2; //40MB public final static int MAX_SCAN_SIZE_REALTIME = MAX_SCAN_SIZE / 2; //40MB
public final static String DATABASE_URL_DEFAULT = "https://divested.dev/MalwareScannerSignatures/";
public final static int MAX_HASH_LENGTH = 12; public final static int MAX_HASH_LENGTH = 12;
@ -98,6 +99,11 @@ class Utils {
return false; return false;
} }
public static String getDatabaseURL(Context context) {
SharedPreferences prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);
return prefs.getString("DATABASE_SERVER", DATABASE_URL_DEFAULT);
}
public static void considerStartService(Context context) { public static void considerStartService(Context context) {
if (!Utils.isServiceRunning(MalwareScannerService.class, context)) { if (!Utils.isServiceRunning(MalwareScannerService.class, context)) {
SharedPreferences prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE); SharedPreferences prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);

View file

@ -12,6 +12,9 @@
<item <item
android:id="@+id/mnuSelectDatabases" android:id="@+id/mnuSelectDatabases"
android:title="@string/lblSelectDatabases" /> android:title="@string/lblSelectDatabases" />
<item
android:id="@+id/mnuDatabaseServer"
android:title="@string/lblDatabaseServer" />
<item <item
android:id="@+id/toggleRealtime" android:id="@+id/toggleRealtime"
android:title="@string/lblRealtimeScannerToggle" android:title="@string/lblRealtimeScannerToggle"

View file

@ -13,6 +13,7 @@
<string name="lblUpdateDatabase">Update databases</string> <string name="lblUpdateDatabase">Update databases</string>
<string name="lblSelectDatabases">Select databases</string> <string name="lblSelectDatabases">Select databases</string>
<string name="lblSelectDatabasesTitle">Select databases to enable</string> <string name="lblSelectDatabasesTitle">Select databases to enable</string>
<string name="lblDatabaseServer">Database server override</string>
<string name="lblFullCredits">Credits</string> <string name="lblFullCredits">Credits</string>
<string name="lblScanSystem">Scan /system</string> <string name="lblScanSystem">Scan /system</string>
<string name="lblScanApps">Scan App APKs</string> <string name="lblScanApps">Scan App APKs</string>
@ -26,8 +27,11 @@
<string name="lblNotificationRealtimeStopped">Hypatia: Realtime Scanning Stopped</string> <string name="lblNotificationRealtimeStopped">Hypatia: Realtime Scanning Stopped</string>
<string name="lblNotificationRealtimeDetection">Malware Detected:</string> <string name="lblNotificationRealtimeDetection">Malware Detected:</string>
<string name="lblRealtimeScannerToggle">Realtime Scanner</string> <string name="lblRealtimeScannerToggle">Realtime Scanner</string>
<string name="lblReset">Reset</string>
<string name="lblOverride">Override</string>
<string name="main_database_updating">Updating %s databases...</string> <string name="main_database_updating">Updating %s databases...</string>
<string name="main_database_override">Using server %s</string>
<string name="main_database_downloading">Downloading %s</string> <string name="main_database_downloading">Downloading %s</string>
<string name="main_database_download_success">Successfully downloaded</string> <string name="main_database_download_success">Successfully downloaded</string>
<string name="main_database_download_error">File not downloaded, response code %s</string> <string name="main_database_download_error">File not downloaded, response code %s</string>

View file

@ -0,0 +1 @@
* Add the option to change server URL. Such replacement must have the same file names. Database generation scripts in source code repository.