Home | History | Annotate | Download | only in anqp
      1 package com.android.server.wifi.anqp;
      2 
      3 import com.android.server.wifi.anqp.eap.EAPMethod;
      4 import com.android.server.wifi.hotspot2.AuthMatch;
      5 import com.android.server.wifi.hotspot2.Utils;
      6 import com.android.server.wifi.hotspot2.pps.Credential;
      7 import com.android.server.wifi.hotspot2.pps.DomainMatcher;
      8 
      9 import java.net.ProtocolException;
     10 import java.nio.ByteBuffer;
     11 import java.nio.charset.StandardCharsets;
     12 import java.util.ArrayList;
     13 import java.util.Collections;
     14 import java.util.List;
     15 
     16 /**
     17  * The NAI Realm Data ANQP sub-element, IEEE802.11-2012 section 8.4.4.10 figure 8-418
     18  */
     19 public class NAIRealmData {
     20     private final List<String> mRealms;
     21     private final List<EAPMethod> mEAPMethods;
     22 
     23     public NAIRealmData(ByteBuffer payload) throws ProtocolException {
     24         if (payload.remaining() < 5) {
     25             throw new ProtocolException("Runt payload: " + payload.remaining());
     26         }
     27 
     28         int length = payload.getShort() & Constants.SHORT_MASK;
     29         if (length > payload.remaining()) {
     30             throw new ProtocolException("Invalid data length: " + length);
     31         }
     32         boolean utf8 = (payload.get() & 1) == Constants.UTF8_INDICATOR;
     33 
     34         String realm = Constants.getPrefixedString(payload, 1, utf8 ?
     35                 StandardCharsets.UTF_8 :
     36                 StandardCharsets.US_ASCII);
     37         String[] realms = realm.split(";");
     38         mRealms = new ArrayList<>();
     39         for (String realmElement : realms) {
     40             if (realmElement.length() > 0) {
     41                 mRealms.add(realmElement);
     42             }
     43         }
     44 
     45         int methodCount = payload.get() & Constants.BYTE_MASK;
     46         mEAPMethods = new ArrayList<>(methodCount);
     47         while (methodCount > 0) {
     48             mEAPMethods.add(new EAPMethod(payload));
     49             methodCount--;
     50         }
     51     }
     52 
     53     public List<String> getRealms() {
     54         return Collections.unmodifiableList(mRealms);
     55     }
     56 
     57     public List<EAPMethod> getEAPMethods() {
     58         return Collections.unmodifiableList(mEAPMethods);
     59     }
     60 
     61     public int match(List<String> credLabels, Credential credential) {
     62         int realmMatch = AuthMatch.None;
     63         if (!mRealms.isEmpty()) {
     64             for (String realm : mRealms) {
     65                 List<String> labels = Utils.splitDomain(realm);
     66                 if (DomainMatcher.arg2SubdomainOfArg1(credLabels, labels)) {
     67                     realmMatch = AuthMatch.Realm;
     68                     break;
     69                 }
     70             }
     71             if (realmMatch == AuthMatch.None || mEAPMethods.isEmpty()) {
     72                 return realmMatch;
     73             }
     74             // else there is a realm match and one or more EAP methods - check them.
     75         }
     76         else if (mEAPMethods.isEmpty()) {
     77             return AuthMatch.Indeterminate;
     78         }
     79 
     80         int best = AuthMatch.None;
     81         for (EAPMethod eapMethod : mEAPMethods) {
     82             int match = eapMethod.match(credential) | realmMatch;
     83             if (match > best) {
     84                 best = match;
     85                 if (best == AuthMatch.Exact) {
     86                     return best;
     87                 }
     88             }
     89         }
     90         return best;
     91     }
     92 
     93     @Override
     94     public String toString() {
     95         StringBuilder sb = new StringBuilder();
     96 
     97         sb.append("  NAI Realm(s)");
     98         for (String realm : mRealms) {
     99             sb.append(' ').append(realm);
    100         }
    101         sb.append('\n');
    102 
    103         for (EAPMethod eapMethod : mEAPMethods) {
    104             sb.append( "    " ).append(eapMethod.toString());
    105         }
    106         return sb.toString();
    107     }
    108 }
    109