Commit ffec64d2 authored by Viktor De Pasquale's avatar Viktor De Pasquale

Added safetynet to the rewritten home fragment

parent f3327461
...@@ -13,3 +13,5 @@ class MagiskChangelogEvent : ViewEvent() ...@@ -13,3 +13,5 @@ class MagiskChangelogEvent : ViewEvent()
class UninstallEvent : ViewEvent() class UninstallEvent : ViewEvent()
class EnvFixEvent : ViewEvent() class EnvFixEvent : ViewEvent()
class UpdateSafetyNetEvent : ViewEvent()
...@@ -8,6 +8,7 @@ import com.topjohnwu.magisk.model.observer.Observer ...@@ -8,6 +8,7 @@ import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.tasks.CheckUpdates import com.topjohnwu.magisk.tasks.CheckUpdates
import com.topjohnwu.magisk.ui.base.MagiskViewModel import com.topjohnwu.magisk.ui.base.MagiskViewModel
import com.topjohnwu.magisk.utils.Event import com.topjohnwu.magisk.utils.Event
import com.topjohnwu.magisk.utils.ISafetyNetHelper
import com.topjohnwu.magisk.utils.toggle import com.topjohnwu.magisk.utils.toggle
import com.topjohnwu.net.Networking import com.topjohnwu.net.Networking
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
...@@ -66,6 +67,21 @@ class HomeViewModel( ...@@ -66,6 +67,21 @@ class HomeViewModel(
"" ""
} }
val safetyNetTitle = KObservableField(resources.getString(R.string.safetyNet_check_text))
val ctsState = KObservableField(SafetyNetState.IDLE)
val basicIntegrityState = KObservableField(SafetyNetState.IDLE)
val safetyNetState = Observer(ctsState, basicIntegrityState) {
val cts = ctsState.value
val basic = basicIntegrityState.value
val states = listOf(cts, basic)
when {
states.any { it == SafetyNetState.LOADING } -> State.LOADING
states.any { it == SafetyNetState.IDLE } -> State.LOADING
else -> State.LOADED
}
}
val hasRoot = KObservableField(false) val hasRoot = KObservableField(false)
private var shownDialog = false private var shownDialog = false
...@@ -103,8 +119,46 @@ class HomeViewModel( ...@@ -103,8 +119,46 @@ class HomeViewModel(
MagiskItem.MAGISK -> MagiskChangelogEvent().publish() MagiskItem.MAGISK -> MagiskChangelogEvent().publish()
} }
fun safetyNetPressed() {
ctsState.value = SafetyNetState.LOADING
basicIntegrityState.value = SafetyNetState.LOADING
safetyNetTitle.value = resources.getString(R.string.checking_safetyNet_status)
UpdateSafetyNetEvent().publish()
}
fun finishSafetyNetCheck(response: Int) = when {
response and 0x0F == 0 -> {
val hasCtsPassed = response and ISafetyNetHelper.CTS_PASS != 0
val hasBasicIntegrityPassed = response and ISafetyNetHelper.BASIC_PASS != 0
safetyNetTitle.value = resources.getString(R.string.safetyNet_check_success)
ctsState.value = if (hasCtsPassed) {
SafetyNetState.PASS
} else {
SafetyNetState.FAILED
}
basicIntegrityState.value = if (hasBasicIntegrityPassed) {
SafetyNetState.PASS
} else {
SafetyNetState.FAILED
}
}
response == -2 -> {
ctsState.value = SafetyNetState.IDLE
basicIntegrityState.value = SafetyNetState.IDLE
}
else -> {
ctsState.value = SafetyNetState.IDLE
basicIntegrityState.value = SafetyNetState.IDLE
val errorString = when (response) {
ISafetyNetHelper.RESPONSE_ERR -> R.string.safetyNet_res_invalid
else -> R.string.safetyNet_api_error
}
safetyNetTitle.value = resources.getString(errorString)
}
}
fun refresh() { fun refresh() {
shownDialog = false
state = State.LOADING state = State.LOADING
magiskState.value = MagiskState.LOADING magiskState.value = MagiskState.LOADING
managerState.value = MagiskState.LOADING managerState.value = MagiskState.LOADING
...@@ -155,7 +209,8 @@ class HomeViewModel( ...@@ -155,7 +209,8 @@ class HomeViewModel(
} }
private fun ensureEnv() { private fun ensureEnv() {
val invalidStates = listOf(MagiskState.NOT_INSTALLED, MagiskState.NO_ROOT, MagiskState.LOADING) val invalidStates =
listOf(MagiskState.NOT_INSTALLED, MagiskState.NO_ROOT, MagiskState.LOADING)
// Don't bother checking env when magisk is not installed, loading or already has been shown // Don't bother checking env when magisk is not installed, loading or already has been shown
if (invalidStates.any { it == magiskState.value } || shownDialog) return if (invalidStates.any { it == magiskState.value } || shownDialog) return
......
package com.topjohnwu.magisk.ui.home
enum class SafetyNetState {
LOADING, PASS, FAILED, IDLE
}
\ No newline at end of file
...@@ -9,12 +9,7 @@ import android.view.ViewGroup; ...@@ -9,12 +9,7 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.StringRes;
import androidx.cardview.widget.CardView;
import butterknife.BindColor;
import butterknife.BindView;
import butterknife.OnClick;
import butterknife.Unbinder;
import com.topjohnwu.magisk.App; import com.topjohnwu.magisk.App;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
...@@ -22,13 +17,20 @@ import com.topjohnwu.magisk.utils.ISafetyNetHelper; ...@@ -22,13 +17,20 @@ import com.topjohnwu.magisk.utils.ISafetyNetHelper;
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog; import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog;
import com.topjohnwu.net.Networking; import com.topjohnwu.net.Networking;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import dalvik.system.DexClassLoader;
import java.io.File; import java.io.File;
import androidx.annotation.StringRes;
import androidx.cardview.widget.CardView;
import butterknife.BindColor;
import butterknife.BindView;
import butterknife.OnClick;
import butterknife.Unbinder;
import dalvik.system.DexClassLoader;
public class SafetyNet implements ISafetyNetHelper.Callback { public class SafetyNet implements ISafetyNetHelper.Callback {
private static final File EXT_APK = public static final File EXT_APK =
new File(App.self.getFilesDir().getParent() + "/snet", "snet.apk"); new File(App.self.getFilesDir().getParent() + "/snet", "snet.apk");
/*@BindView(R.id.safetyNet_card) */ CardView safetyNetCard; /*@BindView(R.id.safetyNet_card) */ CardView safetyNetCard;
...@@ -45,7 +47,7 @@ public class SafetyNet implements ISafetyNetHelper.Callback { ...@@ -45,7 +47,7 @@ public class SafetyNet implements ISafetyNetHelper.Callback {
@BindColor(R.color.green500) int colorOK; @BindColor(R.color.green500) int colorOK;
public Unbinder unbinder; public Unbinder unbinder;
private ExpandableViewHolder expandable; private final ExpandableViewHolder expandable;
public SafetyNet(View v) { public SafetyNet(View v) {
unbinder = new SafetyNet_ViewBinding(this, v); unbinder = new SafetyNet_ViewBinding(this, v);
...@@ -55,27 +57,16 @@ public class SafetyNet implements ISafetyNetHelper.Callback { ...@@ -55,27 +57,16 @@ public class SafetyNet implements ISafetyNetHelper.Callback {
View.VISIBLE : View.GONE); View.VISIBLE : View.GONE);
} }
@OnClick(R.id.safetyNet_refresh) public static void dyRun(Activity activity, Object callback) throws Exception {
void safetyNet(View v) { DexClassLoader loader = new DexClassLoader(EXT_APK.getPath(), EXT_APK.getParent(),
Runnable task = () -> { null, ISafetyNetHelper.class.getClassLoader());
safetyNetProgress.setVisibility(View.VISIBLE); Class<?> clazz = loader.loadClass("com.topjohnwu.snet.Snet");
safetyNetRefreshIcon.setVisibility(View.INVISIBLE); ISafetyNetHelper helper = (ISafetyNetHelper) clazz.getMethod("newHelper",
safetyNetStatusText.setText(R.string.checking_safetyNet_status); Class.class, String.class, Activity.class, Object.class)
check((Activity) v.getContext()); .invoke(null, ISafetyNetHelper.class, EXT_APK.getPath(), activity, callback);
expandable.collapse(); if (helper.getVersion() < Const.SNET_EXT_VER)
}; throw new Exception();
if (!SafetyNet.EXT_APK.exists()) { helper.attest();
// Show dialog
new CustomAlertDialog((Activity) v.getContext())
.setTitle(R.string.proprietary_title)
.setMessage(R.string.proprietary_notice)
.setCancelable(true)
.setPositiveButton(R.string.yes, (d, i) -> task.run())
.setNegativeButton(R.string.no_thanks, null)
.show();
} else {
task.run();
}
} }
public void reset() { public void reset() {
...@@ -117,27 +108,38 @@ public class SafetyNet implements ISafetyNetHelper.Callback { ...@@ -117,27 +108,38 @@ public class SafetyNet implements ISafetyNetHelper.Callback {
} }
} }
private void dyRun(Activity activity) throws Exception { @OnClick(R.id.safetyNet_refresh)
DexClassLoader loader = new DexClassLoader(EXT_APK.getPath(), EXT_APK.getParent(), void safetyNet(View v) {
null, ISafetyNetHelper.class.getClassLoader()); Runnable task = () -> {
Class<?> clazz = loader.loadClass("com.topjohnwu.snet.Snet"); safetyNetProgress.setVisibility(View.VISIBLE);
ISafetyNetHelper helper = (ISafetyNetHelper) clazz.getMethod("newHelper", safetyNetRefreshIcon.setVisibility(View.INVISIBLE);
Class.class, String.class, Activity.class, Object.class) safetyNetStatusText.setText(R.string.checking_safetyNet_status);
.invoke(null, ISafetyNetHelper.class, EXT_APK.getPath(), activity, this); check((Activity) v.getContext());
if (helper.getVersion() < Const.SNET_EXT_VER) expandable.collapse();
throw new Exception(); };
helper.attest(); if (!EXT_APK.exists()) {
// Show dialog
new CustomAlertDialog((Activity) v.getContext())
.setTitle(R.string.proprietary_title)
.setMessage(R.string.proprietary_notice)
.setCancelable(true)
.setPositiveButton(R.string.yes, (d, i) -> task.run())
.setNegativeButton(R.string.no_thanks, null)
.show();
} else {
task.run();
}
} }
private void check(Activity activity) { private void check(Activity activity) {
try { try {
dyRun(activity); dyRun(activity, this);
} catch (Exception ignored) { } catch (Exception ignored) {
Shell.sh("rm -rf " + EXT_APK.getParent()).exec(); Shell.sh("rm -rf " + EXT_APK.getParent()).exec();
EXT_APK.getParentFile().mkdir(); EXT_APK.getParentFile().mkdir();
Networking.get(Const.Url.SNET_URL).getAsFile(EXT_APK, f -> { Networking.get(Const.Url.SNET_URL).getAsFile(EXT_APK, f -> {
try { try {
dyRun(activity); dyRun(activity, this);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
onResponse(-1); onResponse(-1);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment