Path: blob/master/src/java.security.jgss/share/classes/sun/security/krb5/internal/KDCOptions.java
41161 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324/*25*26* (C) Copyright IBM Corp. 1999 All Rights Reserved.27* Copyright 1997 The Open Group Research Institute. All rights reserved.28*/2930package sun.security.krb5.internal;3132import sun.security.krb5.Config;33import sun.security.krb5.KrbException;34import sun.security.krb5.Asn1Exception;35import sun.security.krb5.internal.util.KerberosFlags;36import sun.security.util.*;37import java.io.IOException;3839/**40* Implements the ASN.1 KDCOptions type.41*42* <pre>{@code43* KDCOptions ::= KerberosFlags44* -- reserved(0),45* -- forwardable(1),46* -- forwarded(2),47* -- proxiable(3),48* -- proxy(4),49* -- allow-postdate(5),50* -- postdated(6),51* -- unused7(7),52* -- renewable(8),53* -- unused9(9),54* -- unused10(10),55* -- opt-hardware-auth(11),56* -- unused12(12),57* -- unused13(13),58* -- 15 is reserved for canonicalize59* -- unused15(15),60* -- 26 was unused in 151061* -- disable-transited-check(26),62* -- renewable-ok(27),63* -- enc-tkt-in-skey(28),64* -- renew(30),65* -- validate(31)66*67* KerberosFlags ::= BIT STRING (SIZE (32..MAX))68* -- minimum number of bits shall be sent,69* -- but no fewer than 3270*71* }</pre>72*73* <p>74* This definition reflects the Network Working Group RFC 412075* specification available at76* <a href="http://www.ietf.org/rfc/rfc4120.txt">77* http://www.ietf.org/rfc/rfc4120.txt</a>.78*79* <p>80* This class appears as data field in the initial request(KRB_AS_REQ)81* or subsequent request(KRB_TGS_REQ) to the KDC and indicates the flags82* that the client wants to set on the tickets.83*84* The optional bits are:85* <UL>86* <LI>KDCOptions.RESERVED87* <LI>KDCOptions.FORWARDABLE88* <LI>KDCOptions.FORWARDED89* <LI>KDCOptions.PROXIABLE90* <LI>KDCOptions.PROXY91* <LI>KDCOptions.ALLOW_POSTDATE92* <LI>KDCOptions.POSTDATED93* <LI>KDCOptions.RENEWABLE94* <LI>KDCOptions.RENEWABLE_OK95* <LI>KDCOptions.ENC_TKT_IN_SKEY96* <LI>KDCOptions.RENEW97* <LI>KDCOptions.VALIDATE98* </UL>99* <p> Various checks must be made before honoring an option. The restrictions100* on the use of some options are as follows:101* <ol>102* <li> FORWARDABLE, FORWARDED, PROXIABLE, RENEWABLE options may be set in103* subsequent request only if the ticket_granting ticket on which it is based has104* the same options (FORWARDABLE, FORWARDED, PROXIABLE, RENEWABLE) set.105* <li> ALLOW_POSTDATE may be set in subsequent request only if the106* ticket-granting ticket on which it is based also has its MAY_POSTDATE flag set.107* <li> POSTDATED may be set in subsequent request only if the108* ticket-granting ticket on which it is based also has its MAY_POSTDATE flag set.109* <li> RENEWABLE or RENEW may be set in subsequent request only if the110* ticket-granting ticket on which it is based also has its RENEWABLE flag set.111* <li> POXY may be set in subsequent request only if the ticket-granting ticket112* on which it is based also has its PROXIABLE flag set, and the address(es) of113* the host from which the resulting ticket is to be valid should be included114* in the addresses field of the request.115* <li>FORWARDED, PROXY, ENC_TKT_IN_SKEY, RENEW, VALIDATE are used only in116* subsequent requests.117* </ol>118*/119120public class KDCOptions extends KerberosFlags {121122private static final int KDC_OPT_PROXIABLE = 0x10000000;123private static final int KDC_OPT_RENEWABLE_OK = 0x00000010;124private static final int KDC_OPT_FORWARDABLE = 0x40000000;125126127// KDC Options128129public static final int RESERVED = 0;130public static final int FORWARDABLE = 1;131public static final int FORWARDED = 2;132public static final int PROXIABLE = 3;133public static final int PROXY = 4;134public static final int ALLOW_POSTDATE = 5;135public static final int POSTDATED = 6;136public static final int UNUSED7 = 7;137public static final int RENEWABLE = 8;138public static final int UNUSED9 = 9;139public static final int UNUSED10 = 10;140public static final int UNUSED11 = 11;141public static final int CNAME_IN_ADDL_TKT = 14;142public static final int CANONICALIZE = 15;143public static final int RENEWABLE_OK = 27;144public static final int ENC_TKT_IN_SKEY = 28;145public static final int RENEW = 30;146public static final int VALIDATE = 31;147148private static final String[] names = {149"RESERVED", //0150"FORWARDABLE", //1;151"FORWARDED", //2;152"PROXIABLE", //3;153"PROXY", //4;154"ALLOW_POSTDATE", //5;155"POSTDATED", //6;156"UNUSED7", //7;157"RENEWABLE", //8;158"UNUSED9", //9;159"UNUSED10", //10;160"UNUSED11", //11;161null,null,162"CNAME_IN_ADDL_TKT",//14;163"CANONICALIZE", //15;164null,null,null,null,null,null,null,null,null,null,null,165"RENEWABLE_OK", //27;166"ENC_TKT_IN_SKEY", //28;167null,168"RENEW", //30;169"VALIDATE", //31;170};171172private boolean DEBUG = Krb5.DEBUG;173174public static KDCOptions with(int... flags) {175KDCOptions options = new KDCOptions();176for (int flag: flags) {177options.set(flag, true);178}179return options;180}181182public KDCOptions() {183super(Krb5.KDC_OPTS_MAX + 1);184setDefault();185}186187public KDCOptions(int size, byte[] data) throws Asn1Exception {188super(size, data);189if ((size > data.length * BITS_PER_UNIT) || (size > Krb5.KDC_OPTS_MAX + 1))190throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);191}192193/**194* Constructs a KDCOptions from the specified bit settings.195*196* @param data the bits to be set for the KDCOptions.197* @exception Asn1Exception if an error occurs while decoding an ASN1198* encoded data.199*200*/201public KDCOptions(boolean[] data) throws Asn1Exception {202super(data);203if (data.length > Krb5.KDC_OPTS_MAX + 1) {204throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);205}206}207208public KDCOptions(DerValue encoding) throws Asn1Exception, IOException {209this(encoding.getUnalignedBitString(true).toBooleanArray());210}211212/**213* Constructs a KDCOptions from the passed bit settings.214*215* @param options the bits to be set for the KDCOptions.216*217*/218public KDCOptions(byte[] options) {219super(options.length * BITS_PER_UNIT, options);220}221222/**223* Parse (unmarshal) a KDCOptions from a DER input stream. This form224* parsing might be used when expanding a value which is part of225* a constructed sequence and uses explicitly tagged type.226*227* @param data the Der input stream value, which contains one or more228* marshaled value.229* @param explicitTag tag number.230* @param optional indicate if this data field is optional231* @return an instance of KDCOptions.232* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.233* @exception IOException if an I/O error occurs while reading encoded data.234*235*/236237public static KDCOptions parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {238if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag))239return null;240DerValue der = data.getDerValue();241if (explicitTag != (der.getTag() & (byte)0x1F)) {242throw new Asn1Exception(Krb5.ASN1_BAD_ID);243} else {244DerValue subDer = der.getData().getDerValue();245return new KDCOptions(subDer);246}247}248249/**250* Sets the value(true/false) for one of the <code>KDCOptions</code>.251*252* @param option an option bit.253* @param value true if the option is selected, false if the option is not selected.254* @exception ArrayIndexOutOfBoundsException if array index out of bound occurs.255* @see sun.security.krb5.internal.Krb5256*/257public void set(int option, boolean value) throws ArrayIndexOutOfBoundsException {258super.set(option, value);259}260261/**262* Gets the value(true/false) for one of the <code>KDCOptions</code>.263*264* @param option an option bit.265* @return value true if the option is selected, false if the option is not selected.266* @exception ArrayIndexOutOfBoundsException if array index out of bound occurs.267* @see sun.security.krb5.internal.Krb5268*/269270public boolean get(int option) throws ArrayIndexOutOfBoundsException {271return super.get(option);272}273274@Override public String toString() {275StringBuilder sb = new StringBuilder();276sb.append("KDCOptions: ");277for (int i=0; i<Krb5.KDC_OPTS_MAX+1; i++) {278if (get(i)) {279if (names[i] != null) {280sb.append(names[i]).append(",");281} else {282sb.append(i).append(",");283}284}285}286return sb.toString();287}288289private void setDefault() {290try {291292Config config = Config.getInstance();293294// If key not present, returns Integer.MIN_VALUE, which is295// almost all zero.296297int options = config.getIntValue("libdefaults",298"kdc_default_options");299300if ((options & KDC_OPT_RENEWABLE_OK) == KDC_OPT_RENEWABLE_OK) {301set(RENEWABLE_OK, true);302} else {303if (config.getBooleanObject("libdefaults", "renewable") == Boolean.TRUE) {304set(RENEWABLE_OK, true);305}306}307if ((options & KDC_OPT_PROXIABLE) == KDC_OPT_PROXIABLE) {308set(PROXIABLE, true);309} else {310if (config.getBooleanObject("libdefaults", "proxiable") == Boolean.TRUE) {311set(PROXIABLE, true);312}313}314315if ((options & KDC_OPT_FORWARDABLE) == KDC_OPT_FORWARDABLE) {316set(FORWARDABLE, true);317} else {318if (config.getBooleanObject("libdefaults", "forwardable") == Boolean.TRUE) {319set(FORWARDABLE, true);320}321}322} catch (KrbException e) {323if (DEBUG) {324System.out.println("Exception in getting default values for " +325"KDC Options from the configuration ");326e.printStackTrace();327328}329}330}331}332333334