capacitor-freerasp 2.4.1 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +69 -0
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/aheaditec/freerasp/FreeraspPlugin.kt +61 -46
- package/android/src/main/java/com/aheaditec/freerasp/PluginThreatHandler.kt +25 -27
- package/android/src/main/java/com/aheaditec/freerasp/dispatchers/ExecutionStateDispatcher.kt +35 -16
- package/android/src/main/java/com/aheaditec/freerasp/dispatchers/ThreatDispatcher.kt +42 -24
- package/android/src/main/java/com/aheaditec/freerasp/utils/RandomGenerator.kt +1 -2
- package/dist/esm/api/listeners/raspExecutionState.js +23 -11
- package/dist/esm/api/listeners/raspExecutionState.js.map +1 -1
- package/dist/esm/api/listeners/threat.js +25 -12
- package/dist/esm/api/listeners/threat.js.map +1 -1
- package/dist/esm/api/methods/capacitor.js +7 -1
- package/dist/esm/api/methods/capacitor.js.map +1 -1
- package/dist/esm/channels/threat.js +2 -5
- package/dist/esm/channels/threat.js.map +1 -1
- package/dist/esm/models/threat.js +1 -0
- package/dist/esm/models/threat.js.map +1 -1
- package/dist/esm/types/types.d.ts +6 -1
- package/dist/esm/types/types.js.map +1 -1
- package/dist/plugin.cjs.js +58 -28
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +58 -28
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/FreeraspPlugin.m +1 -0
- package/ios/Plugin/FreeraspPlugin.swift +28 -8
- package/ios/Plugin/TalsecRuntime.xcframework/Info.plist +5 -5
- package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeDirectory +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeResources +95 -62
- package/ios/Plugin/TalsecRuntime.xcframework/_CodeSignature/CodeSignature +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/curl.h +7 -7
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/multi.h +4 -4
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/options.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/urlapi.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.abi.json +360 -103
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.private.swiftinterface +2 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface +2 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/PrivacyInfo.xcprivacy +8 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/_CodeSignature/CodeResources +377 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +2 -2
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/curl.h +7 -7
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/multi.h +4 -4
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/options.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/urlapi.h +1 -1
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.abi.json +367 -110
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +2 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface +2 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.abi.json +367 -110
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +2 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +2 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/PrivacyInfo.xcprivacy +8 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime +0 -0
- package/ios/Plugin/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources +42 -53
- package/ios/Plugin/models/SecurityThreat.swift +2 -0
- package/ios/Plugin/utils/EventIdentifiers.swift +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,75 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.5.1] - 2026-03-24
|
|
9
|
+
|
|
10
|
+
- Android SDK version: 18.0.4
|
|
11
|
+
- iOS SDK version: 6.14.4
|
|
12
|
+
|
|
13
|
+
### Capacitor
|
|
14
|
+
|
|
15
|
+
#### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixed case where event dispatchers on Android were not initialized before calling onResume at the app launch
|
|
18
|
+
|
|
19
|
+
### iOS
|
|
20
|
+
|
|
21
|
+
#### Fixed
|
|
22
|
+
|
|
23
|
+
- Fixed new jailbreak checks false positives on iOS 14 and 13.
|
|
24
|
+
- Fixed false positives with jailbreak on iOS 15 and 16.
|
|
25
|
+
- Fixed issue with app crashing on screenshot/screen recording.
|
|
26
|
+
- Fixed retrigger jailbreak issue on iOS 15 and 16.
|
|
27
|
+
|
|
28
|
+
## [2.5.0] - 2026-03-03
|
|
29
|
+
|
|
30
|
+
- Android SDK version: 18.0.4
|
|
31
|
+
- iOS SDK version: 6.14.1
|
|
32
|
+
|
|
33
|
+
### Capacitor
|
|
34
|
+
|
|
35
|
+
#### Changed
|
|
36
|
+
|
|
37
|
+
- Refactor the Android plugin to separate the logic for managing listener states
|
|
38
|
+
|
|
39
|
+
### Android
|
|
40
|
+
|
|
41
|
+
#### Added
|
|
42
|
+
|
|
43
|
+
- Added support for `KernelSU` to the existing root detection capabilities
|
|
44
|
+
- Added support for `HMA` to the existing root detection capabilities
|
|
45
|
+
- Added new malware detection capabilities
|
|
46
|
+
- Added `onAutomationDetected()` callback to `ThreatDetected` interface
|
|
47
|
+
- We are introducing a new capability, detecting whether the device is being automated using tools like Appium
|
|
48
|
+
- Added value restrictions to `externalId`
|
|
49
|
+
- Method `storeExternalId()` now returns `ExternalIdResult`, which indicates `Success` or `Error` when `externalId` violates restrictions
|
|
50
|
+
|
|
51
|
+
#### Fixed
|
|
52
|
+
|
|
53
|
+
- Fixed exception handling for the KeyStore `getEntry` operation
|
|
54
|
+
- Fixed issue in `ScreenProtector` concerning the `onScreenRecordingDetected` invocations
|
|
55
|
+
- Merged internal shared libraries into a single one, reducing the final APK size
|
|
56
|
+
- Fixed bug related to key storing in keystore type detection (hw-backed keystore check)
|
|
57
|
+
- Fixed manifest queries merge
|
|
58
|
+
|
|
59
|
+
#### Changed
|
|
60
|
+
|
|
61
|
+
- Removed unused library `tmlib`
|
|
62
|
+
- Refactoring of signature verification code
|
|
63
|
+
- Updated compile and target API to 36
|
|
64
|
+
- Improved root detection capabilities
|
|
65
|
+
- Detection of wireless ADB added to ADB detections
|
|
66
|
+
|
|
67
|
+
### iOS
|
|
68
|
+
|
|
69
|
+
#### Added
|
|
70
|
+
|
|
71
|
+
- Added time spoofing detection, detecting an inaccurate device clock. It is a new threat `timeSpoofing`.
|
|
72
|
+
|
|
73
|
+
#### Changed
|
|
74
|
+
|
|
75
|
+
- Improved jailbreak detection methods.
|
|
76
|
+
|
|
8
77
|
## [2.4.1] - 2026-02-13
|
|
9
78
|
|
|
10
79
|
- Android SDK version: 18.0.2
|
package/android/build.gradle
CHANGED
|
@@ -76,5 +76,5 @@ dependencies {
|
|
|
76
76
|
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
77
77
|
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
78
78
|
|
|
79
|
-
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Capacitor:18.0.
|
|
79
|
+
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Capacitor:18.0.4'
|
|
80
80
|
}
|
|
@@ -5,6 +5,8 @@ import android.os.Build
|
|
|
5
5
|
import android.os.Handler
|
|
6
6
|
import android.os.HandlerThread
|
|
7
7
|
import android.os.Looper
|
|
8
|
+
import com.aheaditec.freerasp.dispatchers.ExecutionStateDispatcher
|
|
9
|
+
import com.aheaditec.freerasp.dispatchers.ThreatDispatcher
|
|
8
10
|
import com.aheaditec.freerasp.utils.Utils
|
|
9
11
|
import com.aheaditec.freerasp.utils.getArraySafe
|
|
10
12
|
import com.aheaditec.freerasp.utils.getNestedArraySafe
|
|
@@ -29,8 +31,6 @@ typealias CapacitorCallback = (String, JSObject) -> Unit
|
|
|
29
31
|
@CapacitorPlugin(name = "Freerasp")
|
|
30
32
|
class FreeraspPlugin : Plugin() {
|
|
31
33
|
|
|
32
|
-
private var registered = true
|
|
33
|
-
|
|
34
34
|
override fun load() {
|
|
35
35
|
initializeEventKeys()
|
|
36
36
|
super.load()
|
|
@@ -38,6 +38,11 @@ class FreeraspPlugin : Plugin() {
|
|
|
38
38
|
|
|
39
39
|
@PluginMethod
|
|
40
40
|
fun talsecStart(call: PluginCall) {
|
|
41
|
+
if (talsecStarted) {
|
|
42
|
+
call.resolve(JSObject().put("started", true))
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
val config = call.getObject("config")
|
|
42
47
|
if (config == null) {
|
|
43
48
|
call.reject("Missing config parameter in freeRASP Native Plugin")
|
|
@@ -45,14 +50,7 @@ class FreeraspPlugin : Plugin() {
|
|
|
45
50
|
}
|
|
46
51
|
try {
|
|
47
52
|
val talsecConfig = buildTalsecConfigThrowing(config)
|
|
48
|
-
|
|
49
|
-
val pluginCallback: CapacitorCallback = { eventName, data ->
|
|
50
|
-
notifyListeners(eventName, data, true)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
PluginThreatHandler.threatDispatcher.listener = PluginListener(context, pluginCallback)
|
|
54
|
-
PluginThreatHandler.executionStateDispatcher.listener = PluginListener(context, pluginCallback)
|
|
55
|
-
PluginThreatHandler.registerListener(context)
|
|
53
|
+
PluginThreatHandler.registerSDKListener(context)
|
|
56
54
|
|
|
57
55
|
bridge.activity.runOnUiThread {
|
|
58
56
|
Talsec.start(context, talsecConfig)
|
|
@@ -75,35 +73,52 @@ class FreeraspPlugin : Plugin() {
|
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
@PluginMethod(returnType = PluginMethod.RETURN_NONE)
|
|
77
|
+
override fun addListener(call: PluginCall) {
|
|
78
|
+
val eventName = call.getString("eventName")
|
|
79
|
+
val pluginCallback: CapacitorCallback = { eventName, data ->
|
|
80
|
+
notifyListeners(eventName, data, true)
|
|
81
|
+
}
|
|
82
|
+
if (eventName == ThreatEvent.CHANNEL_NAME) {
|
|
83
|
+
ThreatDispatcher.registerListener(PluginListener(context, pluginCallback))
|
|
84
|
+
}
|
|
85
|
+
if (eventName == RaspExecutionStateEvent.CHANNEL_NAME) {
|
|
86
|
+
ExecutionStateDispatcher.registerListener(PluginListener(context, pluginCallback))
|
|
87
|
+
}
|
|
88
|
+
super.addListener(call)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@PluginMethod(returnType = PluginMethod.RETURN_NONE)
|
|
92
|
+
fun removeListenerForEvent(call: PluginCall) {
|
|
93
|
+
val eventName = call.getString("eventName")
|
|
94
|
+
if (eventName == ThreatEvent.CHANNEL_NAME) {
|
|
95
|
+
ThreatDispatcher.unregisterListener()
|
|
96
|
+
}
|
|
97
|
+
if (eventName == RaspExecutionStateEvent.CHANNEL_NAME) {
|
|
98
|
+
ExecutionStateDispatcher.unregisterListener()
|
|
82
99
|
}
|
|
83
100
|
}
|
|
84
101
|
|
|
85
102
|
override fun handleOnPause() {
|
|
86
103
|
super.handleOnPause()
|
|
104
|
+
ThreatDispatcher.onPause()
|
|
105
|
+
ExecutionStateDispatcher.onPause()
|
|
106
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
107
|
+
ScreenProtector.unregister(activity)
|
|
108
|
+
}
|
|
87
109
|
if (activity.isFinishing) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
PluginThreatHandler.
|
|
91
|
-
PluginThreatHandler.executionStateDispatcher.listener = null
|
|
110
|
+
ThreatDispatcher.unregisterListener()
|
|
111
|
+
ExecutionStateDispatcher.unregisterListener()
|
|
112
|
+
PluginThreatHandler.unregisterSDKListener(context)
|
|
92
113
|
}
|
|
93
114
|
}
|
|
94
115
|
|
|
95
116
|
override fun handleOnResume() {
|
|
96
117
|
super.handleOnResume()
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
PluginThreatHandler.registerListener(context)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
override fun handleOnStop() {
|
|
104
|
-
super.handleOnStop()
|
|
118
|
+
ThreatDispatcher.onResume()
|
|
119
|
+
ExecutionStateDispatcher.onResume()
|
|
105
120
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
106
|
-
ScreenProtector.
|
|
121
|
+
ScreenProtector.register(activity)
|
|
107
122
|
}
|
|
108
123
|
}
|
|
109
124
|
|
|
@@ -317,8 +332,25 @@ class FreeraspPlugin : Plugin() {
|
|
|
317
332
|
private val mainHandler = Handler(Looper.getMainLooper())
|
|
318
333
|
|
|
319
334
|
internal var talsecStarted = false
|
|
335
|
+
}
|
|
320
336
|
|
|
321
|
-
|
|
337
|
+
internal class PluginListener(
|
|
338
|
+
private val context: Context,
|
|
339
|
+
private val pluginCallback: CapacitorCallback
|
|
340
|
+
) : PluginThreatListener, PluginExecutionStateListener {
|
|
341
|
+
override fun threatDetected(threatEventType: ThreatEvent) {
|
|
342
|
+
notifyEvent(threatEventType, pluginCallback)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
override fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>) {
|
|
346
|
+
notifyMalware(suspiciousApps, context, pluginCallback)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
override fun raspExecutionStateChanged(event: RaspExecutionStateEvent) {
|
|
350
|
+
notifyEvent(event, pluginCallback)
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
private fun notifyEvent(
|
|
322
354
|
event: BaseRaspEvent,
|
|
323
355
|
notifyListenersCallback: CapacitorCallback
|
|
324
356
|
) {
|
|
@@ -326,7 +358,7 @@ class FreeraspPlugin : Plugin() {
|
|
|
326
358
|
notifyListenersCallback(event.channelName, params)
|
|
327
359
|
}
|
|
328
360
|
|
|
329
|
-
|
|
361
|
+
private fun notifyMalware(
|
|
330
362
|
suspiciousApps: MutableList<SuspiciousAppInfo>,
|
|
331
363
|
context: Context,
|
|
332
364
|
notifyListenersCallback: CapacitorCallback
|
|
@@ -345,21 +377,4 @@ class FreeraspPlugin : Plugin() {
|
|
|
345
377
|
}
|
|
346
378
|
}
|
|
347
379
|
}
|
|
348
|
-
|
|
349
|
-
internal class PluginListener(
|
|
350
|
-
private val context: Context,
|
|
351
|
-
private val pluginCallback: CapacitorCallback
|
|
352
|
-
) : PluginThreatListener, PluginExecutionStateListener {
|
|
353
|
-
override fun threatDetected(threatEventType: ThreatEvent) {
|
|
354
|
-
notifyEvent(threatEventType, pluginCallback)
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
override fun malwareDetected(suspiciousApps: MutableList<SuspiciousAppInfo>) {
|
|
358
|
-
notifyMalware(suspiciousApps, context, pluginCallback)
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
override fun raspExecutionStateChanged(event: RaspExecutionStateEvent) {
|
|
362
|
-
notifyEvent(event, pluginCallback)
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
380
|
}
|
|
@@ -10,112 +10,110 @@ import com.aheaditec.freerasp.events.ThreatEvent
|
|
|
10
10
|
|
|
11
11
|
internal object PluginThreatHandler {
|
|
12
12
|
|
|
13
|
-
internal val threatDispatcher = ThreatDispatcher()
|
|
14
|
-
internal val executionStateDispatcher = ExecutionStateDispatcher()
|
|
15
13
|
|
|
16
14
|
private val threatDetected = object : ThreatListener.ThreatDetected() {
|
|
17
15
|
|
|
18
16
|
override fun onRootDetected() {
|
|
19
|
-
|
|
17
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.PrivilegedAccess)
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
override fun onDebuggerDetected() {
|
|
23
|
-
|
|
21
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.Debug)
|
|
24
22
|
}
|
|
25
23
|
|
|
26
24
|
override fun onEmulatorDetected() {
|
|
27
|
-
|
|
25
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.Simulator)
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
override fun onTamperDetected() {
|
|
31
|
-
|
|
29
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.AppIntegrity)
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
override fun onUntrustedInstallationSourceDetected() {
|
|
35
|
-
|
|
33
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.UnofficialStore)
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
override fun onHookDetected() {
|
|
39
|
-
|
|
37
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.Hooks)
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
override fun onDeviceBindingDetected() {
|
|
43
|
-
|
|
41
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.DeviceBinding)
|
|
44
42
|
}
|
|
45
43
|
|
|
46
44
|
override fun onObfuscationIssuesDetected() {
|
|
47
|
-
|
|
45
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.ObfuscationIssues)
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
override fun onMalwareDetected(suspiciousAppInfos: MutableList<SuspiciousAppInfo>) {
|
|
51
|
-
|
|
49
|
+
ThreatDispatcher.dispatchMalware(suspiciousAppInfos ?: mutableListOf())
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
override fun onScreenshotDetected() {
|
|
55
|
-
|
|
53
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.Screenshot)
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
override fun onScreenRecordingDetected() {
|
|
59
|
-
|
|
57
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.ScreenRecording)
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
override fun onMultiInstanceDetected() {
|
|
63
|
-
|
|
61
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.MultiInstance)
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
override fun onUnsecureWifiDetected() {
|
|
67
|
-
|
|
65
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.UnsecureWifi)
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
override fun onTimeSpoofingDetected() {
|
|
71
|
-
|
|
69
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.TimeSpoofing)
|
|
72
70
|
}
|
|
73
71
|
|
|
74
72
|
override fun onLocationSpoofingDetected() {
|
|
75
|
-
|
|
73
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.LocationSpoofing)
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
override fun onAutomationDetected() {
|
|
79
|
-
|
|
77
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.Automation)
|
|
80
78
|
}
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
private val deviceState = object : ThreatListener.DeviceState() {
|
|
84
82
|
|
|
85
83
|
override fun onUnlockedDeviceDetected() {
|
|
86
|
-
|
|
84
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.Passcode)
|
|
87
85
|
}
|
|
88
86
|
|
|
89
87
|
override fun onHardwareBackedKeystoreNotAvailableDetected() {
|
|
90
|
-
|
|
88
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.SecureHardwareNotAvailable)
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
override fun onDeveloperModeDetected() {
|
|
94
|
-
|
|
92
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.DevMode)
|
|
95
93
|
}
|
|
96
94
|
|
|
97
95
|
override fun onADBEnabledDetected() {
|
|
98
|
-
|
|
96
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.ADBEnabled)
|
|
99
97
|
}
|
|
100
98
|
|
|
101
99
|
override fun onSystemVPNDetected() {
|
|
102
|
-
|
|
100
|
+
ThreatDispatcher.dispatchThreat(ThreatEvent.SystemVPN)
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
|
|
106
104
|
private val raspExecutionState = object : ThreatListener.RaspExecutionState() {
|
|
107
105
|
override fun onAllChecksFinished() {
|
|
108
|
-
|
|
106
|
+
ExecutionStateDispatcher.dispatch(RaspExecutionStateEvent.AllChecksFinished)
|
|
109
107
|
}
|
|
110
108
|
}
|
|
111
109
|
|
|
112
110
|
private val internalListener = ThreatListener(threatDetected, deviceState, raspExecutionState)
|
|
113
111
|
|
|
114
|
-
internal fun
|
|
112
|
+
internal fun registerSDKListener(context: Context) {
|
|
115
113
|
internalListener.registerListener(context)
|
|
116
114
|
}
|
|
117
115
|
|
|
118
|
-
internal fun
|
|
116
|
+
internal fun unregisterSDKListener(context: Context) {
|
|
119
117
|
internalListener.unregisterListener(context)
|
|
120
118
|
}
|
|
121
|
-
}
|
|
119
|
+
}
|
package/android/src/main/java/com/aheaditec/freerasp/dispatchers/ExecutionStateDispatcher.kt
CHANGED
|
@@ -3,36 +3,55 @@ package com.aheaditec.freerasp.dispatchers
|
|
|
3
3
|
import com.aheaditec.freerasp.events.RaspExecutionStateEvent
|
|
4
4
|
import com.aheaditec.freerasp.interfaces.PluginExecutionStateListener
|
|
5
5
|
|
|
6
|
-
internal
|
|
6
|
+
internal object ExecutionStateDispatcher {
|
|
7
|
+
private lateinit var listener: PluginExecutionStateListener
|
|
7
8
|
private val cache = mutableSetOf<RaspExecutionStateEvent>()
|
|
8
9
|
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
private var isAppInForeground = false
|
|
11
|
+
private var isListenerRegistered = false
|
|
12
|
+
|
|
13
|
+
fun registerListener(newListener: PluginExecutionStateListener) {
|
|
14
|
+
listener = newListener
|
|
15
|
+
isListenerRegistered = true
|
|
16
|
+
isAppInForeground = true
|
|
17
|
+
flushCache()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fun unregisterListener() {
|
|
21
|
+
isListenerRegistered = false
|
|
22
|
+
isAppInForeground = false
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fun onResume() {
|
|
26
|
+
isAppInForeground = true
|
|
27
|
+
if (isListenerRegistered) {
|
|
28
|
+
flushCache()
|
|
15
29
|
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
fun onPause() {
|
|
33
|
+
isAppInForeground = false
|
|
34
|
+
}
|
|
16
35
|
|
|
17
36
|
fun dispatch(event: RaspExecutionStateEvent) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
} else {
|
|
37
|
+
if (isAppInForeground && isListenerRegistered) {
|
|
38
|
+
listener.raspExecutionStateChanged(event)
|
|
39
|
+
} else {
|
|
40
|
+
synchronized(cache) {
|
|
23
41
|
cache.add(event)
|
|
24
|
-
null
|
|
25
42
|
}
|
|
26
43
|
}
|
|
27
|
-
checkedListener?.raspExecutionStateChanged(event)
|
|
28
44
|
}
|
|
29
45
|
|
|
30
|
-
private fun flushCache(
|
|
46
|
+
private fun flushCache() {
|
|
47
|
+
if (!isListenerRegistered || !isAppInForeground) {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
31
50
|
val events = synchronized(cache) {
|
|
32
51
|
val snapshot = cache.toSet()
|
|
33
52
|
cache.clear()
|
|
34
53
|
snapshot
|
|
35
54
|
}
|
|
36
|
-
events.forEach {
|
|
55
|
+
events.forEach { listener.raspExecutionStateChanged(it) }
|
|
37
56
|
}
|
|
38
57
|
}
|
|
@@ -4,51 +4,69 @@ import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
|
|
|
4
4
|
import com.aheaditec.freerasp.events.ThreatEvent
|
|
5
5
|
import com.aheaditec.freerasp.interfaces.PluginThreatListener
|
|
6
6
|
|
|
7
|
-
internal
|
|
7
|
+
internal object ThreatDispatcher {
|
|
8
|
+
private lateinit var listener: PluginThreatListener
|
|
8
9
|
private val threatCache = mutableSetOf<ThreatEvent>()
|
|
9
10
|
private val malwareCache = mutableSetOf<SuspiciousAppInfo>()
|
|
10
11
|
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
private var isAppInForeground = false
|
|
13
|
+
private var isListenerRegistered = false
|
|
14
|
+
|
|
15
|
+
fun registerListener(newListener: PluginThreatListener) {
|
|
16
|
+
listener = newListener
|
|
17
|
+
isListenerRegistered = true
|
|
18
|
+
isAppInForeground = true
|
|
19
|
+
flushCache()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
fun unregisterListener() {
|
|
23
|
+
isListenerRegistered = false
|
|
24
|
+
isAppInForeground = false
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fun onResume() {
|
|
28
|
+
isAppInForeground = true
|
|
29
|
+
if (isListenerRegistered) {
|
|
30
|
+
flushCache()
|
|
17
31
|
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fun onPause() {
|
|
35
|
+
isAppInForeground = false
|
|
36
|
+
}
|
|
18
37
|
|
|
19
38
|
fun dispatchThreat(event: ThreatEvent) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} else {
|
|
39
|
+
if (isAppInForeground && isListenerRegistered) {
|
|
40
|
+
listener.threatDetected(event)
|
|
41
|
+
} else {
|
|
42
|
+
synchronized(threatCache) {
|
|
25
43
|
threatCache.add(event)
|
|
26
|
-
null
|
|
27
44
|
}
|
|
28
45
|
}
|
|
29
|
-
checkedListener?.threatDetected(event)
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
fun dispatchMalware(apps: MutableList<SuspiciousAppInfo>) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
49
|
+
if (isAppInForeground && isListenerRegistered) {
|
|
50
|
+
listener.malwareDetected(apps)
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
synchronized(malwareCache) {
|
|
38
54
|
malwareCache.addAll(apps)
|
|
39
|
-
null
|
|
40
55
|
}
|
|
41
56
|
}
|
|
42
|
-
checkedListener?.malwareDetected(apps)
|
|
43
57
|
}
|
|
44
58
|
|
|
45
|
-
private fun flushCache(
|
|
59
|
+
private fun flushCache() {
|
|
60
|
+
if (!isListenerRegistered || !isAppInForeground) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
46
64
|
val threats = synchronized(threatCache) {
|
|
47
65
|
val snapshot = threatCache.toSet()
|
|
48
66
|
threatCache.clear()
|
|
49
67
|
snapshot
|
|
50
68
|
}
|
|
51
|
-
threats.forEach {
|
|
69
|
+
threats.forEach { listener.threatDetected(it) }
|
|
52
70
|
|
|
53
71
|
val malware = synchronized(malwareCache) {
|
|
54
72
|
val snapshot = malwareCache.toMutableList()
|
|
@@ -56,7 +74,7 @@ internal class ThreatDispatcher {
|
|
|
56
74
|
snapshot
|
|
57
75
|
}
|
|
58
76
|
if (malware.isNotEmpty()) {
|
|
59
|
-
|
|
77
|
+
listener.malwareDetected(malware)
|
|
60
78
|
}
|
|
61
79
|
}
|
|
62
80
|
}
|
|
@@ -3,24 +3,34 @@ import { RaspExecutionState } from '../../models/raspExecutionState';
|
|
|
3
3
|
import { onInvalidCallback } from '../methods/native';
|
|
4
4
|
import { Talsec } from '../nativeModules';
|
|
5
5
|
let eventsListener = null;
|
|
6
|
+
let executionStateChannel = null;
|
|
7
|
+
let executionStateKey = null;
|
|
6
8
|
let isInitializing = false;
|
|
9
|
+
let isMappingPrepared = false;
|
|
7
10
|
export const registerRaspExecutionStateListener = async (config) => {
|
|
8
11
|
if (isInitializing) {
|
|
9
12
|
return;
|
|
10
13
|
}
|
|
11
14
|
isInitializing = true;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
await removeRaspExecutionStateListener();
|
|
16
|
+
if (!executionStateChannel || !executionStateKey) {
|
|
17
|
+
[executionStateChannel, executionStateKey] = await getRaspExecutionStateChannelData();
|
|
15
18
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
if (!isMappingPrepared) {
|
|
20
|
+
await prepareRaspExecutionStateMapping();
|
|
21
|
+
isMappingPrepared = true;
|
|
22
|
+
}
|
|
23
|
+
if (!executionStateChannel) {
|
|
24
|
+
onInvalidCallback();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
eventsListener = await Talsec.addListener(executionStateChannel, async (event) => {
|
|
19
28
|
var _a;
|
|
20
|
-
if (
|
|
29
|
+
if (!executionStateKey) {
|
|
21
30
|
onInvalidCallback();
|
|
31
|
+
return;
|
|
22
32
|
}
|
|
23
|
-
switch (event[
|
|
33
|
+
switch (event[executionStateKey]) {
|
|
24
34
|
case RaspExecutionState.AllChecksFinished.value:
|
|
25
35
|
(_a = config.allChecksFinished) === null || _a === void 0 ? void 0 : _a.call(config);
|
|
26
36
|
break;
|
|
@@ -32,9 +42,11 @@ export const registerRaspExecutionStateListener = async (config) => {
|
|
|
32
42
|
isInitializing = false;
|
|
33
43
|
};
|
|
34
44
|
export const removeRaspExecutionStateListener = async () => {
|
|
35
|
-
if (eventsListener) {
|
|
36
|
-
|
|
37
|
-
eventsListener = null;
|
|
45
|
+
if (!eventsListener || !executionStateChannel) {
|
|
46
|
+
return;
|
|
38
47
|
}
|
|
48
|
+
await eventsListener.remove();
|
|
49
|
+
eventsListener = null;
|
|
50
|
+
await Talsec.removeListenerForEvent({ eventName: executionStateChannel });
|
|
39
51
|
};
|
|
40
52
|
//# sourceMappingURL=raspExecutionState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raspExecutionState.js","sourceRoot":"","sources":["../../../../src/api/listeners/raspExecutionState.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gCAAgC,EAAE,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AACvH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,cAAc,GAAgC,IAAI,CAAC;AACvD,IAAI,cAAc,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"raspExecutionState.js","sourceRoot":"","sources":["../../../../src/api/listeners/raspExecutionState.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gCAAgC,EAAE,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AACvH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,cAAc,GAAgC,IAAI,CAAC;AACvD,IAAI,qBAAqB,GAAkB,IAAI,CAAC;AAChD,IAAI,iBAAiB,GAAkB,IAAI,CAAC;AAE5C,IAAI,cAAc,GAAG,KAAK,CAAC;AAC3B,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAE9B,MAAM,CAAC,MAAM,kCAAkC,GAAG,KAAK,EAAE,MAAsC,EAAiB,EAAE;IAChH,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IACD,cAAc,GAAG,IAAI,CAAC;IAEtB,MAAM,gCAAgC,EAAE,CAAC;IAEzC,IAAI,CAAC,qBAAqB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjD,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,GAAG,MAAM,gCAAgC,EAAE,CAAC;IACxF,CAAC;IAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,gCAAgC,EAAE,CAAC;QACzC,iBAAiB,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,iBAAiB,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,cAAc,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,qBAAqB,EAAE,KAAK,EAAE,KAAU,EAAE,EAAE;;QACpF,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,iBAAiB,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,QAAQ,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACjC,KAAK,kBAAkB,CAAC,iBAAiB,CAAC,KAAK;gBAC7C,MAAA,MAAM,CAAC,iBAAiB,sDAAI,CAAC;gBAC7B,MAAM;YACR;gBACE,iBAAiB,EAAE,CAAC;gBACpB,MAAM;QACV,CAAC;IACH,CAAC,CAAC,CAAC;IACH,cAAc,GAAG,KAAK,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,KAAK,IAAmB,EAAE;IACxE,IAAI,CAAC,cAAc,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,MAAM,cAAc,CAAC,MAAM,EAAE,CAAC;IAC9B,cAAc,GAAG,IAAI,CAAC;IACtB,MAAM,MAAM,CAAC,sBAAsB,CAAC,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC,CAAC;AAC5E,CAAC,CAAC","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\nimport { getRaspExecutionStateChannelData, prepareRaspExecutionStateMapping } from '../../channels/raspExecutionState';\nimport { RaspExecutionState } from '../../models/raspExecutionState';\nimport type { RaspExecutionStateEventActions } from '../../types/types';\nimport { onInvalidCallback } from '../methods/native';\nimport { Talsec } from '../nativeModules';\n\nlet eventsListener: PluginListenerHandle | null = null;\nlet executionStateChannel: string | null = null;\nlet executionStateKey: string | null = null;\n\nlet isInitializing = false;\nlet isMappingPrepared = false;\n\nexport const registerRaspExecutionStateListener = async (config: RaspExecutionStateEventActions): Promise<void> => {\n if (isInitializing) {\n return;\n }\n isInitializing = true;\n\n await removeRaspExecutionStateListener();\n\n if (!executionStateChannel || !executionStateKey) {\n [executionStateChannel, executionStateKey] = await getRaspExecutionStateChannelData();\n }\n\n if (!isMappingPrepared) {\n await prepareRaspExecutionStateMapping();\n isMappingPrepared = true;\n }\n\n if (!executionStateChannel) {\n onInvalidCallback();\n return;\n }\n\n eventsListener = await Talsec.addListener(executionStateChannel, async (event: any) => {\n if (!executionStateKey) {\n onInvalidCallback();\n return;\n }\n\n switch (event[executionStateKey]) {\n case RaspExecutionState.AllChecksFinished.value:\n config.allChecksFinished?.();\n break;\n default:\n onInvalidCallback();\n break;\n }\n });\n isInitializing = false;\n};\n\nexport const removeRaspExecutionStateListener = async (): Promise<void> => {\n if (!eventsListener || !executionStateChannel) {\n return;\n }\n await eventsListener.remove();\n eventsListener = null;\n await Talsec.removeListenerForEvent({ eventName: executionStateChannel });\n};\n"]}
|