blob: 4d4ea44873d351c18d6bc8cc65bbbafc752f4783 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi.hotspot2;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.net.wifi.EAPConstants;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.IMSIParameter;
import com.android.server.wifi.hotspot2.anqp.CellularNetwork;
import com.android.server.wifi.hotspot2.anqp.DomainNameElement;
import com.android.server.wifi.hotspot2.anqp.NAIRealmData;
import com.android.server.wifi.hotspot2.anqp.NAIRealmElement;
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;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Unit tests for {@link com.android.server.wifi.hotspot2.ANQPMatcher}.
*/
@SmallTest
public class ANQPMatcherTest {
private static final String TEST_MCC_MNC = "123456";
private static final String TEST_3GPP_FQDN = String.format("wlan.mnc%s.mcc%s.3gppnetwork.org",
TEST_MCC_MNC.substring(3), TEST_MCC_MNC.substring(0, 3));
/**
* Verify that domain name match will fail when a null Domain Name ANQP element is provided.
*
* @throws Exception
*/
@Test
public void matchDomainNameWithNullElement() throws Exception {
assertFalse(ANQPMatcher.matchDomainName(null, "test.com", null, null));
}
/**
* Verify that domain name match will succeed when the specified FQDN matches a domain name
* in the Domain Name ANQP element.
*
* @throws Exception
*/
@Test
public void matchDomainNameUsingFQDN() throws Exception {
String fqdn = "test.com";
String[] domains = new String[] {fqdn};
DomainNameElement element = new DomainNameElement(Arrays.asList(domains));
assertTrue(ANQPMatcher.matchDomainName(element, fqdn, null, null));
}
/**
* Verify that domain name match will succeed when the specified IMSI parameter and IMSI list
* matches a 3GPP network domain in the Domain Name ANQP element.
*
* @throws Exception
*/
@Test
public void matchDomainNameUsingIMSI() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
List<String> simImsiList = Arrays.asList(new String[] {"123457890", "123498723"});
// 3GPP network domain with MCC=123 and MNC=456.
String[] domains = new String[] {"wlan.mnc457.mcc123.3gppnetwork.org"};
DomainNameElement element = new DomainNameElement(Arrays.asList(domains));
assertTrue(ANQPMatcher.matchDomainName(element, null, imsiParam, simImsiList));
}
/**
* Verify that roaming consortium match will fail when a null Roaming Consortium ANQP
* element is provided.
*
* @throws Exception
*/
@Test
public void matchRoamingConsortiumWithNullElement() throws Exception {
assertFalse(ANQPMatcher.matchRoamingConsortium(null, new long[0]));
}
/**
* Verify that a roaming consortium match will succeed when the specified OI matches
* an OI in the Roaming Consortium ANQP element.
*
* @throws Exception
*/
@Test
public void matchRoamingConsortium() throws Exception {
long oi = 0x1234L;
RoamingConsortiumElement element =
new RoamingConsortiumElement(Arrays.asList(new Long[] {oi}));
assertTrue(ANQPMatcher.matchRoamingConsortium(element, new long[] {oi}));
}
/**
* Verify that an indeterminate 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)));
}
/**
* Verify that an indeterminate match will be returned when matching a NAI Realm
* ANQP element contained no NAI realm data.
*
* @throws Exception
*/
@Test
public void matchNAIRealmWithEmtpyRealmData() throws Exception {
NAIRealmElement element = new NAIRealmElement(new ArrayList<NAIRealmData>());
assertEquals(AuthMatch.INDETERMINATE, ANQPMatcher.matchNAIRealm(element, "test.com",
EAPConstants.EAP_TLS, null));
}
/**
* Verify that a realm match will be returned when the specified realm matches a realm
* in the NAI Realm ANQP element with no EAP methods.
*
* @throws Exception
*/
@Test
public void matchNAIRealmWithRealmMatch() throws Exception {
String realm = "test.com";
NAIRealmData realmData = new NAIRealmData(
Arrays.asList(new String[] {realm}), new ArrayList<EAPMethod>());
NAIRealmElement element = new NAIRealmElement(
Arrays.asList(new NAIRealmData[] {realmData}));
assertEquals(AuthMatch.REALM, ANQPMatcher.matchNAIRealm(element, realm,
EAPConstants.EAP_TLS, null));
}
/**
* 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<Integer, Set<AuthParam>>());
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
* method matches a realm in the NAI Realm ANQP element.
*
* @throws Exception
*/
@Test
public void matchNAIRealmWithRealmMethodMatch() throws Exception {
// Test data.
String realm = "test.com";
int eapMethodID = EAPConstants.EAP_TLS;
// Setup NAI Realm element.
EAPMethod method = new EAPMethod(eapMethodID, new HashMap<Integer, Set<AuthParam>>());
NAIRealmData realmData = new NAIRealmData(
Arrays.asList(new String[] {realm}), Arrays.asList(new EAPMethod[] {method}));
NAIRealmElement element = new NAIRealmElement(
Arrays.asList(new NAIRealmData[] {realmData}));
assertEquals(AuthMatch.REALM | AuthMatch.METHOD,
ANQPMatcher.matchNAIRealm(element, realm, eapMethodID, null));
}
/**
* Verify that an exact 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.
*
* @throws Exception
*/
@Test
public void matchNAIRealmWithExactMatch() throws Exception {
// Test data.
String realm = "test.com";
int eapMethodID = EAPConstants.EAP_TTLS;
NonEAPInnerAuth authParam = new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAP);
Set<AuthParam> authSet = new HashSet<>();
authSet.add(authParam);
Map<Integer, Set<AuthParam>> authMap = new HashMap<>();
authMap.put(authParam.getAuthTypeID(), authSet);
// Setup NAI Realm element.
EAPMethod method = new EAPMethod(eapMethodID, authMap);
NAIRealmData realmData = new NAIRealmData(
Arrays.asList(new String[] {realm}), Arrays.asList(new EAPMethod[] {method}));
NAIRealmElement element = new NAIRealmElement(
Arrays.asList(new NAIRealmData[] {realmData}));
assertEquals(AuthMatch.EXACT,
ANQPMatcher.matchNAIRealm(element, realm, eapMethodID, authParam));
}
/**
* Verify that a mismatch (AuthMatch.NONE) will be returned when the specified EAP method
* doesn't match with the corresponding EAP method in the NAI Realm ANQP element.
*
* @throws Exception
*/
@Test
public void matchNAIRealmWithEAPMethodMismatch() throws Exception {
// Test data.
String realm = "test.com";
int eapMethodID = EAPConstants.EAP_TTLS;
NonEAPInnerAuth authParam = new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAP);
Set<AuthParam> authSet = new HashSet<>();
authSet.add(authParam);
Map<Integer, Set<AuthParam>> authMap = new HashMap<>();
authMap.put(authParam.getAuthTypeID(), authSet);
// Setup NAI Realm element.
EAPMethod method = new EAPMethod(eapMethodID, authMap);
NAIRealmData realmData = new NAIRealmData(
Arrays.asList(new String[] {realm}), Arrays.asList(new EAPMethod[] {method}));
NAIRealmElement element = new NAIRealmElement(
Arrays.asList(new NAIRealmData[] {realmData}));
assertEquals(AuthMatch.NONE,
ANQPMatcher.matchNAIRealm(element, realm, EAPConstants.EAP_TLS, null));
}
/**
* Verify that a mismatch (AuthMatch.NONE) will be returned when the specified authentication
* parameter doesn't match with the corresponding authentication parameter in the NAI Realm
* ANQP element.
*
* @throws Exception
*/
@Test
public void matchNAIRealmWithAuthTypeMismatch() throws Exception {
// Test data.
String realm = "test.com";
int eapMethodID = EAPConstants.EAP_TTLS;
NonEAPInnerAuth authParam = new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAP);
Set<AuthParam> authSet = new HashSet<>();
authSet.add(authParam);
Map<Integer, Set<AuthParam>> authMap = new HashMap<>();
authMap.put(authParam.getAuthTypeID(), authSet);
// Setup NAI Realm element.
EAPMethod method = new EAPMethod(eapMethodID, authMap);
NAIRealmData realmData = new NAIRealmData(
Arrays.asList(new String[] {realm}), Arrays.asList(new EAPMethod[] {method}));
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)));
}
/**
* Verify that 3GPP Network match will fail when a null element is provided.
*
* @throws Exception
*/
@Test
public void matchThreeGPPNetworkWithNullElement() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
List<String> simImsiList = Arrays.asList(new String[] {"123456789", "123498723"});
assertFalse(ANQPMatcher.matchThreeGPPNetwork(null, imsiParam, simImsiList));
}
/**
* Verify that 3GPP network will succeed when the given 3GPP Network ANQP element contained
* a MCC-MNC that matches the both IMSI parameter and an IMSI from the IMSI list.
*
* @throws Exception
*/
@Test
public void matchThreeGPPNetwork() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
List<String> simImsiList = Arrays.asList(new String[] {"123456789", "123498723"});
CellularNetwork network = new CellularNetwork(Arrays.asList(new String[] {"123456"}));
ThreeGPPNetworkElement element =
new ThreeGPPNetworkElement(Arrays.asList(new CellularNetwork[] {network}));
// The MCC-MNC provided in 3GPP Network ANQP element matches both IMSI parameter
// and an IMSI from the installed SIM card.
assertTrue(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsiList));
}
/**
* Verify that 3GPP network will failed when the given 3GPP Network ANQP element contained
* a MCC-MNC that match the IMSI parameter but not the IMSI list.
*
* @throws Exception
*/
@Test
public void matchThreeGPPNetworkWithoutSimImsiMatch() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
List<String> simImsiList = Arrays.asList(new String[] {"123457890", "123498723"});
CellularNetwork network = new CellularNetwork(Arrays.asList(new String[] {"123456"}));
ThreeGPPNetworkElement element =
new ThreeGPPNetworkElement(Arrays.asList(new CellularNetwork[] {network}));
// The MCC-MNC provided in 3GPP Network ANQP element doesn't match any of the IMSIs
// from the installed SIM card.
assertFalse(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsiList));
}
/**
* Verify that 3GPP network will failed when the given 3GPP Network ANQP element contained
* a MCC-MNC that doesn't match with the IMSI parameter.
*
* @throws Exception
*/
@Test
public void matchThreeGPPNetworkWithImsiParamMismatch() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
List<String> simImsiList = Arrays.asList(new String[] {"123457890", "123498723"});
CellularNetwork network = new CellularNetwork(Arrays.asList(new String[] {"123356"}));
ThreeGPPNetworkElement element =
new ThreeGPPNetworkElement(Arrays.asList(new CellularNetwork[] {network}));
// The MCC-MNC provided in 3GPP Network ANQP element doesn't match the IMSI parameter.
assertFalse(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsiList));
}
/**
* Verify that it will return a EAP-Method from the NAI realm when there is a matched realm in
* the NAIRealm element.
*/
@Test
public void getEapMethodForNAIRealmWithCarrierInMatch() {
// Test data.
String realm = TEST_3GPP_FQDN;
int eapMethodID = EAPConstants.EAP_AKA;
// Create a realm that has the EAP method
EAPMethod method = new EAPMethod(eapMethodID, null);
NAIRealmData realmData = new NAIRealmData(
Arrays.asList(new String[]{realm}), Arrays.asList(new EAPMethod[]{method}));
// Setup NAI Realm element.
NAIRealmElement element = new NAIRealmElement(
Arrays.asList(new NAIRealmData[]{realmData}));
assertEquals(EAPConstants.EAP_AKA,
ANQPMatcher.getCarrierEapMethodFromMatchingNAIRealm(TEST_3GPP_FQDN, element));
}
/**
* Verify that it will return -1 when there is a matched realm in the NAIRealm element, but it
* does not have a EAP Method.
*/
@Test
public void getEapMethodForNAIRealmWithCarrierInMatchButNotEapMethod() {
// Test data.
String realm = TEST_3GPP_FQDN;
NAIRealmData realmData = new NAIRealmData(Arrays.asList(new String[]{realm}),
new ArrayList<>());
// Setup NAI Realm element.
NAIRealmElement element = new NAIRealmElement(
Arrays.asList(new NAIRealmData[]{realmData}));
assertEquals(-1,
ANQPMatcher.getCarrierEapMethodFromMatchingNAIRealm(TEST_3GPP_FQDN, element));
}
/**
* Verify that it will return -1 when there is a matched realm in the NAIRealm element, but it
* does have non-carrier EAP-method.
*/
@Test
public void getEapMethodForNAIRealmWithCarrierInMatchButNotCarrierEapMethod() {
// Test data.
String realm = TEST_3GPP_FQDN;
int eapMethodID = EAPConstants.EAP_TTLS;
NonEAPInnerAuth authParam = new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAP);
Set<AuthParam> authSet = new HashSet<>();
authSet.add(authParam);
Map<Integer, Set<AuthParam>> authMap = new HashMap<>();
authMap.put(authParam.getAuthTypeID(), authSet);
// Setup NAI Realm element.
EAPMethod method = new EAPMethod(eapMethodID, authMap);
NAIRealmData realmData = new NAIRealmData(
Arrays.asList(new String[]{realm}), Arrays.asList(new EAPMethod[]{method}));
NAIRealmElement element = new NAIRealmElement(
Arrays.asList(new NAIRealmData[]{realmData}));
assertEquals(-1,
ANQPMatcher.getCarrierEapMethodFromMatchingNAIRealm(TEST_3GPP_FQDN, element));
}
/**
* Verify that it will return -1 when there is no matched realm in the NAIRealm element.
*/
@Test
public void getEapMethodForNAIRealmWithCarrierInNoMatch() {
// Test data.
String realm = "test.com";
int eapMethodID = EAPConstants.EAP_TTLS;
NonEAPInnerAuth authParam = new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAP);
Set<AuthParam> authSet = new HashSet<>();
authSet.add(authParam);
Map<Integer, Set<AuthParam>> authMap = new HashMap<>();
authMap.put(authParam.getAuthTypeID(), authSet);
// Setup NAI Realm element.
EAPMethod method = new EAPMethod(eapMethodID, authMap);
NAIRealmData realmData = new NAIRealmData(
Arrays.asList(new String[]{realm}), Arrays.asList(new EAPMethod[]{method}));
NAIRealmElement element = new NAIRealmElement(
Arrays.asList(new NAIRealmData[]{realmData}));
assertEquals(-1,
ANQPMatcher.getCarrierEapMethodFromMatchingNAIRealm(TEST_3GPP_FQDN, element));
}
}