mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-17 15:08:28 +00:00
Update SuRequest handler
This commit is contained in:
parent
f191db2fe0
commit
8ffbffddb3
@ -13,12 +13,11 @@ import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
|||||||
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
import com.topjohnwu.magisk.core.model.MagiskPolicy
|
||||||
import com.topjohnwu.magisk.core.model.toPolicy
|
import com.topjohnwu.magisk.core.model.toPolicy
|
||||||
import com.topjohnwu.magisk.extensions.now
|
import com.topjohnwu.magisk.extensions.now
|
||||||
import com.topjohnwu.superuser.Shell
|
import kotlinx.coroutines.*
|
||||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.util.concurrent.Callable
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import java.util.concurrent.TimeUnit.SECONDS
|
||||||
|
|
||||||
abstract class SuRequestHandler(
|
abstract class SuRequestHandler(
|
||||||
private val packageManager: PackageManager,
|
private val packageManager: PackageManager,
|
||||||
@ -33,35 +32,11 @@ abstract class SuRequestHandler(
|
|||||||
|
|
||||||
abstract fun onStart()
|
abstract fun onStart()
|
||||||
|
|
||||||
fun start(intent: Intent): Boolean {
|
suspend fun start(intent: Intent): Boolean {
|
||||||
val name = intent.getStringExtra("socket") ?: return false
|
val name = intent.getStringExtra("socket") ?: return false
|
||||||
|
|
||||||
try {
|
if (!init(name))
|
||||||
if (Const.Version.atLeastCanary()) {
|
|
||||||
val server = LocalServerSocket(name)
|
|
||||||
val futureSocket = Shell.EXECUTOR.submit(Callable { server.accept() })
|
|
||||||
try {
|
|
||||||
socket = futureSocket.get(1, TimeUnit.SECONDS)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
// Timeout or any IO errors
|
|
||||||
throw e
|
|
||||||
} finally {
|
|
||||||
server.close()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
socket = LocalSocket()
|
|
||||||
socket.connect(LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT))
|
|
||||||
}
|
|
||||||
output = DataOutputStream(BufferedOutputStream(socket.outputStream))
|
|
||||||
input = DataInputStream(BufferedInputStream(socket.inputStream))
|
|
||||||
val map = Shell.EXECUTOR.submit(Callable { readRequest() })
|
|
||||||
.runCatching { get(1, TimeUnit.SECONDS) }.getOrNull() ?: return false
|
|
||||||
val uid = map["uid"]?.toIntOrNull() ?: return false
|
|
||||||
policy = uid.toPolicy(packageManager)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.e(e)
|
|
||||||
return false
|
return false
|
||||||
}
|
|
||||||
|
|
||||||
// Never allow com.topjohnwu.magisk (could be malware)
|
// Never allow com.topjohnwu.magisk (could be malware)
|
||||||
if (policy.packageName == BuildConfig.APPLICATION_ID)
|
if (policy.packageName == BuildConfig.APPLICATION_ID)
|
||||||
@ -77,10 +52,48 @@ abstract class SuRequestHandler(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UiThreadHandler.run { onStart() }
|
|
||||||
|
onStart()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun <T> Deferred<T>.timedAwait() : T? {
|
||||||
|
return withTimeoutOrNull(SECONDS.toMillis(1)) {
|
||||||
|
await()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SocketError : IOException()
|
||||||
|
|
||||||
|
private suspend fun init(name: String) = withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
if (Const.Version.atLeastCanary()) {
|
||||||
|
LocalServerSocket(name).use {
|
||||||
|
socket = async { it.accept() }.timedAwait() ?: throw SocketError()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
socket = LocalSocket()
|
||||||
|
socket.connect(LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT))
|
||||||
|
}
|
||||||
|
output = DataOutputStream(BufferedOutputStream(socket.outputStream))
|
||||||
|
input = DataInputStream(BufferedInputStream(socket.inputStream))
|
||||||
|
val map = async { readRequest() }.timedAwait() ?: throw SocketError()
|
||||||
|
val uid = map["uid"]?.toIntOrNull() ?: throw SocketError()
|
||||||
|
policy = uid.toPolicy(packageManager)
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
when (e) {
|
||||||
|
is IOException, is PackageManager.NameNotFoundException -> {
|
||||||
|
Timber.e(e)
|
||||||
|
if (::socket.isInitialized)
|
||||||
|
socket.close()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
else -> throw e // Unexpected error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun respond(action: Int, time: Int) {
|
fun respond(action: Int, time: Int) {
|
||||||
val until = if (time > 0)
|
val until = if (time > 0)
|
||||||
TimeUnit.MILLISECONDS.toSeconds(now) + TimeUnit.MINUTES.toSeconds(time.toLong())
|
TimeUnit.MILLISECONDS.toSeconds(now) + TimeUnit.MINUTES.toSeconds(time.toLong())
|
||||||
@ -91,7 +104,7 @@ abstract class SuRequestHandler(
|
|||||||
policy.until = until
|
policy.until = until
|
||||||
policy.uid = policy.uid % 100000 + Const.USER_ID * 100000
|
policy.uid = policy.uid % 100000 + Const.USER_ID * 100000
|
||||||
|
|
||||||
Shell.EXECUTOR.submit {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
output.writeInt(policy.policy)
|
output.writeInt(policy.policy)
|
||||||
output.flush()
|
output.flush()
|
||||||
|
@ -12,12 +12,10 @@ import com.topjohnwu.magisk.R
|
|||||||
import com.topjohnwu.magisk.core.su.SuCallbackHandler
|
import com.topjohnwu.magisk.core.su.SuCallbackHandler
|
||||||
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
|
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
|
||||||
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
||||||
import com.topjohnwu.magisk.extensions.subscribeK
|
|
||||||
import com.topjohnwu.magisk.model.events.DieEvent
|
import com.topjohnwu.magisk.model.events.DieEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||||
import io.reactivex.Single
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityRequestBinding>() {
|
open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityRequestBinding>() {
|
||||||
@ -39,11 +37,7 @@ open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityReques
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
fun showRequest() {
|
fun showRequest() {
|
||||||
Single.fromCallable {
|
viewModel.handleRequest(intent)
|
||||||
viewModel.handleRequest(intent)
|
|
||||||
}.subscribeK {
|
|
||||||
if (!it) finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runHandler(action: String?) {
|
fun runHandler(action: String?) {
|
||||||
|
@ -6,6 +6,7 @@ import android.content.pm.PackageManager
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
||||||
@ -18,6 +19,7 @@ import com.topjohnwu.magisk.model.events.DieEvent
|
|||||||
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import me.tatarka.bindingcollectionadapter2.BindingListViewAdapter
|
import me.tatarka.bindingcollectionadapter2.BindingListViewAdapter
|
||||||
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
||||||
import java.util.concurrent.TimeUnit.SECONDS
|
import java.util.concurrent.TimeUnit.SECONDS
|
||||||
@ -72,8 +74,11 @@ class SuRequestViewModel(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleRequest(intent: Intent): Boolean {
|
fun handleRequest(intent: Intent) {
|
||||||
return handler.start(intent)
|
viewModelScope.launch {
|
||||||
|
if (!handler.start(intent))
|
||||||
|
DieEvent().publish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class Handler : SuRequestHandler(pm, policyDB) {
|
private inner class Handler : SuRequestHandler(pm, policyDB) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user