001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.shared.kerberos.components; 021 022 023import java.nio.BufferOverflowException; 024import java.nio.ByteBuffer; 025 026import org.apache.directory.api.asn1.Asn1Object; 027import org.apache.directory.api.asn1.EncoderException; 028import org.apache.directory.api.asn1.ber.tlv.BerValue; 029import org.apache.directory.api.asn1.ber.tlv.TLV; 030import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 031import org.apache.directory.api.util.Strings; 032import org.apache.directory.server.i18n.I18n; 033import org.apache.directory.shared.kerberos.KerberosConstants; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037 038/** 039 * The AdAndOr structure is used to store a AD-AND-OR associated to a type. 040 * 041 * The ASN.1 grammar is : 042 * <pre> 043 * AD-AND-OR ::= SEQUENCE { 044 * condition-count [0] Int32, 045 * elements [1] <AuthorizationData> 046 * } 047 * </pre> 048 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 049 */ 050public class AdAndOr implements Asn1Object 051{ 052 /** The logger */ 053 private static final Logger LOG = LoggerFactory.getLogger( AdAndOr.class ); 054 055 /** Speedup for logs */ 056 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 057 058 /** The condition-count */ 059 private int conditionCount; 060 061 /** The elements */ 062 private AuthorizationData elements; 063 064 // Storage for computed lengths 065 private int conditionCountTagLength; 066 private int elementsTagLength; 067 private int adAndOrSeqLength; 068 069 070 /** 071 * Creates a new instance of AdAndOr 072 */ 073 public AdAndOr() 074 { 075 } 076 077 078 /** 079 * @return the conditionCount 080 */ 081 public int getConditionCount() 082 { 083 return conditionCount; 084 } 085 086 087 /** 088 * @param conditionCount the conditionCount to set 089 */ 090 public void setConditionCount( int conditionCount ) 091 { 092 this.conditionCount = conditionCount; 093 } 094 095 096 /** 097 * @return the elements 098 */ 099 public AuthorizationData getElements() 100 { 101 return elements; 102 } 103 104 105 /** 106 * @param elements the elements to set 107 */ 108 public void setElements( AuthorizationData elements ) 109 { 110 this.elements = elements; 111 } 112 113 114 /** 115 * Compute the AD-AND-OR length 116 * <pre> 117 * 0x30 L1 AD-AND-OR sequence 118 * | 119 * +--> 0xA1 L2 condition count tag 120 * | | 121 * | +--> 0x02 L2-1 condition count (int) 122 * | 123 * +--> 0xA2 L3 elements tag 124 * | 125 * +--> 0x30 L3-1 elements (AuthorizationData) 126 * </pre> 127 */ 128 @Override 129 public int computeLength() 130 { 131 // Compute the condition count length 132 int conditionCountLength = BerValue.getNbBytes( conditionCount ); 133 conditionCountTagLength = 1 + TLV.getNbBytes( conditionCountLength ) + conditionCountLength; 134 adAndOrSeqLength = 1 + TLV.getNbBytes( conditionCountTagLength ) + conditionCountTagLength; 135 136 // Compute the elements length 137 elementsTagLength = elements.computeLength(); 138 adAndOrSeqLength += 1 + TLV.getNbBytes( elementsTagLength ) + elementsTagLength; 139 140 // Compute the whole sequence length 141 return 1 + TLV.getNbBytes( adAndOrSeqLength ) + adAndOrSeqLength; 142 } 143 144 145 /** 146 * Encode the AD-AND-OR message to a PDU. 147 * 148 * @param buffer The buffer where to put the PDU. It should have been allocated 149 * before, with the right size. 150 * @return The constructed PDU. 151 */ 152 @Override 153 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 154 { 155 if ( buffer == null ) 156 { 157 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 158 } 159 160 try 161 { 162 // The AD-AND-OR SEQ OF Tag 163 buffer.put( UniversalTag.SEQUENCE.getValue() ); 164 buffer.put( TLV.getBytes( adAndOrSeqLength ) ); 165 166 // the condition-count 167 buffer.put( ( byte ) KerberosConstants.AD_AND_OR_CONDITION_COUNT_TAG ); 168 buffer.put( ( byte ) conditionCountTagLength ); 169 BerValue.encode( buffer, conditionCount ); 170 171 // the elements 172 buffer.put( ( byte ) KerberosConstants.AD_AND_OR_ELEMENTS_TAG ); 173 buffer.put( ( byte ) elementsTagLength ); 174 175 elements.encode( buffer ); 176 } 177 catch ( BufferOverflowException boe ) 178 { 179 LOG.error( I18n.err( I18n.ERR_139, 1 + TLV.getNbBytes( adAndOrSeqLength ) 180 + adAndOrSeqLength, buffer.capacity() ) ); 181 throw new EncoderException( I18n.err( I18n.ERR_138 ), boe ); 182 } 183 184 if ( IS_DEBUG ) 185 { 186 LOG.debug( "AD-AND-OR encoding : {}", Strings.dumpBytes( buffer.array() ) ); 187 LOG.debug( "AD-AND-OR initial value : {}", this ); 188 } 189 190 return buffer; 191 } 192 193 194 /** 195 * @see Object#toString() 196 */ 197 public String toString() 198 { 199 return toString( "" ); 200 } 201 202 203 /** 204 * @see Object#toString() 205 */ 206 public String toString( String tabs ) 207 { 208 StringBuilder sb = new StringBuilder(); 209 210 sb.append( tabs ).append( "AD-AND-OR : {\n" ); 211 sb.append( tabs ).append( " condition-count: " ).append( conditionCount ).append( '\n' ); 212 sb.append( tabs + " elements:" ).append( elements ).append( '\n' ); 213 sb.append( tabs + "}\n" ); 214 215 return sb.toString(); 216 } 217}