1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  *
  27  *  (C) Copyright IBM Corp. 1999 All Rights Reserved.
  28  *  Copyright 1997 The Open Group Research Institute.  All rights reserved.
  29  */
  30 
  31 package sun.security.krb5.internal;
  32 
  33 import sun.security.krb5.Asn1Exception;
  34 import sun.security.krb5.internal.util.KerberosFlags;
  35 import sun.security.util.*;
  36 import java.io.IOException;
  37 
  38 /**
  39  * Implements the ASN.1TicketFlags type.
  40  *
  41  *    TicketFlags ::= BIT STRING
  42  *                  {
  43  *                   reserved(0),
  44  *                   forwardable(1),
  45  *                   forwarded(2),
  46  *                   proxiable(3),
  47  *                   proxy(4),
  48  *                   may-postdate(5),
  49  *                   postdated(6),
  50  *                   invalid(7),
  51  *                   renewable(8),
  52  *                   initial(9),
  53  *                   pre-authent(10),
  54  *                   hw-authent(11),
  55  *                   enc-pa-rep(15)
  56  *                  }
  57  */
  58 public class TicketFlags extends KerberosFlags {
  59     public TicketFlags() {
  60         super(Krb5.TKT_OPTS_MAX + 1);
  61     }
  62 
  63     public TicketFlags (boolean[] flags) throws Asn1Exception {
  64         super(flags);
  65         if (flags.length > Krb5.TKT_OPTS_MAX + 1) {
  66             throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
  67         }
  68     }
  69 
  70     public TicketFlags(int size, byte[] data) throws Asn1Exception {
  71         super(size, data);
  72         if ((size > data.length * BITS_PER_UNIT) || (size > Krb5.TKT_OPTS_MAX + 1))
  73             throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
  74     }
  75 
  76     public TicketFlags(DerValue encoding) throws IOException, Asn1Exception {
  77         this(encoding.getUnalignedBitString(true).toBooleanArray());
  78     }
  79 
  80     /**
  81      * Parse (unmarshal) a ticket flag from a DER input stream.  This form
  82      * parsing might be used when expanding a value which is part of
  83      * a constructed sequence and uses explicitly tagged type.
  84      *
  85      * @exception Asn1Exception on error.
  86      * @param data the Der input stream value, which contains one or more marshaled value.
  87      * @param explicitTag tag number.
  88      * @param optional indicate if this data field is optional
  89      * @return an instance of TicketFlags.
  90      *
  91      */
  92     public static TicketFlags parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
  93         if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
  94             return null;
  95         DerValue der = data.getDerValue();
  96         if (explicitTag != (der.getTag() & (byte)0x1F))  {
  97             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
  98         }
  99         else {
 100             DerValue subDer = der.getData().getDerValue();
 101             return new TicketFlags(subDer);
 102         }
 103     }
 104 
 105     public Object clone() {
 106         try {
 107             return new TicketFlags(this.toBooleanArray());
 108         }
 109         catch (Exception e) {
 110             return null;
 111         }
 112     }
 113 
 114     public boolean match(LoginOptions options) {
 115         boolean matched = false;
 116         //We currently only consider if forwardable renewable and proxiable are match
 117         if (this.get(Krb5.TKT_OPTS_FORWARDABLE) == (options.get(KDCOptions.FORWARDABLE))) {
 118             if (this.get(Krb5.TKT_OPTS_PROXIABLE) == (options.get(KDCOptions.PROXIABLE))) {
 119                 if (this.get(Krb5.TKT_OPTS_RENEWABLE) == (options.get(KDCOptions.RENEWABLE))) {
 120                     matched = true;
 121                 }
 122             }
 123         }
 124         return matched;
 125     }
 126     public boolean match(TicketFlags flags) {
 127         boolean matched = true;
 128         for (int i = 0; i <= Krb5.TKT_OPTS_MAX; i++) {
 129             if (this.get(i) != flags.get(i)) {
 130                 return false;
 131             }
 132         }
 133         return matched;
 134     }
 135 
 136 
 137     /**
 138      * Returns the string representative of ticket flags.
 139      */
 140     public String toString() {
 141         StringBuilder sb = new StringBuilder();
 142         boolean[] flags = toBooleanArray();
 143         for (int i = 0; i < flags.length; i++) {
 144             if (flags[i] == true) {
 145                 switch (i) {
 146                 case 0:
 147                     sb.append("RESERVED;");
 148                     break;
 149                 case 1:
 150                     sb.append("FORWARDABLE;");
 151                     break;
 152                 case 2:
 153                     sb.append("FORWARDED;");
 154                     break;
 155                 case 3:
 156                     sb.append("PROXIABLE;");
 157                     break;
 158                 case 4:
 159                     sb.append("PROXY;");
 160                     break;
 161                 case 5:
 162                     sb.append("MAY-POSTDATE;");
 163                     break;
 164                 case 6:
 165                     sb.append("POSTDATED;");
 166                     break;
 167                 case 7:
 168                     sb.append("INVALID;");
 169                     break;
 170                 case 8:
 171                     sb.append("RENEWABLE;");
 172                     break;
 173                 case 9:
 174                     sb.append("INITIAL;");
 175                     break;
 176                 case 10:
 177                     sb.append("PRE-AUTHENT;");
 178                     break;
 179                 case 11:
 180                     sb.append("HW-AUTHENT;");
 181                     break;
 182                 case 15:
 183                     sb.append("ENC-PA-REP;");
 184                     break;
 185                 }
 186             }
 187         }
 188         String result = sb.toString();
 189         if (result.length() > 0) {
 190             result = result.substring(0, result.length() - 1);
 191         }
 192         return result;
 193     }
 194 }