Implement support for WPA2 Enterprise (EAP) (#865)

This commit is contained in:
Steffen Kieß 2017-10-29 21:40:53 +01:00 committed by Sean Owen
parent 5284daa336
commit 49d90b6457
4 changed files with 110 additions and 2 deletions

View file

@ -20,7 +20,8 @@ enum NetworkType {
WEP,
WPA,
NO_PASSWORD;
NO_PASSWORD,
WPA2_EAP;
static NetworkType forIntentValue(String networkTypeString) {
if (networkTypeString == null) {
@ -30,6 +31,8 @@ enum NetworkType {
case "WPA":
case "WPA2":
return WPA;
case "WPA2-EAP":
return WPA2_EAP;
case "WEP":
return WEP;
case "nopass":

View file

@ -17,6 +17,7 @@
package com.google.zxing.client.android.wifi;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.util.Log;
@ -28,6 +29,7 @@ import com.google.zxing.client.result.WifiParsedResult;
/**
* @author Vikram Aggarwal
* @author Sean Owen
* @author Steffen Kieß
*/
public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,Object> {
@ -89,6 +91,9 @@ public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,O
case WPA:
changeNetworkWPA(wifiManager, theWifiResult);
break;
case WPA2_EAP:
changeNetworkWPA2EAP(wifiManager, theWifiResult);
break;
}
}
}
@ -164,6 +169,26 @@ public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,O
updateNetwork(wifiManager, config);
}
// Adding a WPA2 enterprise (EAP) network
private static void changeNetworkWPA2EAP(WifiManager wifiManager, WifiParsedResult wifiResult) {
WifiConfiguration config = changeNetworkCommon(wifiResult);
// Hex passwords that are 64 bits long are not to be quoted.
config.preSharedKey = quoteNonHex(wifiResult.getPassword(), 64);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.enterpriseConfig.setIdentity(wifiResult.getIdentity());
config.enterpriseConfig.setAnonymousIdentity(wifiResult.getAnonymousIdentity());
config.enterpriseConfig.setPassword(wifiResult.getPassword());
config.enterpriseConfig.setEapMethod(parseEap(wifiResult.getEapMethod()));
config.enterpriseConfig.setPhase2Method(parsePhase2(wifiResult.getPhase2Method()));
updateNetwork(wifiManager, config);
}
// Adding an open, unsecured network
private static void changeNetworkUnEncrypted(WifiManager wifiManager, WifiParsedResult wifiResult) {
WifiConfiguration config = changeNetworkCommon(wifiResult);
@ -226,4 +251,44 @@ public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,O
return false;
}
private static int parseEap(String eapString) {
if (eapString == null) {
return WifiEnterpriseConfig.Eap.NONE;
}
switch (eapString) {
case "NONE":
return WifiEnterpriseConfig.Eap.NONE;
case "PEAP":
return WifiEnterpriseConfig.Eap.PEAP;
case "PWD":
return WifiEnterpriseConfig.Eap.PWD;
case "TLS":
return WifiEnterpriseConfig.Eap.TLS;
case "TTLS":
return WifiEnterpriseConfig.Eap.TTLS;
default:
throw new IllegalArgumentException("Unknown value for EAP method: " + eapString);
}
}
private static int parsePhase2(String phase2String) {
if (phase2String == null) {
return WifiEnterpriseConfig.Phase2.NONE;
}
switch (phase2String) {
case "GTC":
return WifiEnterpriseConfig.Phase2.GTC;
case "MSCHAP":
return WifiEnterpriseConfig.Phase2.MSCHAP;
case "MSCHAPV2":
return WifiEnterpriseConfig.Phase2.MSCHAPV2;
case "NONE":
return WifiEnterpriseConfig.Phase2.NONE;
case "PAP":
return WifiEnterpriseConfig.Phase2.PAP;
default:
throw new IllegalArgumentException("Unknown value for phase 2 method: " + phase2String);
}
}
}

View file

@ -27,17 +27,29 @@ public final class WifiParsedResult extends ParsedResult {
private final String networkEncryption;
private final String password;
private final boolean hidden;
private final String identity;
private final String anonymousIdentity;
private final String eapMethod;
private final String phase2Method;
public WifiParsedResult(String networkEncryption, String ssid, String password) {
this(networkEncryption, ssid, password, false);
}
public WifiParsedResult(String networkEncryption, String ssid, String password, boolean hidden) {
this(networkEncryption, ssid, password, hidden, null, null, null, null);
}
public WifiParsedResult(String networkEncryption, String ssid, String password, boolean hidden, String identity, String anonymousIdentity, String eapMethod, String phase2Method) {
super(ParsedResultType.WIFI);
this.ssid = ssid;
this.networkEncryption = networkEncryption;
this.password = password;
this.hidden = hidden;
this.identity = identity;
this.anonymousIdentity = anonymousIdentity;
this.eapMethod = eapMethod;
this.phase2Method = phase2Method;
}
public String getSsid() {
@ -56,6 +68,22 @@ public final class WifiParsedResult extends ParsedResult {
return hidden;
}
public String getIdentity() {
return identity;
}
public String getAnonymousIdentity() {
return anonymousIdentity;
}
public String getEapMethod() {
return eapMethod;
}
public String getPhase2Method() {
return phase2Method;
}
@Override
public String getDisplayResult() {
StringBuilder result = new StringBuilder(80);

View file

@ -23,10 +23,17 @@ import com.google.zxing.Result;
*
* <p>{@code WIFI:T:[network type];S:[network SSID];P:[network password];H:[hidden?];;}</p>
*
* <p>For WPA2 enterprise (EAP), strings will be of the form:</p>
*
* <p>{@code WIFI:T:WPA2-EAP;S:[network SSID];H:[hidden?];E:[EAP method];H:[Phase 2 method];A:[anonymous identity];I:[username];P:[password];;}</p>
*
* <p>"EAP method" can e.g. be "TTLS" or "PWD" or one of the other fields in <a href="https://developer.android.com/reference/android/net/wifi/WifiEnterpriseConfig.Eap.html">WifiEnterpriseConfig.Eap</a> and "Phase 2 method" can e.g. be "MSCHAPV2" or any of the other fields in <a href="https://developer.android.com/reference/android/net/wifi/WifiEnterpriseConfig.Phase2.html">WifiEnterpriseConfig.Phase2</a></p>
*
* <p>The fields can appear in any order. Only "S:" is required.</p>
*
* @author Vikram Aggarwal
* @author Sean Owen
* @author Steffen Kieß
*/
public final class WifiResultParser extends ResultParser {
@ -36,6 +43,7 @@ public final class WifiResultParser extends ResultParser {
if (!rawText.startsWith("WIFI:")) {
return null;
}
rawText = rawText.substring("WIFI:".length());
String ssid = matchSinglePrefixedField("S:", rawText, ';', false);
if (ssid == null || ssid.isEmpty()) {
return null;
@ -46,6 +54,10 @@ public final class WifiResultParser extends ResultParser {
type = "nopass";
}
boolean hidden = Boolean.parseBoolean(matchSinglePrefixedField("H:", rawText, ';', false));
return new WifiParsedResult(type, ssid, pass, hidden);
String identity = matchSinglePrefixedField("I:", rawText, ';', false);
String anonymousIdentity = matchSinglePrefixedField("A:", rawText, ';', false);
String eapMethod = matchSinglePrefixedField("E:", rawText, ';', false);
String phase2Method = matchSinglePrefixedField("H:", rawText, ';', false);
return new WifiParsedResult(type, ssid, pass, hidden, identity, anonymousIdentity, eapMethod, phase2Method);
}
}