I have been trying to connect my android device to an enterprise network programatically over the past few days without any success, I have been following multiple examples online, but most of the ones I find are for EAP(TLS) networks and the one where I work is EAP(PEAP), here is the type of network.
802.1x EAP
EAP method: PEAP
Phase 2 Authentication: MSCHAPV2
the authentication always fails and logcat doesn’t indicate me where the problem is I just know it fails when the authentication is being performed.
Here is a copy of my current code and the logs from logcat where it fails:
/****************** CODE ******************************/
public class WPAActivity extends LauncherActivity
{
private static final String TAG = "WPAActivity";
/************* Definitions to find variables ***************************/
private static final String INT_PRIVATE_KEY = "private_key";
private static final String INT_PHASE2 = "phase2";
private static final String INT_PASSWORD = "password";
private static final String INT_IDENTITY = "identity";
private static final String INT_EAP = "eap";
private static final String INT_CLIENT_CERT = "client_cert";
private static final String INT_CA_CERT = "ca_cert";
private static final String INT_ANONYMOUS_IDENTITY = "anonymous_identity";
final String INT_ENTERPRISEFIELD_NAME ="android.net.wifi.WifiConfiguration$EnterpriseField";
/************************************************************************/
/********************************Configuration Strings*********************/
final String ENTERPRISE_EAP = "PEAP";
final String ENTERPRISE_CLIENT_CERT = "";
final String ENTERPRISE_PRIV_KEY = "";
final String ENTERPRISE_PHASE2 = "\"MSCHAPV2\"";
final String ENTERPRISE_ANON_IDENT = "";
final String ENTERPRISE_CA_CERT = "";
final String userName = "\"my Username";
final String passString = "\"my Password\"";
/**************************************************************************/
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"mySSID\"";
wc.preSharedKey = "\"my Password\"";
wc.hiddenSSID = true;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedKeyManagement.clear();
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
/*Group Ciphers*/
wc.allowedGroupCiphers.clear();
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
/*Protocols*/
wc.allowedProtocols.clear();
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
Class[] enterpriseFieldArray = WifiConfiguration.class.getClasses();
Class<?> enterpriseFieldClass = null;
for(Class<?> myClass : enterpriseFieldArray)
{
if(myClass.getName().equals(INT_ENTERPRISEFIELD_NAME))
{
enterpriseFieldClass = myClass;
break;
}
}
Log.d(TAG, "class chosen " + enterpriseFieldClass.getName() );
Field anonymousId = null, caCert = null, clientCert = null,
eap = null, identity = null, password = null,
phase2 = null, privateKey = null;
Field[] fields = WifiConfiguration.class.getFields();
for (Field tempField : fields)
{
if (tempField.getName().trim().equals(INT_ANONYMOUS_IDENTITY))
{
anonymousId = tempField;
Log.d(TAG, "field " + anonymousId.getName() );
}
else if (tempField.getName().trim().equals(INT_CA_CERT))
{
caCert = tempField;
}
else if (tempField.getName().trim().equals(INT_CA_CERT))
{
}
else if (tempField.getName().trim().equals(INT_CLIENT_CERT))
{
clientCert = tempField;
Log.d(TAG, "field " + clientCert.getName() );
}
else if (tempField.getName().trim().equals(INT_EAP))
{
eap = tempField;
Log.d(TAG, "field " + eap.getName() );
}
else if (tempField.getName().trim().equals(INT_IDENTITY))
{
identity = tempField;
Log.d(TAG, "field " + identity.getName() );
}
else if (tempField.getName().trim().equals(INT_PASSWORD))
{
password = tempField;
Log.d(TAG, "field " + password.getName() );
}
else if (tempField.getName().trim().equals(INT_PHASE2))
{
phase2 = tempField;
Log.d(TAG, "field " + phase2.getName() );
}
else if (tempField.getName().trim().equals(INT_PRIVATE_KEY))
{
privateKey = tempField;
}
}
Method setValue = null;
for(Method m: enterpriseFieldClass.getMethods())
{
if(m.getName().trim().equals("setValue"))
{
Log.d(TAG, "method " + m.getName() );
setValue = m;
break;
}
}
try
{
// EAP
setValue.invoke(eap.get(wc), ENTERPRISE_EAP);
// EAP Phase 2
setValue.invoke(phase2.get(wc), ENTERPRISE_PHASE2);
// EAP Anonymous Id
setValue.invoke(anonymousId.get(wc), ENTERPRISE_ANON_IDENT);
// EAP CA Certificate
setValue.invoke(caCert.get(wc), ENTERPRISE_CA_CERT);
// Private Key
setValue.invoke(privateKey.get(wc), ENTERPRISE_PRIV_KEY);
// EAP Identity
setValue.invoke(identity.get(wc), userName);
// EAP Password
setValue.invoke(password.get(wc), passString);
// EAP Client certificate
setValue.invoke(clientCert.get(wc), ENTERPRISE_CLIENT_CERT);
}
catch (Exception e)
{
}
Log.d("WifiPreference", "2");
int res = wifi.addNetwork(wc);
Log.d("WifiPreference", "add Network returned " + res );
boolean b = wifi.enableNetwork(res, true);
Log.d("WifiPreference", "enableNetwork returned " + b );
}
}
and these are the logs indicating where the connection attempt fails
/************************And here are the logs********************/
02-09 09:23:30.514: I/ActivityManager(2084): Displayed activity com.test.wpa/.WPAActivity: 445 ms (total 445 ms)
02-09 09:23:31.514: I/wpa_supplicant(27633): CTRL-EVENT-SCAN-RESULTS Ready
02-09 09:23:31.514: I/wpa_supplicant(27633): Trying to associate with 00:1c:0f:82:04:e0 (SSID='*****' freq=2437 MHz)
02-09 09:23:31.514: I/wpa_supplicant(27633): CTRL-EVENT-STATE-CHANGE id=-1 state=3
02-09 09:23:31.649: V/WifiMonitor(2084): Event [Trying to associate with 00:1c:0f:82:04:e0 (SSID='*****' freq=2437 MHz)]
02-09 09:23:31.649: V/WifiMonitor(2084): Event [CTRL-EVENT-STATE-CHANGE id=-1 state=3]
02-09 09:23:31.654: V/WifiStateTracker(2084): Changing supplicant state: SCANNING ==> ASSOCIATING
02-09 09:23:31.654: D/NetworkStateTracker(2084): setDetailed state, old =SCANNING and new state=CONNECTING
02-09 09:23:31.659: D/ConnectivityService(2084): ConnectivityChange for WIFI: CONNECTING/CONNECTING
02-09 09:23:32.621: I/wpa_supplicant(27633): CTRL-EVENT-STATE-CHANGE id=0 state=4
02-09 09:23:32.621: V/WifiMonitor(2084): Event [CTRL-EVENT-STATE-CHANGE id=0 state=4]
02-09 09:23:32.624: I/wpa_supplicant(27633): Associated with 00:1c:0f:82:04:e0
02-09 09:23:32.624: I/wpa_supplicant(27633): CTRL-EVENT-EAP-STARTED EAP authentication started
02-09 09:23:32.629: V/WifiMonitor(2084): Event [Associated with 00:1c:0f:82:04:e0]
**02-09 09:23:32.629: V/WifiMonitor(2084): Event [CTRL-EVENT-EAP-STARTED EAP authentication started]**
02-09 09:23:32.629: V/WifiStateTracker(2084): Changing supplicant state: ASSOCIATING ==> ASSOCIATED
**02-09 09:23:32.629: D/NetworkStateTracker(2084): setDetailed state, old =CONNECTING and new state=CONNECTING**
**02-09 09:23:32.634: I/wpa_supplicant(27633): CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys**
02-09 09:23:32.644: I/wpa_supplicant(27633): CTRL-EVENT-STATE-CHANGE id=0 state=0
**02-09 09:23:32.644: V/WifiMonitor(2084): Event [CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys]**
02-09 09:23:32.644: V/WifiMonitor(2084): Event [CTRL-EVENT-STATE-CHANGE id=0 state=0]
I couldn’t find examples online about EAP (PEAP) authentication programmatically, I have tried changing the WiFi configuration with no success. Any Ideas or helpful sites/examples on how to connect to a Enterprise network EAP (PEAP), or can someone point me in the right direction?
Finally, I’ve defeated my CiSCO EAP-FAST corporate wifi network, and all our Android devices are now able to connect to it.
The walk-around I’ve performed in order to gain access to this kind of networks from an Android device are easiest than you can imagine.
There’s a Wifi Config Editor in the Google Play Store you can use to “activate” the secondary CISCO Protocols when you are setting up a EAP wifi connection.
Its name is Wifi Config Advanced Editor.
-
First, you have to setup your wireless network manually as close as you can to your “official” corporate wifi parameters.
-
Save it.
-
Go to the WCE and edit the parameters of the network you have created in the previous step.
-
There are 3 or 4 series of settings you should activate in order to force the Android device to use them as a way to connect (the main site I think you want to visit is Enterprise Configuration, but don’t forget to check all the parameters to change them if needed.
As a suggestion, even if you have a WPA2 EAP-FAST Cipher, try LEAP in your setup. It worked for me as a charm. -
When you finished to edit the config, go to the main Android wifi controller, and force to connect to this network.
-
Do not Edit the network again with the Android wifi interface.
I have tested it on Samsung Galaxy 1 and 2, Note mobile devices, and on a Lenovo Thinkpad Tablet.
Answer:
Thanks for enlightening us Cypawer.
I also tried this app https://play.google.com/store/apps/details?id=com.oneguyinabasement.leapwifi
and it worked flawlessly.
Tags: androidandroid