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.codec; 021 022 023import java.nio.ByteBuffer; 024import java.nio.InvalidMarkException; 025 026import org.apache.directory.api.asn1.DecoderException; 027import org.apache.directory.api.asn1.ber.Asn1Decoder; 028import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 029import org.apache.directory.api.asn1.ber.grammar.Grammar; 030import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 031import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 032import org.apache.directory.api.asn1.ber.tlv.TLV; 033import org.apache.directory.shared.kerberos.KerberosConstants; 034import org.apache.directory.shared.kerberos.codec.apRep.ApRepContainer; 035import org.apache.directory.shared.kerberos.codec.apReq.ApReqContainer; 036import org.apache.directory.shared.kerberos.codec.asRep.AsRepContainer; 037import org.apache.directory.shared.kerberos.codec.asReq.AsReqContainer; 038import org.apache.directory.shared.kerberos.codec.krbCred.KrbCredContainer; 039import org.apache.directory.shared.kerberos.codec.krbError.KrbErrorContainer; 040import org.apache.directory.shared.kerberos.codec.krbPriv.KrbPrivContainer; 041import org.apache.directory.shared.kerberos.codec.krbSafe.KrbSafeContainer; 042import org.apache.directory.shared.kerberos.codec.tgsRep.TgsRepContainer; 043import org.apache.directory.shared.kerberos.codec.tgsReq.TgsReqContainer; 044import org.apache.directory.shared.kerberos.messages.KerberosMessage; 045import org.slf4j.Logger; 046import org.slf4j.LoggerFactory; 047 048 049/** 050 * This class implements the KerberosMessage message. All the actions are declared 051 * in this class. As it is a singleton, these declaration are only done once. If 052 * an action is to be added or modified, this is where the work is to be done ! 053 * 054 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 055 */ 056public final class KerberosMessageGrammar extends AbstractGrammar<KerberosMessageContainer> 057{ 058 /** The logger */ 059 static final Logger LOG = LoggerFactory.getLogger( KerberosMessageGrammar.class ); 060 061 /** A speedup for logger */ 062 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 063 064 /** The instance of grammar. KerberosMessageGrammar is a singleton */ 065 private static Grammar<KerberosMessageContainer> instance = new KerberosMessageGrammar(); 066 067 private class DecodeKerberosMessage extends GrammarAction<KerberosMessageContainer> 068 { 069 public void action( KerberosMessageContainer kerberosMessageContainer ) throws DecoderException 070 { 071 ByteBuffer stream = kerberosMessageContainer.getStream(); 072 073 try 074 { 075 stream.reset(); 076 } 077 catch ( InvalidMarkException ime ) 078 { 079 stream.rewind(); 080 } 081 082 TLV tlv = kerberosMessageContainer.getCurrentTLV(); 083 kerberosMessageContainer.setGrammarEndAllowed( true ); 084 085 // Now, depending on the T, call the inner decoder 086 switch ( tlv.getTag() ) 087 { 088 case KerberosConstants.AS_REQ_TAG: 089 AsReqContainer asReqContainer = new AsReqContainer( stream ); 090 091 // Decode the AS_REQ PDU 092 Asn1Decoder.decode( stream, asReqContainer ); 093 094 KerberosMessage asReq = asReqContainer.getAsReq(); 095 kerberosMessageContainer.setMessage( asReq ); 096 097 break; 098 099 case KerberosConstants.AS_REP_TAG: 100 AsRepContainer asRepContainer = new AsRepContainer( stream ); 101 102 // Decode the AS-REP PDU 103 Asn1Decoder.decode( stream, asRepContainer ); 104 105 KerberosMessage asRep = asRepContainer.getAsRep(); 106 kerberosMessageContainer.setMessage( asRep ); 107 108 break; 109 110 case KerberosConstants.TGS_REQ_TAG: 111 TgsReqContainer tgsReqContainer = new TgsReqContainer( stream ); 112 113 // Decode the TGS-REQ PDU 114 Asn1Decoder.decode( stream, tgsReqContainer ); 115 116 KerberosMessage tgsReq = tgsReqContainer.getTgsReq(); 117 kerberosMessageContainer.setMessage( tgsReq ); 118 119 break; 120 121 case KerberosConstants.TGS_REP_TAG: 122 TgsRepContainer tgsRepContainer = new TgsRepContainer( stream ); 123 124 // Decode the TGS-REP PDU 125 Asn1Decoder.decode( stream, tgsRepContainer ); 126 127 KerberosMessage tgsRep = tgsRepContainer.getTgsRep(); 128 kerberosMessageContainer.setMessage( tgsRep ); 129 130 break; 131 132 case KerberosConstants.AP_REQ_TAG: 133 ApReqContainer apReqContainer = new ApReqContainer( stream ); 134 135 // Decode the AP-REQ PDU 136 Asn1Decoder.decode( stream, apReqContainer ); 137 138 KerberosMessage apReq = apReqContainer.getApReq(); 139 kerberosMessageContainer.setMessage( apReq ); 140 break; 141 142 case KerberosConstants.AP_REP_TAG: 143 ApRepContainer apRepContainer = new ApRepContainer( stream ); 144 145 // Decode the AP-REP PDU 146 Asn1Decoder.decode( stream, apRepContainer ); 147 148 KerberosMessage apRep = apRepContainer.getApRep(); 149 kerberosMessageContainer.setMessage( apRep ); 150 break; 151 152 case KerberosConstants.KRB_SAFE_TAG: 153 KrbSafeContainer krbSafeContainer = new KrbSafeContainer( stream ); 154 155 // Decode the KRB-SAFE PDU 156 Asn1Decoder.decode( stream, krbSafeContainer ); 157 158 KerberosMessage krbSafe = krbSafeContainer.getKrbSafe(); 159 kerberosMessageContainer.setMessage( krbSafe ); 160 break; 161 162 case KerberosConstants.KRB_PRIV_TAG: 163 KrbPrivContainer krbPrivContainer = new KrbPrivContainer( stream ); 164 165 // Decode the KRB-PRIV PDU 166 Asn1Decoder.decode( stream, krbPrivContainer ); 167 168 KerberosMessage krbPriv = krbPrivContainer.getKrbPriv(); 169 kerberosMessageContainer.setMessage( krbPriv ); 170 break; 171 172 case KerberosConstants.KRB_CRED_TAG: 173 KrbCredContainer krbCredContainer = new KrbCredContainer( stream ); 174 175 // Decode the KRB-CRED PDU 176 Asn1Decoder.decode( stream, krbCredContainer ); 177 178 KerberosMessage krbCred = krbCredContainer.getKrbCred(); 179 kerberosMessageContainer.setMessage( krbCred ); 180 break; 181 182 case KerberosConstants.KRB_ERROR_TAG: 183 KrbErrorContainer krbErrorContainer = new KrbErrorContainer( stream ); 184 185 // Decode the KRB-ERROR PDU 186 Asn1Decoder.decode( stream, krbErrorContainer ); 187 188 KerberosMessage krbError = krbErrorContainer.getKrbError(); 189 kerberosMessageContainer.setMessage( krbError ); 190 break; 191 } 192 193 // We are done, get out 194 if ( IS_DEBUG ) 195 { 196 LOG.debug( "Decoded KerberosMessage {}", kerberosMessageContainer.getMessage() ); 197 } 198 } 199 } 200 201 202 /** 203 * Creates a new KerberosMessageGrammar object. 204 */ 205 @SuppressWarnings("unchecked") 206 private KerberosMessageGrammar() 207 { 208 setName( KerberosMessageGrammar.class.getName() ); 209 210 // Create the transitions table 211 super.transitions = new GrammarTransition[KerberosMessageStatesEnum.LAST_KERBEROS_MESSAGE_STATE.ordinal()][256]; 212 213 // ============================================================================================ 214 // Ticket 215 // ============================================================================================ 216 // -------------------------------------------------------------------------------------------- 217 // Transition from START to Ticket 218 // -------------------------------------------------------------------------------------------- 219 // This is the starting state : 220 // Ticket ::= [APPLICATION 1] ... 221 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.AS_REQ_TAG] = 222 new GrammarTransition<KerberosMessageContainer>( 223 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.AS_REQ_STATE, 224 KerberosConstants.AS_REQ_TAG, 225 new DecodeKerberosMessage() ); 226 227 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.AS_REP_TAG] = 228 new GrammarTransition<KerberosMessageContainer>( 229 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.AS_REP_TAG_STATE, 230 KerberosConstants.AS_REP_TAG, 231 new DecodeKerberosMessage() ); 232 233 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.TGS_REQ_TAG] = 234 new GrammarTransition<KerberosMessageContainer>( 235 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.TGS_REQ_TAG_STATE, 236 KerberosConstants.TGS_REQ_TAG, 237 new DecodeKerberosMessage() ); 238 239 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.TGS_REP_TAG] = 240 new GrammarTransition<KerberosMessageContainer>( 241 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.TGS_REP_TAG_STATE, 242 KerberosConstants.TGS_REP_TAG, 243 new DecodeKerberosMessage() ); 244 245 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.AP_REQ_TAG] = 246 new GrammarTransition<KerberosMessageContainer>( 247 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.AP_REQ_TAG_STATE, 248 KerberosConstants.AP_REQ_TAG, 249 new DecodeKerberosMessage() ); 250 251 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.AP_REP_TAG] = 252 new GrammarTransition<KerberosMessageContainer>( 253 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.AP_REP_TAG_STATE, 254 KerberosConstants.AP_REP_TAG, 255 new DecodeKerberosMessage() ); 256 257 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.KRB_SAFE_TAG] = 258 new GrammarTransition<KerberosMessageContainer>( 259 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.KRB_SAFE_STATE, 260 KerberosConstants.KRB_SAFE_TAG, 261 new DecodeKerberosMessage() ); 262 263 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.KRB_PRIV_TAG] = 264 new GrammarTransition<KerberosMessageContainer>( 265 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.KRB_PRIV_STATE, 266 KerberosConstants.KRB_PRIV_TAG, 267 new DecodeKerberosMessage() ); 268 269 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.KRB_CRED_TAG] = 270 new GrammarTransition<KerberosMessageContainer>( 271 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.KRB_CRED_STATE, 272 KerberosConstants.KRB_CRED_TAG, 273 new DecodeKerberosMessage() ); 274 275 super.transitions[KerberosMessageStatesEnum.START_STATE.ordinal()][KerberosConstants.KRB_ERROR_TAG] = 276 new GrammarTransition<KerberosMessageContainer>( 277 KerberosMessageStatesEnum.START_STATE, KerberosMessageStatesEnum.KRB_ERROR_STATE, 278 KerberosConstants.KRB_ERROR_TAG, 279 new DecodeKerberosMessage() ); 280 } 281 282 283 /** 284 * Get the instance of this grammar 285 * 286 * @return An instance on the KerberosMessage Grammar 287 */ 288 public static Grammar<KerberosMessageContainer> getInstance() 289 { 290 return instance; 291 } 292}