16a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistpackage com.android.server.wifi.anqp; 26a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 36a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport com.android.server.wifi.anqp.eap.EAPMethod; 471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport com.android.server.wifi.hotspot2.AuthMatch; 5866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvistimport com.android.server.wifi.hotspot2.Utils; 6866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvistimport com.android.server.wifi.hotspot2.pps.Credential; 7866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvistimport com.android.server.wifi.hotspot2.pps.DomainMatcher; 86a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 96a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.net.ProtocolException; 106a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.nio.ByteBuffer; 116a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.nio.charset.StandardCharsets; 126a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.ArrayList; 136a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.Collections; 146a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.List; 156a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 166a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist/** 176a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist * The NAI Realm Data ANQP sub-element, IEEE802.11-2012 section 8.4.4.10 figure 8-418 186a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist */ 196a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistpublic class NAIRealmData { 206a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist private final List<String> mRealms; 216a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist private final List<EAPMethod> mEAPMethods; 226a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 236a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist public NAIRealmData(ByteBuffer payload) throws ProtocolException { 246a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist if (payload.remaining() < 5) { 256a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist throw new ProtocolException("Runt payload: " + payload.remaining()); 266a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 276a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 286a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist int length = payload.getShort() & Constants.SHORT_MASK; 296a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist if (length > payload.remaining()) { 306a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist throw new ProtocolException("Invalid data length: " + length); 316a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 326a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist boolean utf8 = (payload.get() & 1) == Constants.UTF8_INDICATOR; 336a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 346a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist String realm = Constants.getPrefixedString(payload, 1, utf8 ? 356a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist StandardCharsets.UTF_8 : 366a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist StandardCharsets.US_ASCII); 376a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist String[] realms = realm.split(";"); 38866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist mRealms = new ArrayList<>(); 396a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist for (String realmElement : realms) { 406a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist if (realmElement.length() > 0) { 416a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist mRealms.add(realmElement); 426a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 436a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 446a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 456a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist int methodCount = payload.get() & Constants.BYTE_MASK; 46866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist mEAPMethods = new ArrayList<>(methodCount); 476a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist while (methodCount > 0) { 486a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist mEAPMethods.add(new EAPMethod(payload)); 496a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist methodCount--; 506a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 516a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 526a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 536a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist public List<String> getRealms() { 546a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist return Collections.unmodifiableList(mRealms); 556a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 566a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 576a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist public List<EAPMethod> getEAPMethods() { 586a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist return Collections.unmodifiableList(mEAPMethods); 596a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 606a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 61c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist public int match(List<String> credLabels, Credential credential) { 62c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist int realmMatch = AuthMatch.None; 63866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist if (!mRealms.isEmpty()) { 64866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist for (String realm : mRealms) { 65866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist List<String> labels = Utils.splitDomain(realm); 66866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist if (DomainMatcher.arg2SubdomainOfArg1(credLabels, labels)) { 67c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist realmMatch = AuthMatch.Realm; 68866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist break; 69866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist } 70866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist } 71c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist if (realmMatch == AuthMatch.None || mEAPMethods.isEmpty()) { 72c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist return realmMatch; 73866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist } 74866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist // else there is a realm match and one or more EAP methods - check them. 75866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist } 76866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist else if (mEAPMethods.isEmpty()) { 77866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist return AuthMatch.Indeterminate; 7871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist } 7971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist 80c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist int best = AuthMatch.None; 81866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist for (EAPMethod eapMethod : mEAPMethods) { 82c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist int match = eapMethod.match(credential) | realmMatch; 83c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist if (match > best) { 8471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist best = match; 85866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist if (best == AuthMatch.Exact) { 86866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist return best; 8771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist } 8871a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist } 8971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist } 9071a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist return best; 9171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist } 9271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist 936a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist @Override 946a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist public String toString() { 957b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist StringBuilder sb = new StringBuilder(); 967b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist 977b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist sb.append(" NAI Realm(s)"); 987b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist for (String realm : mRealms) { 997b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist sb.append(' ').append(realm); 1007b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist } 1017b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist sb.append('\n'); 1027b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist 1037b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist for (EAPMethod eapMethod : mEAPMethods) { 1047b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist sb.append( " " ).append(eapMethod.toString()); 1057b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist } 1067b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist return sb.toString(); 1076a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 1086a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist} 109