Misc BSSID fixes

This commit is contained in:
Mygod
2020-06-14 07:56:08 +08:00
parent d98333d35e
commit bf79573b27
6 changed files with 113 additions and 96 deletions

View File

@@ -152,6 +152,7 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded
* (since API 28) [`Lcom/android/internal/R$integer;->config_wifi_framework_soft_ap_timeout_delay:I,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#245007) * (since API 28) [`Lcom/android/internal/R$integer;->config_wifi_framework_soft_ap_timeout_delay:I,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#245007)
* [`Lcom/android/internal/R$string;->config_ethernet_iface_regex:I,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#245611) * [`Lcom/android/internal/R$string;->config_ethernet_iface_regex:I,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#245611)
* (since API 27) `Lcom/android/server/connectivity/tethering/OffloadHardwareInterface;->DEFAULT_TETHER_OFFLOAD_DISABLED:I` * (since API 27) `Lcom/android/server/connectivity/tethering/OffloadHardwareInterface;->DEFAULT_TETHER_OFFLOAD_DISABLED:I`
* (since API 29) `Lcom/android/server/wifi/p2p/WifiP2pServiceImpl;->ANONYMIZED_DEVICE_ADDRESS:Ljava/lang/String;`
* (since API 30) `Lcom/android/server/SystemServer;->TETHERING_CONNECTOR_CLASS:Ljava/lang/String;` * (since API 30) `Lcom/android/server/SystemServer;->TETHERING_CONNECTOR_CLASS:Ljava/lang/String;`
* (since API 26) [`Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#333141) * (since API 26) [`Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#333141)
* (since API 26) [`Ljava/lang/invoke/MethodHandles$Lookup;->ALL_MODES:I,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#333142) * (since API 26) [`Ljava/lang/invoke/MethodHandles$Lookup;->ALL_MODES:I,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#333142)

View File

@@ -32,6 +32,8 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MANAGE_USB" <uses-permission android:name="android.permission.MANAGE_USB"
tools:ignore="ProtectedPermissions"/> tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.NETWORK_SETTINGS" <uses-permission android:name="android.permission.NETWORK_SETTINGS"

View File

@@ -18,6 +18,7 @@ import androidx.core.content.getSystemService
import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.net.MacAddressCompat import be.mygod.vpnhotspot.net.MacAddressCompat
import be.mygod.vpnhotspot.net.monitor.TetherTimeoutMonitor import be.mygod.vpnhotspot.net.monitor.TetherTimeoutMonitor
import be.mygod.vpnhotspot.net.wifi.P2pSupplicantConfiguration
import be.mygod.vpnhotspot.net.wifi.SoftApConfigurationCompat import be.mygod.vpnhotspot.net.wifi.SoftApConfigurationCompat
import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper
import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.deletePersistentGroup import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.deletePersistentGroup
@@ -28,7 +29,6 @@ import be.mygod.vpnhotspot.util.*
import be.mygod.vpnhotspot.widget.SmartSnackbar import be.mygod.vpnhotspot.widget.SmartSnackbar
import kotlinx.coroutines.* import kotlinx.coroutines.*
import timber.log.Timber import timber.log.Timber
import java.lang.IllegalArgumentException
import java.lang.reflect.InvocationTargetException import java.lang.reflect.InvocationTargetException
import java.net.NetworkInterface import java.net.NetworkInterface
@@ -75,7 +75,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
(!hasP2pValidateName || app.pref.getBoolean(KEY_SAFE_MODE, true)) (!hasP2pValidateName || app.pref.getBoolean(KEY_SAFE_MODE, true))
var lastMac: String? var lastMac: String?
get() = app.pref.getString(KEY_LAST_MAC, null) get() = app.pref.getString(KEY_LAST_MAC, null)
private set(value) = app.pref.edit { putString(KEY_LAST_MAC, value) } set(value) = app.pref.edit { putString(KEY_LAST_MAC, value) }
var networkName: String? var networkName: String?
get() = app.pref.getString(KEY_NETWORK_NAME, null) get() = app.pref.getString(KEY_NETWORK_NAME, null)
@@ -122,7 +122,6 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
} }
} }
val groupChanged = StickyEvent1 { group } val groupChanged = StickyEvent1 { group }
var thisDevice: WifiP2pDevice? = null
fun startWps(pin: String? = null) { fun startWps(pin: String? = null) {
val channel = channel val channel = channel
@@ -164,8 +163,13 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
} }
private val deviceListener = broadcastReceiver { _, intent -> private val deviceListener = broadcastReceiver { _, intent ->
when (intent.action) { when (intent.action) {
WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION -> binder.thisDevice = WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION -> {
intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE) val device = intent.getParcelableExtra<WifiP2pDevice>(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)
val address = MacAddressCompat.fromString(device?.deviceAddress ?: return@broadcastReceiver)
if (Build.VERSION.SDK_INT < 29 || address != MacAddressCompat.ANY_ADDRESS) {
lastMac = device.deviceAddress
}
}
WifiP2pManagerHelper.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION -> if (!safeMode) onPersistentGroupsChanged() WifiP2pManagerHelper.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION -> if (!safeMode) onPersistentGroupsChanged()
} }
} }
@@ -242,13 +246,25 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
} }
@SuppressLint("NewApi") // networkId is available since Android 4.2 @SuppressLint("NewApi") // networkId is available since Android 4.2
private fun onPersistentGroupsChanged() { private fun onPersistentGroupsChanged() = launch {
val channel = channel ?: return val ownerAddress = lastMac?.let(MacAddressCompat.Companion::fromString) ?: withContext(Dispatchers.Default) {
val device = binder.thisDevice ?: return
try { try {
p2pManager.requestPersistentGroupInfo(channel) { P2pSupplicantConfiguration().bssid
if (it.isNotEmpty()) persistentSupported = true } catch (e: RuntimeException) {
val ownedGroups = it.filter { it.isGroupOwner && it.owner.deviceAddress == device.deviceAddress } Timber.d(e)
null
}
} ?: return@launch
val channel = channel ?: return@launch
try {
p2pManager.requestPersistentGroupInfo(channel) { groups ->
if (groups.isNotEmpty()) persistentSupported = true
val ownedGroups = groups.filter {
if (!it.isGroupOwner) return@filter false
val address = MacAddressCompat.fromString(it.owner.deviceAddress)
// WifiP2pServiceImpl only removes self address
Build.VERSION.SDK_INT >= 29 && address == MacAddressCompat.ANY_ADDRESS || address == ownerAddress
}
val main = ownedGroups.minBy { it.networkId } val main = ownedGroups.minBy { it.networkId }
// do not replace current group if it's better // do not replace current group if it's better
if (binder.group?.passphrase == null) binder.group = main if (binder.group?.passphrase == null) binder.group = main

View File

@@ -199,8 +199,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
val group = binder?.group val group = binder?.group
if (group != null) try { if (group != null) try {
val config = withContext(Dispatchers.Default) { val config = withContext(Dispatchers.Default) {
P2pSupplicantConfiguration(group, P2pSupplicantConfiguration(group, RepeaterService.lastMac)
binder?.thisDevice?.deviceAddress, RepeaterService.deviceAddress?.toString())
} }
holder.config = config holder.config = config
return SoftApConfigurationCompat.empty().apply { return SoftApConfigurationCompat.empty().apply {

View File

@@ -18,7 +18,7 @@ inline class MacAddressCompat(val addr: Long) {
* @hide * @hide
*/ */
val ALL_ZEROS_ADDRESS = MacAddressCompat(0) val ALL_ZEROS_ADDRESS = MacAddressCompat(0)
val ANY_ADDRESS = MacAddressCompat(2L shl 40) val ANY_ADDRESS = MacAddressCompat(2)
fun bytesToString(addr: ByteArray): String { fun bytesToString(addr: ByteArray): String {
require(addr.size == ETHER_ADDR_LEN) { addr.contentToString() + " was not a valid MAC address" } require(addr.size == ETHER_ADDR_LEN) { addr.contentToString() + " was not a valid MAC address" }

View File

@@ -14,7 +14,7 @@ import java.io.File
* https://android.googlesource.com/platform/external/wpa_supplicant_8/+/d2986c2/wpa_supplicant/config.c#488 * https://android.googlesource.com/platform/external/wpa_supplicant_8/+/d2986c2/wpa_supplicant/config.c#488
* https://android.googlesource.com/platform/external/wpa_supplicant_8/+/6fa46df/wpa_supplicant/config_file.c#182 * https://android.googlesource.com/platform/external/wpa_supplicant_8/+/6fa46df/wpa_supplicant/config_file.c#182
*/ */
class P2pSupplicantConfiguration(private val group: WifiP2pGroup?, vararg ownerAddresses: String?) { class P2pSupplicantConfiguration(private val group: WifiP2pGroup? = null, ownerAddress: String? = null) {
companion object { companion object {
private const val TAG = "P2pSupplicantConfiguration" private const val TAG = "P2pSupplicantConfiguration"
private const val CONF_PATH_TREBLE = "/data/vendor/wifi/wpa/p2p_supplicant.conf" private const val CONF_PATH_TREBLE = "/data/vendor/wifi/wpa/p2p_supplicant.conf"
@@ -49,8 +49,7 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup?, vararg ownerA
private data class Content(val lines: ArrayList<Any>, var target: NetworkBlock, var persistentMacLine: Int?, private data class Content(val lines: ArrayList<Any>, var target: NetworkBlock, var persistentMacLine: Int?,
var legacy: Boolean) var legacy: Boolean)
private val content by lazy { private val content = RootSession.use {
RootSession.use {
val result = ArrayList<Any>() val result = ArrayList<Any>()
var target: NetworkBlock? = null var target: NetworkBlock? = null
var persistentMacLine: Int? = null var persistentMacLine: Int? = null
@@ -59,8 +58,7 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup?, vararg ownerA
RootSession.checkOutput(command, shell, false, false) RootSession.checkOutput(command, shell, false, false)
val parser = Parser(shell.out) val parser = Parser(shell.out)
try { try {
var bssids = (listOf(group?.owner?.deviceAddress, RepeaterService.lastMac) + ownerAddresses) var bssids = listOfNotNull(group?.owner?.deviceAddress, ownerAddress)
.filterNotNull()
.distinct() .distinct()
.filter { .filter {
try { try {
@@ -130,17 +128,18 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup?, vararg ownerA
if (target == null) target = this if (target == null) target = this
}) })
} }
Content(result, target!!, persistentMacLine, shell.err.isNotEmpty()) Content(result, target!!.apply {
RepeaterService.lastMac = bssid!!
}, persistentMacLine, shell.err.isNotEmpty())
} catch (e: RuntimeException) { } catch (e: RuntimeException) {
FirebaseCrashlytics.getInstance().apply { FirebaseCrashlytics.getInstance().apply {
setCustomKey(TAG, parser.lines.joinToString("\n")) setCustomKey(TAG, parser.lines.joinToString("\n"))
setCustomKey("$TAG.ownerAddresses", ownerAddresses.joinToString()) setCustomKey("$TAG.ownerAddress", ownerAddress.toString())
setCustomKey("$TAG.p2pGroup", group.toString()) setCustomKey("$TAG.p2pGroup", group.toString())
} }
throw e throw e
} }
} }
}
val psk = group?.passphrase ?: content.target.psk!! val psk = group?.passphrase ?: content.target.psk!!
val bssid = MacAddressCompat.fromString(content.target.bssid!!) val bssid = MacAddressCompat.fromString(content.target.bssid!!)