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  *                  }
  56  */
  57 public class TicketFlags extends KerberosFlags {
  58     public TicketFlags() {
  59         super(Krb5.TKT_OPTS_MAX + 1);
  60     }
  61 
  62     public TicketFlags (boolean[] flags) throws Asn1Exception {
  63         super(flags);
  64         if (flags.length > Krb5.TKT_OPTS_MAX + 1) {
  65             throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
  66         }
  67     }
  68 
  69     public TicketFlags(int size, byte[] data) throws Asn1Exception {
  70         super(size, data);
  71         if ((size > data.length * BITS_PER_UNIT) || (size > Krb5.TKT_OPTS_MAX + 1))
  72             throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
  73     }
  74 
  75     public TicketFlags(DerValue encoding) throws IOException, Asn1Exception {
  76         this(encoding.getUnalignedBitString(true).toBooleanArray());
  77     }
  78 
  79     /**
  80      * Parse (unmarshal) a ticket flag from a DER input stream.  This form
  81      * parsing might be used when expanding a value which is part of
  82      * a constructed sequence and uses explicitly tagged type.
  83      *
  84      * @exception Asn1Exception on error.
  85      * @param data the Der input stream value, which contains one or more marshaled value.
  86      * @param explicitTag tag number.
  87      * @param optional indicate if this data field is optional
  88      * @return an instance of TicketFlags.
  89      *
  90      */
  91     public static TicketFlags parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
  92         if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
  93             return null;
  94         DerValue der = data.getDerValue();
  95         if (explicitTag != (der.getTag() & (byte)0x1F))  {
  96             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
  97         }
  98         else {
  99             DerValue subDer = der.getData().getDerValue();
 100             return new TicketFlags(subDer);
 101         }
 102     }
 103 
 104     public Object clone() {
 105         try {
 106             return new TicketFlags(this.toBooleanArray());
 107         }
 108         catch (Exception e) {
 109             return null;
 110         }
 111     }
 112 
 113     public boolean match(LoginOptions options) {
 114         boolean matched = false;
 115         //We currently only consider if forwardable renewable and proxiable are match
 116         if (this.get(Krb5.TKT_OPTS_FORWARDABLE) == (options.get(KDCOptions.FORWARDABLE))) {
 117             if (this.get(Krb5.TKT_OPTS_PROXIABLE) == (options.get(KDCOptions.PROXIABLE))) {
 118                 if (this.get(Krb5.TKT_OPTS_RENEWABLE) == (options.get(KDCOptions.RENEWABLE))) {
 119                     matched = true;
 120                 }
 121             }
 122         }
 123         return matched;
 124     }
 125     public boolean match(TicketFlags flags) {
 126         boolean matched = true;
 127         for (int i = 0; i <= Krb5.TKT_OPTS_MAX; i++) {
 128             if (this.get(i) != flags.get(i)) {
 129                 return false;
 130             }
 131         }
 132         return matched;
 133     }
 134 
 135 
 136     /**
 137      * Returns the string representative of ticket flags.
 138      */
 139     public String toString() {
 140         StringBuilder sb = new StringBuilder();
 141         boolean[] flags = toBooleanArray();
 142         for (int i = 0; i < flags.length; i++) {
 143             if (flags[i] == true) {
 144                 switch (i) {
 145                 case 0:
 146                     sb.append("RESERVED;");
 147                     break;
 148                 case 1:
 149                     sb.append("FORWARDABLE;");
 150                     break;
 151                 case 2:
 152                     sb.append("FORWARDED;");
 153                     break;
 154                 case 3:
 155                     sb.append("PROXIABLE;");
 156                     break;
 157                 case 4:
 158                     sb.append("PROXY;");
 159                     break;
 160                 case 5:
 161                     sb.append("MAY-POSTDATE;");
 162                     break;
 163                 case 6:
 164                     sb.append("POSTDATED;");
 165                     break;
 166                 case 7:
 167                     sb.append("INVALID;");
 168                     break;
 169                 case 8:
 170                     sb.append("RENEWABLE;");
 171                     break;
 172                 case 9:
 173                     sb.append("INITIAL;");
 174                     break;
 175                 case 10:
 176                     sb.append("PRE-AUTHENT;");
 177                     break;
 178                 case 11:
 179                     sb.append("HW-AUTHENT;");
 180                     break;
 181                 }
 182             }
 183         }
 184         String result = sb.toString();
 185         if (result.length() > 0) {
 186             result = result.substring(0, result.length() - 1);
 187         }
 188         return result;
 189     }
 190 }