Skip to content

Commit

Permalink
Add optional disabling of AV feature
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasKypta committed Jun 21, 2024
1 parent b21154d commit f2c0615
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 22 deletions.
32 changes: 20 additions & 12 deletions demoapp/www/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ var demoApp = {
},
configureAndroid: function () {
return __awaiter(this, void 0, void 0, function () {
var result, avFeatures, updateObserver, langSelect, isInitialized, list, itemPromises, enrichedItems, e_2, observer;
var result, avEnabled, avFeatures, updateObserver, langSelect, isInitialized, list, itemPromises, enrichedItems, e_2, observer;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
Expand All @@ -348,8 +348,16 @@ var demoApp = {
case 1:
result = _a.sent();
this.setAndroidState(result);
return [4, window.plugins.malwarelytics.android.antivirus.isAvEnabled()];
case 2:
avEnabled = _a.sent();
avFeatures = document.getElementById("av-features");
avFeatures.setAttribute('style', 'display:inline-block');
if (avEnabled) {
avFeatures.setAttribute('style', 'display:inline-block');
}
else {
avFeatures.setAttribute('style', 'display:none');
}
this.setButtonClick("smart-protection-button", this.onRunSmartProtection);
this.setButtonClick("last-update-info-button", function () { return __awaiter(_this, void 0, void 0, function () {
var _a, _b, _c, _d;
Expand Down Expand Up @@ -730,14 +738,14 @@ var demoApp = {
});
}); });
return [4, window.plugins.malwarelytics.isInitialized()];
case 2:
case 3:
isInitialized = _a.sent();
console.log("Is initialized: ".concat(isInitialized));
_a.label = 3;
case 3:
_a.trys.push([3, 6, , 7]);
return [4, window.plugins.malwarelytics.android.antivirus.getThreatList()];
_a.label = 4;
case 4:
_a.trys.push([4, 7, , 8]);
return [4, window.plugins.malwarelytics.android.antivirus.getThreatList()];
case 5:
list = _a.sent();
itemPromises = list.items
.filter(function (i) { return i.threatIndex == "MALWARE" || i.threatIndex == "HIGHLY_DANGEROUS" || i.threatIndex == "DANGEROUS"; })
Expand All @@ -753,7 +761,7 @@ var demoApp = {
});
}); });
return [4, Promise.all(itemPromises)];
case 5:
case 6:
enrichedItems = _a.sent();
enrichedItems
.sort(function (a, b) {
Expand Down Expand Up @@ -800,12 +808,12 @@ var demoApp = {
node.innerHTML = "<div class=\"threat\">".concat(icon, "<div class=\"appname\">").concat(apkInfo.label || apk.packageName, "</div><div class=\"threatindex ").concat(threatCls, "\">").concat(apk.threatIndex, "</div>").concat(flagsDiv, "</div>");
appList.appendChild(node);
});
return [3, 7];
case 6:
return [3, 8];
case 7:
e_2 = _a.sent();
console.log(e_2);
return [3, 7];
case 7:
return [3, 8];
case 8:
observer = {
debuggerDetected: function (detected) { console.log("RASP DEBUGGER DETECTED " + detected); },
emulatorDetected: function (emulatorDetection) { console.log("RASP EMULATOR DETECTED " + JSON.stringify(emulatorDetection)); },
Expand Down
7 changes: 6 additions & 1 deletion demoapp/www/js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,13 @@ var demoApp = {
let result = await window.plugins.malwarelytics.android.getInitializationResult();
this.setAndroidState(result);

const avEnabled = await window.plugins.malwarelytics.android.antivirus.isAvEnabled()
let avFeatures = document.getElementById("av-features");
avFeatures.setAttribute('style', 'display:inline-block');
if (avEnabled) {
avFeatures.setAttribute('style', 'display:inline-block');
} else {
avFeatures.setAttribute('style', 'display:none');
}
this.setButtonClick("smart-protection-button", this.onRunSmartProtection);

this.setButtonClick("last-update-info-button", async () => {
Expand Down
3 changes: 2 additions & 1 deletion scripts/MalwarelyticsError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ type MalwarelyticsErrorType =
"UTILS_LANG_CHANGE_FAILED" |
"THREAT_LIST_FAILED" |
"APK_INFO_NOT_AVAILABLE" |
"RASP_UNKNOWN_DETECTION";
"RASP_UNKNOWN_DETECTION" |
"AV_DISABLED";

class MalwarelyticsError {

Expand Down
7 changes: 7 additions & 0 deletions scripts/android/MalwarelyticsAndroidAntivirus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
*/
class MalwarelyticsAndroidAntivirus extends __MPAndroidService {

/**
* Check if AV feature is enabled.
*/
async isAvEnabled(): Promise<Boolean> {
return await this.callAsync("isAvEnabled");
}

/**
* Schedules a job that will execute smart protection run. Note that this is asynchronous and
* can take some time.
Expand Down
3 changes: 3 additions & 0 deletions scripts/configuration/MalwarelyticsAndroidConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ type MalwarelyticsAndroidFingerprintType = "NONE" | "BASIC" | "SAFE" | "FULL";
* Antivirus component configuration for Android platform
*/
interface MalwarelyticsAndroidAntivirusConfig {

/** For turning off Antivirus feature of Malwarelytics. Default is true. */
enableAntivirus?: boolean;

/** Malwarelytics in silent mode does not show any UI. Default is true. */
enableSilentMode?: boolean;
Expand Down
67 changes: 61 additions & 6 deletions src/android/MalwarelyticsPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ class MalwarelyticsPlugin : CordovaPlugin() {

APK_INFO_NOT_AVAILABLE,

RASP_UNKNOWN_DETECTION
RASP_UNKNOWN_DETECTION,

AV_DISABLED
}

private enum class RaspDetection {
Expand Down Expand Up @@ -174,6 +176,11 @@ class MalwarelyticsPlugin : CordovaPlugin() {
return true
}

if (action == "isAvEnabled") {
this.isAvEnabled(callbackContext)
return true
}

if (action == "triggerSmartProtection") {
val performOnlineUpdate: Boolean = if (args.isNull(0)) {
true
Expand Down Expand Up @@ -282,6 +289,16 @@ class MalwarelyticsPlugin : CordovaPlugin() {
return result
}

private fun isAvEnabled(callbackContext: CallbackContext): Boolean {
if (!this.isInitialized()) {
callbackContext.error(Error.PLUGIN_NOT_INITIALIZED.name)
return false
}
val result = this.isAvEnabled()
callbackContext.success(if (result) 1 else 0)
return result
}

private fun initialize(config: JsMalwarelyticsConfig, callbackContext: CallbackContext) {

cordova.threadPool.execute(Runnable {
Expand Down Expand Up @@ -364,8 +381,15 @@ class MalwarelyticsPlugin : CordovaPlugin() {
MalwarelyticsConfig.DELETE_ICON?.let { tmBuilder.screenDeleteIcon(it) }
config.androidConfig?.languageCode?.let { tmBuilder.customLocalization(it) }

val avConfigBuilder = AntivirusConfig.Builder().smartProtectionConfig(spb.build())
avConfigBuilder.threatMitigationUIConfig(tmBuilder.build())

val avConfigBuilder = AntivirusConfig.Builder()
.smartProtectionConfig(spb.build())
.threatMitigationUIConfig(tmBuilder.build())

// disabling AV feature
config.androidConfig?.antivirusConfig?.enableAntivirus?.let {
avConfigBuilder.enableAntivirus(it)
}

val builder = AppProtectionConfig.Builder(context)
.antivirusConfig(avConfigBuilder.build())
Expand Down Expand Up @@ -449,6 +473,10 @@ class MalwarelyticsPlugin : CordovaPlugin() {
if (!isInitialized()) {
callbackContext.error(Error.PLUGIN_NOT_INITIALIZED.name)
} else {
if (!isAvEnabled()) {
callbackContext.error(Error.AV_DISABLED.name)
return@Runnable
}
val updateResult = appProtection!!.getAntivirus().getSmartProtectionManager().performSingleSmartProtectionUpdate(performOnlineUpdate)
val o = JSONObject()
o.put("uiDisplayed", updateResult.uiDisplayed)
Expand Down Expand Up @@ -503,11 +531,17 @@ class MalwarelyticsPlugin : CordovaPlugin() {
}

private fun getLastUpdateInfo(callbackContext: CallbackContext) {
if (!isAvInProperState(callbackContext)) {
return
}
val updateInfo = this.appProtection!!.getAntivirus().getUpdateManager().getLastUpdateInfo()
callbackContext.success(updateInfo.toJson())
}

private fun setUpdateCallback(callbackContext: CallbackContext) {
if (!isAvInProperState(callbackContext)) {
return
}
fun resolve(jsonObject: JSONObject) {
cordova.threadPool.execute(Runnable {
updateCallbackContext?.sendPluginResult(PluginResult(PluginResult.Status.OK, jsonObject).also { it.keepCallback = true })
Expand All @@ -531,6 +565,9 @@ class MalwarelyticsPlugin : CordovaPlugin() {
}

private fun clearUpdateCallback(callbackContext: CallbackContext?) {
if (!isAvInProperState(callbackContext)) {
return
}
val result = PluginResult(PluginResult.Status.NO_RESULT, "Update Callback Cleared")
result.keepCallback = false
updateCallbackContext?.sendPluginResult(result)
Expand All @@ -539,6 +576,18 @@ class MalwarelyticsPlugin : CordovaPlugin() {
callbackContext?.success()
}

private fun isAvInProperState(callbackContext: CallbackContext?): Boolean {
if (!isInitialized()) {
callbackContext?.error(Error.PLUGIN_NOT_INITIALIZED.name)
return false
}
if (!isAvEnabled()) {
callbackContext?.error(Error.AV_DISABLED.name)
return false
}
return true
}

private fun getRaspDetection(detection: RaspDetection, callbackContext: CallbackContext) {
cordova.threadPool.execute(Runnable {

Expand Down Expand Up @@ -727,6 +776,10 @@ class MalwarelyticsPlugin : CordovaPlugin() {
raspObserver = null
callbackContext?.success()
}

private fun isAvEnabled(): Boolean {
return appProtection!!.getAppProtectionConfig().antivirusConfig.enableAntivirus
}
}

data class JsMalwarelyticsConfig(val clientId: String?,
Expand Down Expand Up @@ -759,9 +812,11 @@ enum class JsFingerprintType {
}
}

data class JsAntivirusConfig(val enableSilentMode: Boolean?,
val onlineCheckIntervalHours: Int?,
val updateOnInitialize: Boolean?)
data class JsAntivirusConfig(
val enableAntivirus: Boolean?,
val enableSilentMode: Boolean?,
val onlineCheckIntervalHours: Int?,
val updateOnInitialize: Boolean?)

data class JsRaspConfig(val emulator: JsRaspDetectionConfig?,
val root: JsRaspRootDetectionConfig?,
Expand Down
8 changes: 7 additions & 1 deletion www/MalwarelyticsPlugin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ declare class MalwarelyticsAndroid extends __MPAndroidService {
* Antivirus component of the Malwarelytics for Android.
*/
declare class MalwarelyticsAndroidAntivirus extends __MPAndroidService {
/**
* Check if AV feature is enabled.
*/
isAvEnabled(): Promise<Boolean>;
/**
* Schedules a job that will execute smart protection run. Note that this is asynchronous and
* can take some time.
Expand Down Expand Up @@ -334,6 +338,8 @@ type MalwarelyticsAndroidFingerprintType = "NONE" | "BASIC" | "SAFE" | "FULL";
* Antivirus component configuration for Android platform
*/
interface MalwarelyticsAndroidAntivirusConfig {
/** For turning off Antivirus feature of Malwarelytics. Default is true. */
enableAntivirus?: boolean;
/** Malwarelytics in silent mode does not show any UI. Default is true. */
enableSilentMode?: boolean;
/** How often will be antivirus database checked (hourly). Default is 48 hours. */
Expand Down Expand Up @@ -732,7 +738,7 @@ interface MalwarelyticsConfig {
/**
* Each type matches to specific error case
*/
type MalwarelyticsErrorType = "PLUGIN_UNKNOWN_ACTION" | "PLUGIN_ALREADY_INITIALIZED" | "PLUGIN_NOT_INITIALIZED" | "MISSING_ARGUMENTS" | "INITIALIZE_MISSING_CREDENTIALS" | "INITIALIZE_WRONG_CONFIG" | "TRIGGER_SMART_PROTECTION_UPDATE_FAILED" | "TRIGGER_SMART_PROTECTION_FAILED" | "UTILS_LANG_CHANGE_FAILED" | "THREAT_LIST_FAILED" | "APK_INFO_NOT_AVAILABLE" | "RASP_UNKNOWN_DETECTION";
type MalwarelyticsErrorType = "PLUGIN_UNKNOWN_ACTION" | "PLUGIN_ALREADY_INITIALIZED" | "PLUGIN_NOT_INITIALIZED" | "MISSING_ARGUMENTS" | "INITIALIZE_MISSING_CREDENTIALS" | "INITIALIZE_WRONG_CONFIG" | "TRIGGER_SMART_PROTECTION_UPDATE_FAILED" | "TRIGGER_SMART_PROTECTION_FAILED" | "UTILS_LANG_CHANGE_FAILED" | "THREAT_LIST_FAILED" | "APK_INFO_NOT_AVAILABLE" | "RASP_UNKNOWN_DETECTION" | "AV_DISABLED";
declare class MalwarelyticsError {
readonly type: MalwarelyticsErrorType;
readonly data?: any;
Expand Down
13 changes: 13 additions & 0 deletions www/MalwarelyticsPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,19 @@ var MalwarelyticsAndroidAntivirus = /** @class */ (function (_super) {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Check if AV feature is enabled.
*/
MalwarelyticsAndroidAntivirus.prototype.isAvEnabled = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.callAsync("isAvEnabled")];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
/**
* Schedules a job that will execute smart protection run. Note that this is asynchronous and
* can take some time.
*
Expand Down
8 changes: 7 additions & 1 deletion www/MalwarelyticsPlugin.module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ export declare class MalwarelyticsAndroid extends __MPAndroidService {
* Antivirus component of the Malwarelytics for Android.
*/
export declare class MalwarelyticsAndroidAntivirus extends __MPAndroidService {
/**
* Check if AV feature is enabled.
*/
isAvEnabled(): Promise<Boolean>;
/**
* Schedules a job that will execute smart protection run. Note that this is asynchronous and
* can take some time.
Expand Down Expand Up @@ -334,6 +338,8 @@ export declare type MalwarelyticsAndroidFingerprintType = "NONE" | "BASIC" | "SA
* Antivirus component configuration for Android platform
*/
export interface MalwarelyticsAndroidAntivirusConfig {
/** For turning off Antivirus feature of Malwarelytics. Default is true. */
enableAntivirus?: boolean;
/** Malwarelytics in silent mode does not show any UI. Default is true. */
enableSilentMode?: boolean;
/** How often will be antivirus database checked (hourly). Default is 48 hours. */
Expand Down Expand Up @@ -732,7 +738,7 @@ export interface MalwarelyticsConfig {
/**
* Each type matches to specific error case
*/
export declare type MalwarelyticsErrorType = "PLUGIN_UNKNOWN_ACTION" | "PLUGIN_ALREADY_INITIALIZED" | "PLUGIN_NOT_INITIALIZED" | "MISSING_ARGUMENTS" | "INITIALIZE_MISSING_CREDENTIALS" | "INITIALIZE_WRONG_CONFIG" | "TRIGGER_SMART_PROTECTION_UPDATE_FAILED" | "TRIGGER_SMART_PROTECTION_FAILED" | "UTILS_LANG_CHANGE_FAILED" | "THREAT_LIST_FAILED" | "APK_INFO_NOT_AVAILABLE" | "RASP_UNKNOWN_DETECTION";
export declare type MalwarelyticsErrorType = "PLUGIN_UNKNOWN_ACTION" | "PLUGIN_ALREADY_INITIALIZED" | "PLUGIN_NOT_INITIALIZED" | "MISSING_ARGUMENTS" | "INITIALIZE_MISSING_CREDENTIALS" | "INITIALIZE_WRONG_CONFIG" | "TRIGGER_SMART_PROTECTION_UPDATE_FAILED" | "TRIGGER_SMART_PROTECTION_FAILED" | "UTILS_LANG_CHANGE_FAILED" | "THREAT_LIST_FAILED" | "APK_INFO_NOT_AVAILABLE" | "RASP_UNKNOWN_DETECTION" | "AV_DISABLED";
export declare class MalwarelyticsError {
readonly type: MalwarelyticsErrorType;
readonly data?: any;
Expand Down

0 comments on commit f2c0615

Please sign in to comment.