////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1993, 1994, 1995.
// Unpublished work.  All Rights Reserved.
//
// The software contained on this media is the property of the
// DSTC Pty Ltd.  Use of this software is strictly in accordance
// with the license agreement in the accompanying LICENSE.DOC
// file. If your distribution of this software does not contain
// a LICENSE.DOC file then you have no rights to use this
// software in any manner and should contact DSTC at the address
// below to determine an appropriate licensing arrangement.
//
//      DSTC Pty Ltd
//      Level 7, GP South
//      University of Queensland
//      St Lucia, 4072
//      Australia
//      Tel: +61 7 3365 4310
//      Fax: +61 7 3365 4311
//      Email: jcsi@dstc.qut.edu.au
//
// This software is being provided "AS IS" without warranty of
// any kind.  In no event shall DSTC Pty Ltd be liable for
// damage of any kind arising out of or in connection with
// the use or performance of this software.
//
////////////////////////////////////////////////////////////////////////////

package com.dstc.security.kerberos.v5.base;

import java.util.StringTokenizer;
import com.dstc.security.asn1.*;

/**
 * <p>A class representing the Kerberos ASN.1 structure KDCOptions.
 *
 * <pre>
 * KDCOptions ::=  BIT STRING {
 *    reserved(0),
 *                  forwardable(1),
 *                  forwarded(2),
 *                  proxiable(3),
 *                  proxy(4),
 *                  allow-postdate(5),
 *                  postdated(6),
 *                  unused7(7),
 *                  renewable(8),
 *                  unused9(9),
 *                  unused10(10),
 *                  unused11(11),
 *                  unused12(12),
 *                  unused13(13),
 *                  disable-transited-check(26),
 *                  renewable-ok(27),
 *                  enc-tkt-in-skey(28),
 *                  renew(30),
 *                  validate(31)
 * }
 * </pre>
 *
 * @version 0.98, 98/07/01
 * @author Nam Tran
 */
public final class KDCOptions extends BitString {
  /**
   * Constructs a KDCOptions from a string containing option names.
   * Those options named will be turned on. The string is normally the value
   * of an appropriate property. For example:
   *    <p> krb5.requester.kdcoptions=renewable, forwardable
   * Acceptable option names are: forwardable, forwarded, proxiable, proxy,
   * allow-postdate, postdated, renewable, disable-transited-check,
   * renewable-ok, enc-tkt-in-skey, renew, validate. Option names are not
   * case-sensitive.
   *
   * @param opts A string containing a list of comma separated option names.
   */
  public KDCOptions(String opts)
  {
    super();

    contents = new byte[5];
    contents[0] = (byte) 0x00;   // number of padded bits
    contents[1] = (byte) 0x00;
    contents[2] = (byte) 0x00;
    contents[3] = (byte) 0x00;
    contents[4] = (byte) 0x00;

    StringTokenizer tknz = new StringTokenizer(opts, " \t\n\r\f,");

    String option;
    while (tknz.hasMoreTokens()) {
      option = tknz.nextToken().toUpperCase();
      if (option.equals("FORWARDABLE"))
contents[1] |= (byte) 0x40;
      else if (option.equals("FORWARDED"))
contents[1] |= (byte) 0x20;
      else if (option.equals("PROXIABLE"))
contents[1] |= (byte) 0x10;
      else if (option.equals("PROXY"))
contents[1] |= (byte) 0x08;
      else if (option.equals("ALLOW-POSTDATE"))
contents[1] |= (byte) 0x04;
      else if (option.equals("POSTDATED"))
contents[1] |= (byte) 0x02;
      else if (option.equals("RENEWABLE"))
contents[2] |= (byte) 0x80;
      else if (option.equals("DISABLE-TRANSITED-CHECK"))
contents[4] |= (byte) 0x20;
      else if (option.equals("RENEWABLE-OK"))
contents[4] |= (byte) 0x10;
      else if (option.equals("ENC-TKT-IN-SKEY"))
contents[4] |= (byte) 0x08;
      else if (option.equals("RENEW"))
contents[4] |= (byte) 0x02;
      else if (option.equals("VALIDATE"))
contents[4] |= (byte) 0x01;
    }
  }

  /**
   * Constructs an KDCOptions from a DER encoding
   */
  public KDCOptions(byte encoded[]) throws Asn1Exception
  {
    doDecode(encoded);
  }

  /**
   * Checks if an option is turned on. Returns true for yes, false otherwise.
   *
   * @see #KDCOptions
   * @param opt Name of the option to check for.
   */
  public boolean isOn(String opt)
  {
    String option = opt.toUpperCase();

    if (option.equals("FORWARDABLE"))
      return (contents[1] & (byte) 0x40) != 0;
    else if (option.equals("FORWARDED"))
      return (contents[1] & (byte) 0x20) != 0;
    else if (option.equals("PROXIABLE"))
      return (contents[1] & (byte) 0x10) != 0;
    else if (option.equals("PROXY"))
      return (contents[1] & (byte) 0x08) != 0;
    else if (option.equals("ALLOW-POSTDATE"))
      return (contents[1] & (byte) 0x04) != 0;
    else if (option.equals("POSTDATED"))
      return (contents[1] & (byte) 0x02) != 0;
    else if (option.equals("RENEWABLE"))
      return (contents[2] & (byte) 0x80) != 0;
    else if (option.equals("DISABLE-TRANSITED-CHECK"))
      return (contents[4] & (byte) 0x20) != 0;
    else if (option.equals("RENEWABLE-OK"))
      return (contents[4] & (byte) 0x10) != 0;
    else if (option.equals("ENC-TKT-IN-SKEY"))
      return (contents[4] & (byte) 0x08) != 0;
    else if (option.equals("RENEW"))
      return (contents[4] & (byte) 0x02) != 0;
    else if (option.equals("VALIDATE"))
      return (contents[4] & (byte) 0x01) != 0;

    return false;
  }

  /**
   * Turn ons an option.
   *
   * @param opt Name of the option to turn on.
   */
  public void setOn(String opt)
  {
    String option = opt.toUpperCase();

    if (option.equals("FORWARDABLE"))
      contents[1] |= (byte) 0x40;
    else if (option.equals("FORWARDED"))
      contents[1] |= (byte) 0x20;
    else if (option.equals("PROXIABLE"))
      contents[1] |= (byte) 0x10;
    else if (option.equals("PROXY"))
      contents[1] |= (byte) 0x08;
    else if (option.equals("ALLOW-POSTDATE"))
      contents[1] |= (byte) 0x04;
    else if (option.equals("POSTDATED"))
      contents[1] |= (byte) 0x02;
    else if (option.equals("RENEWABLE"))
      contents[2] |= (byte) 0x80;
    else if (option.equals("DISABLE-TRANSITED-CHECK"))
      contents[4] |= (byte) 0x20;
    else if (option.equals("RENEWABLE-OK"))
      contents[4] |= (byte) 0x10;
    else if (option.equals("ENC-TKT-IN-SKEY"))
      contents[4] |= (byte) 0x08;
    else if (option.equals("RENEW"))
      contents[4] |= (byte) 0x02;
    else if (option.equals("VALIDATE"))
      contents[4] |= (byte) 0x01;
  }
}
