Handle multiple groups and other formats of psk
This should address #17.
This commit is contained in:
@@ -245,8 +245,8 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL
|
|||||||
val conf = P2pSupplicantConfiguration()
|
val conf = P2pSupplicantConfiguration()
|
||||||
wifi.SSID = ssid
|
wifi.SSID = ssid
|
||||||
wifi.preSharedKey = binder.password
|
wifi.preSharedKey = binder.password
|
||||||
if (wifi.preSharedKey == null || wifi.preSharedKey.length < 8) wifi.preSharedKey = conf.readPsk()
|
if (wifi.preSharedKey == null) wifi.preSharedKey = conf.readPsk()
|
||||||
if (wifi.preSharedKey != null && wifi.preSharedKey.length >= 8) {
|
if (wifi.preSharedKey != null) {
|
||||||
var dialog: WifiP2pDialog? = null
|
var dialog: WifiP2pDialog? = null
|
||||||
dialog = WifiP2pDialog(context, DialogInterface.OnClickListener { _, which ->
|
dialog = WifiP2pDialog(context, DialogInterface.OnClickListener { _, which ->
|
||||||
when (which) {
|
when (which) {
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnMonitor.Ca
|
|||||||
val ssid get() = group?.networkName
|
val ssid get() = group?.networkName
|
||||||
val password get() = group?.passphrase
|
val password get() = group?.passphrase
|
||||||
|
|
||||||
|
private var groups: Collection<WifiP2pGroup> = emptyList()
|
||||||
|
|
||||||
fun startWps(pin: String? = null) {
|
fun startWps(pin: String? = null) {
|
||||||
if (!active) return
|
if (!active) return
|
||||||
val wps = WpsInfo()
|
val wps = WpsInfo()
|
||||||
@@ -67,8 +69,8 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnMonitor.Ca
|
|||||||
if (active) removeGroup()
|
if (active) removeGroup()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetCredentials() {
|
fun resetCredentials() = (groups + group).filterNotNull().forEach {
|
||||||
p2pManager.deletePersistentGroup(channel, (group ?: return).netId, object : WifiP2pManager.ActionListener {
|
p2pManager.deletePersistentGroup(channel, it.netId, object : WifiP2pManager.ActionListener {
|
||||||
override fun onSuccess() = Toast.makeText(this@RepeaterService,
|
override fun onSuccess() = Toast.makeText(this@RepeaterService,
|
||||||
R.string.repeater_reset_credentials_success, Toast.LENGTH_SHORT).show()
|
R.string.repeater_reset_credentials_success, Toast.LENGTH_SHORT).show()
|
||||||
override fun onFailure(reason: Int) = Toast.makeText(this@RepeaterService,
|
override fun onFailure(reason: Int) = Toast.makeText(this@RepeaterService,
|
||||||
@@ -80,11 +82,8 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnMonitor.Ca
|
|||||||
group = null
|
group = null
|
||||||
try {
|
try {
|
||||||
p2pManager.requestPersistentGroupInfo(channel, {
|
p2pManager.requestPersistentGroupInfo(channel, {
|
||||||
when (it.size) {
|
groups = it
|
||||||
0 -> { }
|
if (it.size == 1) group = it.single()
|
||||||
1 -> group = it.single()
|
|
||||||
else -> Log.w(TAG, "Unexpected groups: $it")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
} catch (e: ReflectiveOperationException) {
|
} catch (e: ReflectiveOperationException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|||||||
@@ -12,16 +12,27 @@ import java.io.File
|
|||||||
class P2pSupplicantConfiguration {
|
class P2pSupplicantConfiguration {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "P2pSupplicationConf"
|
private const val TAG = "P2pSupplicationConf"
|
||||||
// format for ssid is much more complicated, therefore we are only trying to find the line
|
/**
|
||||||
|
* Format for ssid is much more complicated, therefore we are only trying to find the line and rely on
|
||||||
|
* Android's results instead.
|
||||||
|
*
|
||||||
|
* Source: https://android.googlesource.com/platform/external/wpa_supplicant_8/+/2933359/src/utils/common.c#631
|
||||||
|
*/
|
||||||
private val ssidMatcher = "^[\\r\\t ]*ssid=".toRegex()
|
private val ssidMatcher = "^[\\r\\t ]*ssid=".toRegex()
|
||||||
private val pskParser = "^[\\r\\t ]*psk=\"(.*)\"\$".toRegex(RegexOption.MULTILINE)
|
/**
|
||||||
|
* PSK parser can be found here: https://android.googlesource.com/platform/external/wpa_supplicant_8/+/d2986c2/wpa_supplicant/config.c#448
|
||||||
|
*/
|
||||||
|
private val pskParser = "^[\\r\\t ]*psk=(ext:|\"(.*)\"|\"(.*)|[0-9a-fA-F]{64})".toRegex(RegexOption.MULTILINE)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val content by lazy { loggerSu("cat /data/misc/wifi/p2p_supplicant.conf") }
|
private val content by lazy { loggerSu("cat /data/misc/wifi/p2p_supplicant.conf") }
|
||||||
|
|
||||||
fun readPsk(): String? {
|
fun readPsk(): String? {
|
||||||
return try {
|
return try {
|
||||||
pskParser.findAll(content ?: return null).single().groupValues[1]
|
val match = pskParser.findAll(content ?: return null).single()
|
||||||
|
val result = match.groupValues[2] + match.groupValues[3] // only one will match and hold non-empty value
|
||||||
|
check(result.length in 8..63)
|
||||||
|
result
|
||||||
} catch (e: RuntimeException) {
|
} catch (e: RuntimeException) {
|
||||||
Log.w(TAG, content)
|
Log.w(TAG, content)
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@@ -34,26 +45,24 @@ class P2pSupplicantConfiguration {
|
|||||||
val content = content ?: return null
|
val content = content ?: return null
|
||||||
val tempFile = File.createTempFile("vpnhotspot-", ".conf", app.cacheDir)
|
val tempFile = File.createTempFile("vpnhotspot-", ".conf", app.cacheDir)
|
||||||
try {
|
try {
|
||||||
var ssidFound = false
|
var ssidFound = 0
|
||||||
var pskFound = false
|
var pskFound = 0
|
||||||
tempFile.printWriter().use {
|
tempFile.printWriter().use {
|
||||||
for (line in content.lineSequence()) it.println(when {
|
for (line in content.lineSequence()) it.println(when {
|
||||||
ssidMatcher.containsMatchIn(line) -> {
|
ssidMatcher.containsMatchIn(line) -> {
|
||||||
ssidFound = true
|
ssidFound += 1
|
||||||
"\tssid=" + config.SSID.toByteArray()
|
"\tssid=" + config.SSID.toByteArray()
|
||||||
.joinToString("") { it.toInt().toString(16).padStart(2, '0') }
|
.joinToString("") { it.toInt().toString(16).padStart(2, '0') }
|
||||||
}
|
}
|
||||||
pskParser.containsMatchIn(line) -> {
|
pskParser.containsMatchIn(line) -> {
|
||||||
pskFound = true
|
pskFound += 1
|
||||||
"\tpsk=\"${config.preSharedKey}\"" // no control chars or weird stuff
|
"\tpsk=\"${config.preSharedKey}\"" // no control chars or weird stuff
|
||||||
}
|
}
|
||||||
else -> line // do nothing
|
else -> line // do nothing
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (!ssidFound || !pskFound) {
|
if (ssidFound != 1 || pskFound != 1) Log.w(TAG, "Invalid conf ($ssidFound, $pskFound): $content")
|
||||||
Log.w(TAG, "Invalid conf ($ssidFound, $pskFound): $content")
|
if (ssidFound == 0 || pskFound == 0) return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
// pkill not available on Lollipop. Source: https://android.googlesource.com/platform/system/core/+/master/shell_and_utilities/README.md
|
// pkill not available on Lollipop. Source: https://android.googlesource.com/platform/system/core/+/master/shell_and_utilities/README.md
|
||||||
return noisySu("cat ${tempFile.absolutePath} > /data/misc/wifi/p2p_supplicant.conf",
|
return noisySu("cat ${tempFile.absolutePath} > /data/misc/wifi/p2p_supplicant.conf",
|
||||||
if (Build.VERSION.SDK_INT >= 23) "pkill wpa_supplicant"
|
if (Build.VERSION.SDK_INT >= 23) "pkill wpa_supplicant"
|
||||||
|
|||||||
Reference in New Issue
Block a user