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 */ 020 021package org.apache.directory.shared.kerberos.messages; 022 023 024import java.nio.BufferOverflowException; 025import java.nio.ByteBuffer; 026 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.apache.directory.shared.kerberos.KerberosMessageType; 035import org.apache.directory.shared.kerberos.components.Checksum; 036import org.apache.directory.shared.kerberos.components.KrbSafeBody; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040 041/** 042 * Class representing KRB-SAFE message 043 * 044 * <pre> 045 * KRB-SAFE ::= [APPLICATION 20] SEQUENCE { 046 * pvno [0] INTEGER (5), 047 * msg-type [1] INTEGER (20), 048 * safe-body [2] KRB-SAFE-BODY, 049 * cksum [3] Checksum 050 * } 051 * </pre> 052 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 053 */ 054public class KrbSafe extends KerberosMessage 055{ 056 /** The logger */ 057 private static final Logger log = LoggerFactory.getLogger( KrbError.class ); 058 059 /** Speedup for logs */ 060 private static final boolean IS_DEBUG = log.isDebugEnabled(); 061 062 /** body of this message */ 063 private KrbSafeBody krbSafeBody; 064 065 /** the checksum */ 066 private Checksum checksum; 067 068 // Storage for computed lengths 069 private int pvnoLen; 070 private int msgTypeLength; 071 private int krbSafeBodyLen; 072 private int checksumLen; 073 private int krbSafeSeqLen; 074 private int krbSafeLen; 075 076 077 /** 078 * Creates a new instance of KrbSafe. 079 */ 080 public KrbSafe() 081 { 082 super( KerberosMessageType.KRB_SAFE ); 083 } 084 085 086 /** 087 * @return the krbSafeBody 088 */ 089 public KrbSafeBody getSafeBody() 090 { 091 return krbSafeBody; 092 } 093 094 095 /** 096 * @param safeBody the KrbSafeBody to set 097 */ 098 public void setSafeBody( KrbSafeBody safeBody ) 099 { 100 this.krbSafeBody = safeBody; 101 } 102 103 104 /** 105 * @return the checksum 106 */ 107 public Checksum getChecksum() 108 { 109 return checksum; 110 } 111 112 113 /** 114 * @param checksum the checksum to set 115 */ 116 public void setChecksum( Checksum checksum ) 117 { 118 this.checksum = checksum; 119 } 120 121 122 /** 123 * Compute the KRB-SAFE length 124 * <pre> 125 * KRB-SAFE : 126 * 127 * 0x74 L1 KRB-SAFE APPLICATION[20] 128 * | 129 * +--> 0x30 L2 KRB-ERROR sequence 130 * | 131 * +--> 0xA0 0x03 pvno tag 132 * | | 133 * | +--> 0x02 0x01 0x05 pvno (5) 134 * | 135 * +--> 0xA1 0x03 msg-type tag 136 * | | 137 * | +--> 0x02 0x01 0x14 msg-type (20) 138 * | 139 * +--> 0xA2 L3 safe-body tag 140 * | | 141 * | +--> 0x30 L3-1 safe-body (KRB-SAFE-BODY) 142 * | 143 * +--> 0xA3 L4 cksum tag 144 * | 145 * +--> 0x30 L4-1 cksum (CHECKSUM) 146 * </pre> 147 */ 148 @Override 149 public int computeLength() 150 { 151 pvnoLen = 1 + 1 + 1; 152 krbSafeSeqLen = 1 + TLV.getNbBytes( pvnoLen ) + pvnoLen; 153 154 msgTypeLength = 1 + 1 + BerValue.getNbBytes( getMessageType().getValue() ); 155 krbSafeSeqLen += 1 + TLV.getNbBytes( msgTypeLength ) + msgTypeLength; 156 157 krbSafeBodyLen = krbSafeBody.computeLength(); 158 krbSafeSeqLen += 1 + TLV.getNbBytes( krbSafeBodyLen ) + krbSafeBodyLen; 159 160 checksumLen = checksum.computeLength(); 161 krbSafeSeqLen += 1 + TLV.getNbBytes( checksumLen ) + checksumLen; 162 163 krbSafeLen = 1 + TLV.getNbBytes( krbSafeSeqLen ) + krbSafeSeqLen; 164 165 return 1 + TLV.getNbBytes( krbSafeLen ) + krbSafeLen; 166 } 167 168 169 /** 170 * {@inheritDoc} 171 */ 172 @Override 173 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 174 { 175 if ( buffer == null ) 176 { 177 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 178 } 179 180 try 181 { 182 // The KRB-SAFE APPLICATION tag 183 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_TAG ); 184 buffer.put( TLV.getBytes( krbSafeLen ) ); 185 186 // The KRB-SAFE sequence 187 buffer.put( UniversalTag.SEQUENCE.getValue() ); 188 buffer.put( TLV.getBytes( krbSafeSeqLen ) ); 189 190 // pvno tag and value 191 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_PVNO_TAG ); 192 buffer.put( TLV.getBytes( pvnoLen ) ); 193 BerValue.encode( buffer, getProtocolVersionNumber() ); 194 195 // msg-type tag and value 196 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_MSGTYPE_TAG ); 197 buffer.put( TLV.getBytes( msgTypeLength ) ); 198 BerValue.encode( buffer, getMessageType().getValue() ); 199 200 // safe-body tag and value 201 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_SAFE_BODY_TAG ); 202 buffer.put( TLV.getBytes( krbSafeBodyLen ) ); 203 krbSafeBody.encode( buffer ); 204 205 // cksum tag and value 206 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_CKSUM_TAG ); 207 buffer.put( TLV.getBytes( checksumLen ) ); 208 checksum.encode( buffer ); 209 } 210 catch ( BufferOverflowException boe ) 211 { 212 log.error( I18n.err( I18n.ERR_736_CANNOT_ENCODE_KRBSAFE, 1 + TLV.getNbBytes( krbSafeLen ) 213 + krbSafeLen, buffer.capacity() ) ); 214 throw new EncoderException( I18n.err( I18n.ERR_138 ), boe ); 215 } 216 217 if ( IS_DEBUG ) 218 { 219 log.debug( "KrbSafe encoding : {}", Strings.dumpBytes( buffer.array() ) ); 220 log.debug( "KrbSafe initial value : {}", this ); 221 } 222 223 return buffer; 224 } 225 226 227 /** 228 * @see Object#toString() 229 */ 230 public String toString() 231 { 232 StringBuilder sb = new StringBuilder(); 233 234 sb.append( "KRB-SAFE : {\n" ); 235 sb.append( " pvno: " ).append( getProtocolVersionNumber() ).append( '\n' ); 236 sb.append( " msgType: " ).append( getMessageType() ).append( '\n' ); 237 238 if ( krbSafeBody != null ) 239 { 240 sb.append( " safe-body: " ).append( krbSafeBody ).append( '\n' ); 241 } 242 243 if ( checksum != null ) 244 { 245 sb.append( " cusec: " ).append( checksum ).append( '\n' ); 246 } 247 248 sb.append( "}\n" ); 249 250 return sb.toString(); 251 } 252}