Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
SirionRazzer committed Aug 27, 2024
1 parent 816c1e7 commit 5d25048
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 4 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ android {
namespace("com.aheaditec.freerasp")
}

compileSdkVersion 33
compileSdkVersion 34

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand Down
4 changes: 3 additions & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aheaditec.freerasp">
package="com.aheaditec.freerasp">

<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
</manifest>
6 changes: 6 additions & 0 deletions android/src/main/kotlin/com/aheaditec/freerasp/CaptureType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.aheaditec.freerasp

internal sealed class CaptureType(val value: Int) {
object Unknown : CaptureType(1115787534)

}
2 changes: 2 additions & 0 deletions android/src/main/kotlin/com/aheaditec/freerasp/Threat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ internal sealed class Threat(val value: Int) {
object SystemVPN : Threat(659382561)

object DevMode : Threat(45291047)

object ScreenCapture : Threat(669512294)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.aheaditec.freerasp.handlers

import android.content.Context
import com.aheaditec.freerasp.CaptureType
import com.aheaditec.freerasp.runResultCatching
import com.aheaditec.freerasp.utils.Utils
import io.flutter.Log
Expand Down Expand Up @@ -38,6 +39,7 @@ internal class MethodCallHandler : MethodCallHandler {
it.setMethodCallHandler(this)
}

TalsecThreatHandler.attachMethod(sink)
this.context = context
}

Expand All @@ -47,6 +49,7 @@ internal class MethodCallHandler : MethodCallHandler {
fun destroyMethodChannel() {
methodChannel?.setMethodCallHandler(null)
methodChannel = null
TalsecThreatHandler.detachMethod()
this.context = null
}

Expand Down Expand Up @@ -79,4 +82,17 @@ internal class MethodCallHandler : MethodCallHandler {
result.success(null)
}
}

private val sink = object : MethodSink {
override fun onScreenCaptureDetected(captureType: CaptureType) {
methodChannel?.invokeMethod(
"onScreenCaptureDetected",
mapOf(Pair("type", captureType.value))
)
}
}

internal interface MethodSink {
fun onScreenCaptureDetected(captureType: CaptureType)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package com.aheaditec.freerasp.handlers

import android.app.Activity
import android.content.Context
import android.os.Build
import android.view.WindowManager
import com.aheaditec.freerasp.CaptureType
import com.aheaditec.freerasp.Threat
import com.aheaditec.talsec_security.security.api.Talsec
import com.aheaditec.talsec_security.security.api.TalsecConfig
Expand All @@ -14,6 +16,7 @@ import io.flutter.plugin.common.EventChannel.EventSink
*/
internal object TalsecThreatHandler {
private var eventSink: EventSink? = null
private var methodSink: MethodCallHandler.MethodSink? = null
private var isListening = false
private var enableScreenCaptureGuard = false

Expand Down Expand Up @@ -124,6 +127,10 @@ internal object TalsecThreatHandler {
flushThreatCache(eventSink)
}

internal fun attachMethod(methodSink: MethodCallHandler.MethodSink) {
this.methodSink = methodSink
}

/**
* Called when a listener unsubscribes from the event channel.
*/
Expand All @@ -132,10 +139,20 @@ internal object TalsecThreatHandler {
PluginThreatHandler.listener = null
}

internal fun detachMethod() {
methodSink = null
}

internal fun guardActivity(activity: Activity?) {
if (enableScreenCaptureGuard) {
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
}

if (Build.VERSION.SDK_INT >= 34) {
Activity.ScreenCaptureCallback {
methodSink?.onScreenCaptureDetected(CaptureType.Unknown)
}
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions lib/src/models/android_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class AndroidConfig {
required this.packageName,
required this.signingCertHashes,
this.supportedStores = const <String>[],
this.enableScreenCaptureGuard = false,
}) {
ConfigVerifier.verifyAndroid(this);
}
Expand All @@ -30,4 +31,6 @@ class AndroidConfig {

/// List of supported sources where application can be installed from.
final List<String> supportedStores;

final bool enableScreenCaptureGuard;
}
3 changes: 3 additions & 0 deletions lib/src/models/android_config.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions lib/src/models/talsec_config.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions lib/src/talsec.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:ffi';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
Expand Down Expand Up @@ -180,6 +181,14 @@ class Talsec {
break;
}
});

methodChannel.setMethodCallHandler((call) {
if (call.method == "onScreenCaptureDetected") {
final value = call.arguments as int;

callback.onScreenCaptureDetected?.call(CaptureType.fromInt(value));
}
});
}

/// Removes instance of latest [ThreatCallback]. Also cancels
Expand Down
21 changes: 21 additions & 0 deletions lib/src/threat_callback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ThreatCallback {
this.onSecureHardwareNotAvailable,
this.onSystemVPN,
this.onDevMode,
this.onScreenCaptureDetected
});

/// This method is called when a threat related dynamic hooking (e.g. Frida)
Expand Down Expand Up @@ -80,4 +81,24 @@ class ThreatCallback {

/// This method is called whe the device has Developer mode enabled
final VoidCallback? onDevMode;

void Function(CaptureType type)? onScreenCaptureDetected;
}

enum CaptureType {
unknown(1115787534),
screenshot(0),
recording(0),
mirroring(0);

final int value;

const CaptureType(this.value);

static CaptureType fromInt(int value) {
switch (value) {
case 1115787534: return CaptureType.unknown;
default: return CaptureType.unknown;
}
}
}

0 comments on commit 5d25048

Please sign in to comment.