I want to develop an app that can prevent connection to a WiFi network unless I approve it. I want to be able to query the MAC address of the access point and compare that to a list of known addresses corresponding to SSIDs. The goal of the app is to protect users from accidentally connecting to malicious access points, such as the types that can be produced with pineapple devices.
I'm not clear from my research how I would achieve this goal. Questions such as How to be notified on wifi network status change? explain how to detect the connection has happened, but for my use case that's already too late.
Neither ConnectivityManager
nor WifiManager
seem to offer methods for adding listeners that could interrupt a connection in progress.
Some thoughts I've had for a solution:
Install myself as a proxy and make the decision as to whether to allow data through. However, this doesn't seem to be an option based on Do Android proxy settings apply to all apps on the device? (hint: the answer is "No").
Replace the existing WiFi manager with something of my own creation. However, I've really struggled to find any information in the Android developer guides regarding replacing system components. Consequently, I'm not sure this is possible on non-rooted phones.
Store the network passwords within my app and set the passwords in the WiFi manager to nonsense values. Then capture a broadcast message that warns of a failed connection (presumably something like. It occurs to me that pineapple devices would probably accept any password, thus rendering this approach void.WifiManager.WPS_AUTH_FAILURE
) and selectively decide to reconnect back to that network. Might be a possible (if ugly) solution, but can I set the password back to a nonsense value while the network is still connected, to ensure we don't quietly connect to another SSID of the same name? I'm not sureFind some way to prevent Android automatically connecting to known networks (i.e. networks that have been used before or have a password stored with them). Then I could manage all connections/disconnections from my app. I can't see how to do this manually on my phone, however, so I'm doubtful this is possible programmatically.
Can anyone suggest an approach that would work on a non-rooted phone?
ScanResult
should provide the BSSID, right? If so, I can retrieve that separately. – Dewain