diff options
author | Ecco Park <eccopark@google.com> | 2018-06-26 14:27:01 -0700 |
---|---|---|
committer | Ecco Park <eccopark@google.com> | 2018-10-01 16:12:13 -0700 |
commit | 8d6c5e6b13a710a8df9a81db269e039421d64e0b (patch) | |
tree | 13573b3c0cd1ba70e79c160cd796c0a56a731cf1 | |
parent | c442cac03988b303a1151a774cc291a89ed1dad1 (diff) |
passpoint: skip NAI realms match in case of 3GPP element match
From O, EAP-AKA/SIM for T-mobile has been broken with Boingo AP.
For Boingo AP, NAI realm ANQP element doesn't contain realm matching
PLMN ID(MNC/MCC) from SIM on the device.
Because of this, current design can't find the Boingo AP as roaming partner with
T-mobile even though 3GPP Celluar Network ANQP element is already matched with
MCC/MNC from SIM on the device.
In case of 3GPP element match, it is considered as roaming partner
regardless of NAI realm match
Bug: 80527981
Test: ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Test: live test with OSU AP
Change-Id: Iedb9b26873779070c0b08a0b4ff3c4e96a5bdcb9
Signed-off-by: Ecco Park <eccopark@google.com>
(cherry picked from commit d085366918fa9a1db977993eb859e790180508aa)
-rw-r--r-- | service/java/com/android/server/wifi/hotspot2/PasspointProvider.java | 27 | ||||
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java | 294 |
2 files changed, 260 insertions, 61 deletions
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java index f86a938d7..6d09a29ca 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java @@ -259,24 +259,32 @@ public class PasspointProvider { */ public PasspointMatch match(Map<ANQPElementType, ANQPElement> anqpElements, RoamingConsortium roamingConsortium) { - PasspointMatch providerMatch = matchProvider(anqpElements, roamingConsortium); + PasspointMatch providerMatch = matchProviderExceptFor3GPP(anqpElements, roamingConsortium); + + // 3GPP Network matching. + if (providerMatch == PasspointMatch.None && ANQPMatcher.matchThreeGPPNetwork( + (ThreeGPPNetworkElement) anqpElements.get(ANQPElementType.ANQP3GPPNetwork), + mImsiParameter, mMatchingSIMImsiList)) { + return PasspointMatch.RoamingProvider; + } // Perform authentication match against the NAI Realm. int authMatch = ANQPMatcher.matchNAIRealm( (NAIRealmElement) anqpElements.get(ANQPElementType.ANQPNAIRealm), mConfig.getCredential().getRealm(), mEAPMethodID, mAuthParam); - // Auth mismatch, demote provider match. + // In case of Auth mismatch, demote provider match. if (authMatch == AuthMatch.NONE) { return PasspointMatch.None; } - // No realm match, return provider match as is. + // In case of no realm match, return provider match as is. if ((authMatch & AuthMatch.REALM) == 0) { return providerMatch; } - // Realm match, promote provider match to roaming if no other provider match is found. + // Promote the provider match to roaming provider if provider match is not found, but NAI + // realm is matched. return providerMatch == PasspointMatch.None ? PasspointMatch.RoamingProvider : providerMatch; } @@ -454,13 +462,14 @@ public class PasspointProvider { } /** - * Perform a provider match based on the given ANQP elements. + * Perform a provider match based on the given ANQP elements except for matching 3GPP Network. * * @param anqpElements List of ANQP elements * @param roamingConsortium Roaming Consortium information element from the AP * @return {@link PasspointMatch} */ - private PasspointMatch matchProvider(Map<ANQPElementType, ANQPElement> anqpElements, + private PasspointMatch matchProviderExceptFor3GPP( + Map<ANQPElementType, ANQPElement> anqpElements, RoamingConsortium roamingConsortium) { // Domain name matching. if (ANQPMatcher.matchDomainName( @@ -489,12 +498,6 @@ public class PasspointProvider { } } - // 3GPP Network matching. - if (ANQPMatcher.matchThreeGPPNetwork( - (ThreeGPPNetworkElement) anqpElements.get(ANQPElementType.ANQP3GPPNetwork), - mImsiParameter, mMatchingSIMImsiList)) { - return PasspointMatch.RoamingProvider; - } return PasspointMatch.None; } diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java index 0055fbaaa..58496622f 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java @@ -47,8 +47,8 @@ import com.android.server.wifi.hotspot2.anqp.ThreeGPPNetworkElement; import com.android.server.wifi.hotspot2.anqp.eap.AuthParam; import com.android.server.wifi.hotspot2.anqp.eap.EAPMethod; import com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth; - import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium; + import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -447,7 +447,7 @@ public class PasspointProviderTest { * @throws Exception */ @Test - public void match3GPPNetworkDomainName() throws Exception { + public void matchFQDNWith3GPPNetworkDomainName() throws Exception { String testImsi = "1234567890"; // Setup test provider. @@ -472,13 +472,56 @@ public class PasspointProviderTest { } /** + * Verify that a provider is a home provider when its FQDN, roaming consortium OI, and + * IMSI all matched against the ANQP elements, since we prefer matching home provider over + * roaming provider. + * + * @throws Exception + */ + @Test + public void matchFQDNOverRoamingProvider() throws Exception { + // Setup test data. + String testDomain = "test.com"; + String testImsi = "1234567890"; + long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; + Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L}; + + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn(testDomain); + homeSp.setRoamingConsortiumOis(providerRCOIs); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + Credential.SimCredential simCredential = new Credential.SimCredential(); + simCredential.setImsi(testImsi); + credential.setSimCredential(simCredential); + config.setCredential(credential); + when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false))) + .thenReturn(Arrays.asList(new String[] {testImsi})); + mProvider = createProvider(config); + + // Setup ANQP elements. + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {testDomain})); + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpRCOIs)); + anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork, + createThreeGPPNetworkElement(new String[] {"123456"})); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI - * in the roaming consortium ANQP element. + * in the roaming consortium ANQP element and no NAI realm is provided. * * @throws Exception */ @Test - public void matchRoamingConsortium() throws Exception { + public void matchRoamingConsortiumWithoutNAIRealm() throws Exception { long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L}; @@ -505,12 +548,87 @@ public class PasspointProviderTest { /** * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI - * in the roaming consortium information element. + * in the roaming consortium ANQP element and the provider's credential matches the + * NAI realm provided. + * + * @throws Exception + */ + @Test + public void matchRoamingConsortiumWithNAIRealmMatch() throws Exception { + long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; + Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L}; + String testRealm = "realm.com"; + + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setRoamingConsortiumOis(providerRCOIs); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setRealm(testRealm); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2); + credential.setUserCredential(userCredential); + config.setCredential(credential); + mProvider = createProvider(config); + + // Setup Roaming Consortium ANQP element. + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpRCOIs)); + anqpElementMap.put(ANQPElementType.ANQPNAIRealm, + createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS, + new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2))); + + assertEquals(PasspointMatch.RoamingProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that there is no match when a roaming consortium OI matches an OI + * in the roaming consortium ANQP element and but NAI realm is not matched. + * + * @throws Exception + */ + @Test + public void matchRoamingConsortiumWithNAIRealmMisMatch() throws Exception { + long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; + Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L}; + String testRealm = "realm.com"; + + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setRoamingConsortiumOis(providerRCOIs); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setRealm(testRealm); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2); + credential.setUserCredential(userCredential); + config.setCredential(credential); + mProvider = createProvider(config); + + // Setup Roaming Consortium ANQP element. + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpRCOIs)); + // Set up NAI with different EAP method + anqpElementMap.put(ANQPElementType.ANQPNAIRealm, + createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); + + assertEquals(PasspointMatch.None, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI + * in the roaming consortium information element and no NAI realm is provided. * * @throws Exception */ @Test - public void matchRoamingConsortiumIe() throws Exception { + public void matchRoamingConsortiumIeWithoutNAIRealm() throws Exception { long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; long[] ieRCOIs = new long[] {0x1234L, 0x2133L}; @@ -537,7 +655,84 @@ public class PasspointProviderTest { } /** - * Verify that none of matched providers are not found when a roaming consortium OI doesn't + * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI + * in the roaming consortium information element and the provider's credential matches the + * NAI realm provided. + * + * @throws Exception + */ + @Test + public void matchRoamingConsortiumIeWithNAIRealmMatch() throws Exception { + long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; + long[] ieRCOIs = new long[] {0x1234L, 0x2133L}; + String testRealm = "realm.com"; + + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setRoamingConsortiumOis(providerRCOIs); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setRealm(testRealm); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2); + credential.setUserCredential(userCredential); + config.setCredential(credential); + mProvider = createProvider(config); + + // Setup Roaming Consortium ANQP element. + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + + // Setup Roaming Consortium Information element. + when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(ieRCOIs); + anqpElementMap.put(ANQPElementType.ANQPNAIRealm, + createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS, + new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2))); + + assertEquals(PasspointMatch.RoamingProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that there is no match when a roaming consortium OI matches an OI + * in the roaming consortium information element, but NAI realm is not matched. + * + * @throws Exception + */ + @Test + public void matchRoamingConsortiumIeWithNAIRealmMismatch() throws Exception { + long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; + long[] ieRCOIs = new long[] {0x1234L, 0x2133L}; + String testRealm = "realm.com"; + + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setRoamingConsortiumOis(providerRCOIs); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setRealm(testRealm); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2); + credential.setUserCredential(userCredential); + config.setCredential(credential); + mProvider = createProvider(config); + + // Setup Roaming Consortium ANQP element. + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + + // Setup Roaming Consortium Information element. + when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(ieRCOIs); + // Set up NAI with different EAP method + anqpElementMap.put(ANQPElementType.ANQPNAIRealm, + createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); + + assertEquals(PasspointMatch.None, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that none of matched providers are found when a roaming consortium OI doesn't * matches an OI in the roaming consortium information element and * none of NAI realms match each other. * @@ -571,15 +766,16 @@ public class PasspointProviderTest { } /** - * Verify that a provider is a roaming provider when the provider's IMSI parameter and an - * IMSI from the SIM card matches a MCC-MNC in the 3GPP Network ANQP element. + * Verify that a provider is a roaming provider when the provider's IMSI parameter and an IMSI + * from the SIM card matches a MCC-MNC in the 3GPP Network ANQP element regardless of NAI realm + * mismatch. * * @throws Exception */ @Test - public void matchThreeGPPNetwork() throws Exception { + public void matchThreeGPPNetworkWithNAIRealmMismatch() throws Exception { String testImsi = "1234567890"; - + String testRealm = "realm.com"; // Setup test provider. PasspointConfiguration config = new PasspointConfiguration(); config.setHomeSp(new HomeSp()); @@ -597,84 +793,84 @@ public class PasspointProviderTest { anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork, createThreeGPPNetworkElement(new String[] {"123456"})); + // Setup NAI Realm ANQP element with different realm. + anqpElementMap.put(ANQPElementType.ANQPNAIRealm, + createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS, + new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2))); + assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap, mRoamingConsortium)); } /** - * Verify that a provider is a roaming provider when its credential matches a NAI realm in - * the NAI Realm ANQP element. + * Verify that a provider is a roaming provider when the provider's IMSI parameter and an IMSI + * from the SIM card matches a MCC-MNC in the 3GPP Network ANQP element regardless of NAI realm + * match. * * @throws Exception */ @Test - public void matchNAIRealm() throws Exception { + public void matchThreeGPPNetworkWithNAIRealmMatch() throws Exception { + String testImsi = "1234567890"; String testRealm = "realm.com"; - // Setup test provider. PasspointConfiguration config = new PasspointConfiguration(); config.setHomeSp(new HomeSp()); Credential credential = new Credential(); - credential.setRealm(testRealm); - Credential.UserCredential userCredential = new Credential.UserCredential(); - userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2); - credential.setUserCredential(userCredential); + Credential.SimCredential simCredential = new Credential.SimCredential(); + simCredential.setImsi(testImsi); + credential.setSimCredential(simCredential); config.setCredential(credential); + credential.setRealm(testRealm); + when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false))) + .thenReturn(Arrays.asList(new String[] {testImsi})); mProvider = createProvider(config); - // Setup NAI Realm ANQP element. + // Setup 3GPP Network ANQP element. Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork, + createThreeGPPNetworkElement(new String[] {"123456"})); + + // Setup NAI Realm ANQP element with same realm. anqpElementMap.put(ANQPElementType.ANQPNAIRealm, - createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS, - new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2))); + createNAIRealmElement(testRealm, EAPConstants.EAP_AKA, null)); assertEquals(PasspointMatch.RoamingProvider, - mProvider.match(anqpElementMap, mRoamingConsortium)); + mProvider.match(anqpElementMap, mRoamingConsortium)); } /** - * Verify that a provider is a home provider when its FQDN, roaming consortium OI, and - * IMSI all matched against the ANQP elements, since we prefer matching home provider over - * roaming provider. + * Verify that a provider is a roaming provider when its credential only matches a NAI realm in + * the NAI Realm ANQP element and not match for Domain Name, RoamingConsortium and 3GPP. * * @throws Exception */ @Test - public void matchHomeOverRoamingProvider() throws Exception { - // Setup test data. - String testDomain = "test.com"; - String testImsi = "1234567890"; - long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; - Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L}; + public void matchOnlyNAIRealmWithOtherInformationMismatch() throws Exception { + String testRealm = "realm.com"; // Setup test provider. PasspointConfiguration config = new PasspointConfiguration(); - HomeSp homeSp = new HomeSp(); - homeSp.setFqdn(testDomain); - homeSp.setRoamingConsortiumOis(providerRCOIs); - config.setHomeSp(homeSp); + config.setHomeSp(new HomeSp()); Credential credential = new Credential(); - Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi(testImsi); - credential.setSimCredential(simCredential); + credential.setRealm(testRealm); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2); + credential.setUserCredential(userCredential); config.setCredential(credential); - when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false))) - .thenReturn(Arrays.asList(new String[] {testImsi})); mProvider = createProvider(config); - // Setup ANQP elements. + // Setup NAI Realm ANQP element. Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); - anqpElementMap.put(ANQPElementType.ANQPDomName, - createDomainNameElement(new String[] {testDomain})); - anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, - createRoamingConsortiumElement(anqpRCOIs)); - anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork, - createThreeGPPNetworkElement(new String[] {"123456"})); + anqpElementMap.put(ANQPElementType.ANQPNAIRealm, + createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS, + new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2))); - assertEquals(PasspointMatch.HomeProvider, + assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap, mRoamingConsortium)); } + /** * Verify that an expected WifiConfiguration will be returned for a Passpoint provider * with an user credential. |