From 4354285b8de3345d5146f68ce2d17be83b4f34a4 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 11 Mar 2020 13:57:36 -0700 Subject: [Passpoint] Fix Passpoint matching algorithm for Home networks Match Home networks if there is an FQDN match (without realm or method), or if OtherHomePartners element exists and matches the other advertised FQDNs, or if HomeOIList element exists and matches advertised RCOIs. Bug: 151245024 Test: atest PasspointProviderTest ANQPMatcherTest Change-Id: I7bf9c98c853c3973d30ce2651bdea49546dae4b5 Merged-In: I513f83a6d545b9ae7da5577ee163ce7d186f006e --- .../server/wifi/hotspot2/ANQPMatcherTest.java | 127 ++++++++------ .../wifi/hotspot2/PasspointProviderTest.java | 189 ++++++++++++++++++++- 2 files changed, 256 insertions(+), 60 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java index 4d4ea4487..df9c332a3 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java @@ -33,7 +33,6 @@ import com.android.server.wifi.hotspot2.anqp.RoamingConsortiumElement; 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.InnerAuthEAP; import com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth; import org.junit.Test; @@ -102,7 +101,7 @@ public class ANQPMatcherTest { */ @Test public void matchRoamingConsortiumWithNullElement() throws Exception { - assertFalse(ANQPMatcher.matchRoamingConsortium(null, new long[0])); + assertFalse(ANQPMatcher.matchRoamingConsortium(null, new long[0], false)); } /** @@ -116,23 +115,22 @@ public class ANQPMatcherTest { long oi = 0x1234L; RoamingConsortiumElement element = new RoamingConsortiumElement(Arrays.asList(new Long[] {oi})); - assertTrue(ANQPMatcher.matchRoamingConsortium(element, new long[] {oi})); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, new long[] {oi}, false)); } /** - * Verify that an indeterminate match will be returned when matching a null NAI Realm + * Verify that no match will be returned when matching a null NAI Realm * ANQP element. * * @throws Exception */ @Test public void matchNAIRealmWithNullElement() throws Exception { - assertEquals(AuthMatch.INDETERMINATE, ANQPMatcher.matchNAIRealm(null, "test.com", - EAPConstants.EAP_TLS, new InnerAuthEAP(EAPConstants.EAP_TTLS))); + assertFalse(ANQPMatcher.matchNAIRealm(null, "test.com")); } /** - * Verify that an indeterminate match will be returned when matching a NAI Realm + * Verify that no match will be returned when matching a NAI Realm * ANQP element contained no NAI realm data. * * @throws Exception @@ -140,8 +138,7 @@ public class ANQPMatcherTest { @Test public void matchNAIRealmWithEmtpyRealmData() throws Exception { NAIRealmElement element = new NAIRealmElement(new ArrayList()); - assertEquals(AuthMatch.INDETERMINATE, ANQPMatcher.matchNAIRealm(element, "test.com", - EAPConstants.EAP_TLS, null)); + assertFalse(ANQPMatcher.matchNAIRealm(element, "test.com")); } /** @@ -157,38 +154,11 @@ public class ANQPMatcherTest { Arrays.asList(new String[] {realm}), new ArrayList()); NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - assertEquals(AuthMatch.REALM, ANQPMatcher.matchNAIRealm(element, realm, - EAPConstants.EAP_TLS, null)); + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** - * Verify that method match will be returned when the specified EAP - * method only matches a eap method in the NAI Realm ANQP element if the element does not have - * auth params. - * - * @throws Exception - */ - @Test - public void matchNAIRealmWithMethodMatch() throws Exception { - // Test data. - String providerRealm = "test.com"; - String anqpRealm = "test2.com"; - NonEAPInnerAuth authParam = new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAP); - int eapMethodID = EAPConstants.EAP_TLS; - - // Setup NAI Realm element that has EAP method and no auth params. - EAPMethod method = new EAPMethod(eapMethodID, new HashMap>()); - NAIRealmData realmData = new NAIRealmData( - Arrays.asList(new String[]{anqpRealm}), Arrays.asList(new EAPMethod[]{method})); - NAIRealmElement element = new NAIRealmElement( - Arrays.asList(new NAIRealmData[]{realmData})); - - assertEquals(AuthMatch.METHOD, - ANQPMatcher.matchNAIRealm(element, providerRealm, eapMethodID, authParam)); - } - - /** - * Verify that a realm and method match will be returned when the specified realm and EAP + * Verify that a realm match will be returned when the specified realm and EAP * method matches a realm in the NAI Realm ANQP element. * * @throws Exception @@ -206,12 +176,11 @@ public class ANQPMatcherTest { NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - assertEquals(AuthMatch.REALM | AuthMatch.METHOD, - ANQPMatcher.matchNAIRealm(element, realm, eapMethodID, null)); + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** - * Verify that an exact match will be returned when the specified realm, EAP + * Verify that a realm match will be returned when the specified realm, EAP * method, and the authentication parameter matches a realm with the associated EAP method and * authentication parameter in the NAI Realm ANQP element. * @@ -235,12 +204,11 @@ public class ANQPMatcherTest { NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - assertEquals(AuthMatch.EXACT, - ANQPMatcher.matchNAIRealm(element, realm, eapMethodID, authParam)); + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** - * Verify that a mismatch (AuthMatch.NONE) will be returned when the specified EAP method + * Verify that a realm match will be returned when the specified EAP method * doesn't match with the corresponding EAP method in the NAI Realm ANQP element. * * @throws Exception @@ -263,12 +231,11 @@ public class ANQPMatcherTest { NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - assertEquals(AuthMatch.NONE, - ANQPMatcher.matchNAIRealm(element, realm, EAPConstants.EAP_TLS, null)); + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** - * Verify that a mismatch (AuthMatch.NONE) will be returned when the specified authentication + * Verify that a realm match will be returned when the specified authentication * parameter doesn't match with the corresponding authentication parameter in the NAI Realm * ANQP element. * @@ -292,10 +259,8 @@ public class ANQPMatcherTest { NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - // Mismatch in authentication type. - assertEquals(AuthMatch.NONE, - ANQPMatcher.matchNAIRealm(element, realm, EAPConstants.EAP_TTLS, - new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_PAP))); + // Mismatch in authentication type which we ignore. + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** @@ -458,4 +423,64 @@ public class ANQPMatcherTest { assertEquals(-1, ANQPMatcher.getCarrierEapMethodFromMatchingNAIRealm(TEST_3GPP_FQDN, element)); } + + /** + * Verify that match is found when HomeOI contains some of the RCOIs advertised by an AP marked + * as not required. + * + * @throws Exception + */ + @Test + public void matchAnyHomeOi() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, providerOis, false)); + } + + /** + * Verify that no match is found when HomeOI does not contain any of the RCOIs advertised by an + * AP marked as not required. + * + * @throws Exception + */ + @Test + public void matchAnyHomeOiNegative() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0xabc2L, 0x1232L}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertFalse(ANQPMatcher.matchRoamingConsortium(element, providerOis, false)); + } + + /** + * Verify that match is found when HomeOI contains all of the RCOIs advertised by an AP marked + * as required. + * + * @throws Exception + */ + @Test + public void matchAllHomeOi() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xabcdL, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, providerOis, true)); + } + + /** + * Verify that match is not found when HomeOI does not contain all of the RCOIs advertised by an + * AP marked as required. + * + * @throws Exception + */ + @Test + public void matchAllHomeOiNegative() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertFalse(ANQPMatcher.matchRoamingConsortium(element, providerOis, true)); + } } 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 31229c562..c35d67301 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java @@ -478,9 +478,10 @@ public class PasspointProviderTest { } /** - * Verify that there is no match when the provider's FQDN matches a domain name in the - * Domain Name ANQP element but the provider's credential doesn't match the authentication - * method provided in the NAI realm. + * Verify that Home provider is matched even when the provider's FQDN matches a domain name in + * the Domain Name ANQP element but the provider's credential doesn't match the authentication + * method provided in the NAI realm. This can happen when the infrastructure provider is not + * the identity provider, and authentication method matching is not required in the spec. * * @throws Exception */ @@ -509,7 +510,8 @@ public class PasspointProviderTest { anqpElementMap.put(ANQPElementType.ANQPNAIRealm, createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); - assertEquals(PasspointMatch.None, mProvider.match(anqpElementMap, mRoamingConsortium)); + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); } /** @@ -657,8 +659,8 @@ public class PasspointProviderTest { } /** - * 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. + * Verify that there is Roaming provider match when a roaming consortium OI matches an OI + * in the roaming consortium ANQP element and regardless of NAI realm mismatch. * * @throws Exception */ @@ -689,7 +691,7 @@ public class PasspointProviderTest { anqpElementMap.put(ANQPElementType.ANQPNAIRealm, createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); - assertEquals(PasspointMatch.None, + assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap, mRoamingConsortium)); } @@ -766,8 +768,14 @@ public class PasspointProviderTest { } /** - * Verify that there is no match when a roaming consortium OI matches an OI + * Verify that there is Roaming provider match when a roaming consortium OI matches an OI * in the roaming consortium information element, but NAI realm is not matched. + * This can happen in roaming federation where the infrastructure provider is not the + * identity provider. + * Page 133 in the Hotspot2.0 specification states: + * Per subclause 11.25.8 of [2], if the value of HomeOI matches an OI in the Roaming + * Consortium advertised by a hotspot operator, successful authentication with that hotspot + * is possible. * * @throws Exception */ @@ -799,7 +807,7 @@ public class PasspointProviderTest { anqpElementMap.put(ANQPElementType.ANQPNAIRealm, createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); - assertEquals(PasspointMatch.None, + assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap, mRoamingConsortium)); } @@ -1354,4 +1362,167 @@ public class PasspointProviderTest { mProvider.setHasEverConnected(true); assertTrue(mProvider.getHasEverConnected()); } + + /** + * Verify that an expected WifiConfiguration will be returned for a Passpoint provider + * with a user credential. + * + * @throws Exception + */ + @Test + public void matchOtherPartnersDomainName() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setOtherHomePartners(new String [] {"test3.com"}); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that matching Any HomeOI results in a Home Provider match + * + * @throws Exception + */ + @Test + public void matchAnyHomeOi() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setMatchAnyOis(new long[] {0x1234L, 0x2345L}); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + Long[] anqpOis = new Long[] {0x1234L, 0xdeadL, 0xf0cdL}; + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that non-matching Any HomeOI results in a None Provider match + * + * @throws Exception + */ + @Test + public void matchAnyHomeOiNegative() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setMatchAnyOis(new long[] {0x1234L, 0x2345L}); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + Long[] anqpOis = new Long[] {0x12a4L, 0xceadL, 0xf0cdL}; + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.None, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that matching All HomeOI results in a Home Provider match + * + * @throws Exception + */ + @Test + public void matchAllHomeOi() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setMatchAllOis(new long[] {0x1234L, 0x2345L}); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + Long[] anqpOis = new Long[] {0x1234L, 0x2345L, 0xabcdL, 0xdeadL, 0xf0cdL}; + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that non-matching All HomeOI results in a None Provider match + * + * @throws Exception + */ + @Test + public void matchAllHomeOiNegative() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setMatchAllOis(new long[] {0x1234L, 0x2345L}); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + + // 0x1234 matches, but 0x2345 does not + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.None, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } } -- cgit v1.2.3