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

View file

@ -17,6 +17,7 @@
package com.google.zxing.client.android.wifi; package com.google.zxing.client.android.wifi;
import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.util.Log; import android.util.Log;
@ -28,6 +29,7 @@ import com.google.zxing.client.result.WifiParsedResult;
/** /**
* @author Vikram Aggarwal * @author Vikram Aggarwal
* @author Sean Owen * @author Sean Owen
* @author Steffen Kieß
*/ */
public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,Object> { public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,Object> {
@ -89,6 +91,9 @@ public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,O
case WPA: case WPA:
changeNetworkWPA(wifiManager, theWifiResult); changeNetworkWPA(wifiManager, theWifiResult);
break; break;
case WPA2_EAP:
changeNetworkWPA2EAP(wifiManager, theWifiResult);
break;
} }
} }
} }
@ -164,6 +169,26 @@ public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,O
updateNetwork(wifiManager, config); 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 // Adding an open, unsecured network
private static void changeNetworkUnEncrypted(WifiManager wifiManager, WifiParsedResult wifiResult) { private static void changeNetworkUnEncrypted(WifiManager wifiManager, WifiParsedResult wifiResult) {
WifiConfiguration config = changeNetworkCommon(wifiResult); WifiConfiguration config = changeNetworkCommon(wifiResult);
@ -226,4 +251,44 @@ public final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,O
return false; 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 networkEncryption;
private final String password; private final String password;
private final boolean hidden; 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) { public WifiParsedResult(String networkEncryption, String ssid, String password) {
this(networkEncryption, ssid, password, false); this(networkEncryption, ssid, password, false);
} }
public WifiParsedResult(String networkEncryption, String ssid, String password, boolean hidden) { 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); super(ParsedResultType.WIFI);
this.ssid = ssid; this.ssid = ssid;
this.networkEncryption = networkEncryption; this.networkEncryption = networkEncryption;
this.password = password; this.password = password;
this.hidden = hidden; this.hidden = hidden;
this.identity = identity;
this.anonymousIdentity = anonymousIdentity;
this.eapMethod = eapMethod;
this.phase2Method = phase2Method;
} }
public String getSsid() { public String getSsid() {
@ -56,6 +68,22 @@ public final class WifiParsedResult extends ParsedResult {
return hidden; return hidden;
} }
public String getIdentity() {
return identity;
}
public String getAnonymousIdentity() {
return anonymousIdentity;
}
public String getEapMethod() {
return eapMethod;
}
public String getPhase2Method() {
return phase2Method;
}
@Override @Override
public String getDisplayResult() { public String getDisplayResult() {
StringBuilder result = new StringBuilder(80); 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>{@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> * <p>The fields can appear in any order. Only "S:" is required.</p>
* *
* @author Vikram Aggarwal * @author Vikram Aggarwal
* @author Sean Owen * @author Sean Owen
* @author Steffen Kieß
*/ */
public final class WifiResultParser extends ResultParser { public final class WifiResultParser extends ResultParser {
@ -36,6 +43,7 @@ public final class WifiResultParser extends ResultParser {
if (!rawText.startsWith("WIFI:")) { if (!rawText.startsWith("WIFI:")) {
return null; return null;
} }
rawText = rawText.substring("WIFI:".length());
String ssid = matchSinglePrefixedField("S:", rawText, ';', false); String ssid = matchSinglePrefixedField("S:", rawText, ';', false);
if (ssid == null || ssid.isEmpty()) { if (ssid == null || ssid.isEmpty()) {
return null; return null;
@ -46,6 +54,10 @@ public final class WifiResultParser extends ResultParser {
type = "nopass"; type = "nopass";
} }
boolean hidden = Boolean.parseBoolean(matchSinglePrefixedField("H:", rawText, ';', false)); 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);
} }
} }