blob: 708c4d0130eda6cd0ca694305ca2fc3a9d8095a4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.server.kerberos.protocol;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.apache.directory.shared.asn1.ber.Asn1Container;
import org.apache.directory.shared.asn1.ber.Asn1Decoder;
import org.apache.directory.shared.asn1.ber.tlv.TLVStateEnum;
import org.apache.directory.shared.asn1.codec.DecoderException;
import org.apache.directory.shared.kerberos.codec.KerberosMessageContainer;
import org.apache.directory.shared.kerberos.codec.EncKdcRepPart.EncKdcRepPartContainer;
import org.apache.directory.shared.kerberos.codec.apRep.ApRepContainer;
import org.apache.directory.shared.kerberos.codec.apReq.ApReqContainer;
import org.apache.directory.shared.kerberos.codec.authenticator.AuthenticatorContainer;
import org.apache.directory.shared.kerberos.codec.authorizationData.AuthorizationDataContainer;
import org.apache.directory.shared.kerberos.codec.encApRepPart.EncApRepPartContainer;
import org.apache.directory.shared.kerberos.codec.encAsRepPart.EncAsRepPartContainer;
import org.apache.directory.shared.kerberos.codec.encKrbPrivPart.EncKrbPrivPartContainer;
import org.apache.directory.shared.kerberos.codec.encTicketPart.EncTicketPartContainer;
import org.apache.directory.shared.kerberos.codec.encryptedData.EncryptedDataContainer;
import org.apache.directory.shared.kerberos.codec.encryptionKey.EncryptionKeyContainer;
import org.apache.directory.shared.kerberos.codec.krbPriv.KrbPrivContainer;
import org.apache.directory.shared.kerberos.codec.paEncTsEnc.PaEncTsEncContainer;
import org.apache.directory.shared.kerberos.codec.principalName.PrincipalNameContainer;
import org.apache.directory.shared.kerberos.codec.ticket.TicketContainer;
import org.apache.directory.shared.kerberos.components.AuthorizationData;
import org.apache.directory.shared.kerberos.components.EncKdcRepPart;
import org.apache.directory.shared.kerberos.components.EncKrbPrivPart;
import org.apache.directory.shared.kerberos.components.EncTicketPart;
import org.apache.directory.shared.kerberos.components.EncryptedData;
import org.apache.directory.shared.kerberos.components.EncryptionKey;
import org.apache.directory.shared.kerberos.components.PaEncTsEnc;
import org.apache.directory.shared.kerberos.components.PrincipalName;
import org.apache.directory.shared.kerberos.exceptions.ErrorType;
import org.apache.directory.shared.kerberos.exceptions.KerberosException;
import org.apache.directory.shared.kerberos.messages.ApRep;
import org.apache.directory.shared.kerberos.messages.ApReq;
import org.apache.directory.shared.kerberos.messages.Authenticator;
import org.apache.directory.shared.kerberos.messages.EncApRepPart;
import org.apache.directory.shared.kerberos.messages.EncAsRepPart;
import org.apache.directory.shared.kerberos.messages.KrbPriv;
import org.apache.directory.shared.kerberos.messages.Ticket;
import org.apache.directory.shared.ldap.codec.LdapDecoder;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class KerberosDecoder extends ProtocolDecoderAdapter
{
/** The logger */
private static Logger LOG = LoggerFactory.getLogger( LdapDecoder.class );
/** A speedup for logger */
private static final boolean IS_DEBUG = LOG.isDebugEnabled();
/** The ASN 1 decoder instance */
private Asn1Decoder asn1Decoder = new Asn1Decoder();
/** the key used while storing message container in the session */
private static final String KERBEROS_MESSAGE_CONTAINER = "kerberosMessageContainer";
public void decode( IoSession session, IoBuffer in, ProtocolDecoderOutput out ) throws IOException
{
ByteBuffer buf = in.buf();
KerberosMessageContainer kerberosMessageContainer = ( KerberosMessageContainer ) session.getAttribute( KERBEROS_MESSAGE_CONTAINER );
if ( kerberosMessageContainer == null )
{
kerberosMessageContainer = new KerberosMessageContainer();
session.setAttribute( KERBEROS_MESSAGE_CONTAINER, kerberosMessageContainer );
kerberosMessageContainer.setStream( buf );
kerberosMessageContainer.setGathering( true );
}
while ( buf.hasRemaining() )
{
try
{
asn1Decoder.decode( buf, kerberosMessageContainer );
if ( kerberosMessageContainer.getState() == TLVStateEnum.PDU_DECODED )
{
if ( IS_DEBUG )
{
LOG.debug( "Decoded KerberosMessage : " + kerberosMessageContainer.getMessage() );
buf.mark();
}
out.write( kerberosMessageContainer.getMessage() );
kerberosMessageContainer.clean();
}
}
catch ( DecoderException de )
{
buf.clear();
kerberosMessageContainer.clean();
}
catch ( Exception e )
{
LOG.warn( "error while decoding", e );
}
}
}
/**
* Decode an EncrytedData structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of EncryptedData
* @throws KerberosException If the decoding fails
*/
public static EncryptedData decodeEncryptedData( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a EncryptedData Container
Asn1Container encryptedDataContainer = new EncryptedDataContainer();
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the EncryptedData PDU
try
{
kerberosDecoder.decode( stream, encryptedDataContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded EncryptedData
EncryptedData encryptedData = ( ( EncryptedDataContainer ) encryptedDataContainer ).getEncryptedData();
return encryptedData;
}
/**
* Decode an PaEncTsEnc structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of PaEncTsEnc
* @throws KerberosException If the decoding fails
*/
public static PaEncTsEnc decodePaEncTsEnc( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a PaEncTsEnc Container
Asn1Container paEncTsEncContainer = new PaEncTsEncContainer();
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the PaEncTsEnc PDU
try
{
kerberosDecoder.decode( stream, paEncTsEncContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded PaEncTsEnc
PaEncTsEnc paEncTsEnc = ( ( PaEncTsEncContainer ) paEncTsEncContainer ).getPaEncTsEnc();
return paEncTsEnc;
}
/**
* Decode an EncApRepPart structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of EncApRepPart
* @throws KerberosException If the decoding fails
*/
public static EncApRepPart decodeEncApRepPart( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a EncApRepPart Container
Asn1Container encApRepPartContainer = new EncApRepPartContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the EncApRepPart PDU
try
{
kerberosDecoder.decode( stream, encApRepPartContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded EncApRepPart
EncApRepPart encApRepPart = ( ( EncApRepPartContainer ) encApRepPartContainer ).getEncApRepPart();
return encApRepPart;
}
/**
* Decode an EncKdcRepPart structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of EncKdcRepPart
* @throws KerberosException If the decoding fails
*/
public static EncKdcRepPart decodeEncKdcRepPart( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a EncKdcRepPart Container
Asn1Container encKdcRepPartContainer = new EncKdcRepPartContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the EncKdcRepPart PDU
try
{
kerberosDecoder.decode( stream, encKdcRepPartContainer );
}
catch ( DecoderException de )
{
de.printStackTrace();
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded EncKdcRepPart
EncKdcRepPart encKdcRepPart = ( ( EncKdcRepPartContainer ) encKdcRepPartContainer ).getEncKdcRepPart();
return encKdcRepPart;
}
/**
* Decode an EncKrbPrivPart structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of EncKrbPrivPart
* @throws KerberosException If the decoding fails
*/
public static EncKrbPrivPart decodeEncKrbPrivPart( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a EncKrbPrivPart Container
Asn1Container encKrbPrivPartContainer = new EncKrbPrivPartContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the EncKrbPrivPart PDU
try
{
kerberosDecoder.decode( stream, encKrbPrivPartContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded EncKrbPrivPart
EncKrbPrivPart encKrbPrivPart = ( ( EncKrbPrivPartContainer ) encKrbPrivPartContainer ).getEncKrbPrivPart();
return encKrbPrivPart;
}
/**
* Decode an EncTicketPart structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of EncTicketPart
* @throws KerberosException If the decoding fails
*/
public static EncTicketPart decodeEncTicketPart( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a EncTicketPart Container
Asn1Container encTicketPartContainer = new EncTicketPartContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the EncTicketPart PDU
try
{
kerberosDecoder.decode( stream, encTicketPartContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded EncTicketPart
EncTicketPart encTicketPart = ( ( EncTicketPartContainer ) encTicketPartContainer ).getEncTicketPart();
return encTicketPart;
}
/**
* Decode an EncryptionKey structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of EncryptionKey
* @throws KerberosException If the decoding fails
*/
public static EncryptionKey decodeEncryptionKey( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a EncryptionKey Container
Asn1Container encryptionKeyContainer = new EncryptionKeyContainer();
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the EncryptionKey PDU
try
{
kerberosDecoder.decode( stream, encryptionKeyContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded EncryptionKey
EncryptionKey encryptionKey = ( ( EncryptionKeyContainer ) encryptionKeyContainer ).getEncryptionKey();
return encryptionKey;
}
/**
* Decode an PrincipalName structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of PrincipalName
* @throws KerberosException If the decoding fails
*/
public static PrincipalName decodePrincipalName( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a PrincipalName Container
Asn1Container principalNameContainer = new PrincipalNameContainer();
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the PrincipalName PDU
try
{
kerberosDecoder.decode( stream, principalNameContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded PrincipalName
PrincipalName principalName = ( ( PrincipalNameContainer ) principalNameContainer ).getPrincipalName();
return principalName;
}
/**
* Decode a Ticket structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of Ticket
* @throws KerberosException If the decoding fails
*/
public static Ticket decodeTicket( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a Ticket Container
Asn1Container ticketContainer = new TicketContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the Ticket PDU
try
{
kerberosDecoder.decode( stream, ticketContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded Ticket
Ticket ticket = ( ( TicketContainer ) ticketContainer ).getTicket();
return ticket;
}
/**
* Decode a Authenticator structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of Authenticator
* @throws KerberosException If the decoding fails
*/
public static Authenticator decodeAuthenticator( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a Authenticator Container
Asn1Container authenticatorContainer = new AuthenticatorContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the Ticket PDU
try
{
kerberosDecoder.decode( stream, authenticatorContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded Authenticator
Authenticator authenticator = ( ( AuthenticatorContainer ) authenticatorContainer ).getAuthenticator();
return authenticator;
}
/**
* Decode a AuthorizationData structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of AuthorizationData
* @throws KerberosException If the decoding fails
*/
public static AuthorizationData decodeAuthorizationData( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a AuthorizationData Container
Asn1Container authorizationDataContainer = new AuthorizationDataContainer();
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the Ticket PDU
try
{
kerberosDecoder.decode( stream, authorizationDataContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded AuthorizationData
AuthorizationData authorizationData = ( ( AuthorizationDataContainer ) authorizationDataContainer ).getAuthorizationData();
return authorizationData;
}
/**
* Decode a AP-REP structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of ApRep
* @throws KerberosException If the decoding fails
*/
public static ApRep decodeApRep( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a ApRep Container
Asn1Container apRepContainer = new ApRepContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the ApRep PDU
try
{
kerberosDecoder.decode( stream, apRepContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded ApRep
ApRep apRep = ( ( ApRepContainer ) apRepContainer ).getApRep();
return apRep;
}
/**
* Decode a AP-REQ structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of ApReq
* @throws KerberosException If the decoding fails
*/
public static ApReq decodeApReq( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a ApReq Container
Asn1Container apReqContainer = new ApReqContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the ApReq PDU
try
{
kerberosDecoder.decode( stream, apReqContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded ApReq
ApReq apReq = ( ( ApReqContainer ) apReqContainer ).getApReq();
return apReq;
}
/**
* Decode a KRB-PRIV structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of KrbPriv
* @throws KerberosException If the decoding fails
*/
public static KrbPriv decodeKrbPriv( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a KrbPriv Container
Asn1Container krbPrivContainer = new KrbPrivContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the KrbPriv PDU
try
{
kerberosDecoder.decode( stream, krbPrivContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded KrbPriv
KrbPriv krbPriv = ( ( KrbPrivContainer ) krbPrivContainer ).getKrbPriv();
return krbPriv;
}
/**
* Decode an EncAsRepPart structure
*
* @param data The byte array containing the data structure to decode
* @return An instance of EncAsRepPart
* @throws KerberosException If the decoding fails
*/
public static EncAsRepPart decodeEncAsRepPart( byte[] data ) throws KerberosException
{
ByteBuffer stream = ByteBuffer.allocate( data.length );
stream.put( data );
stream.flip();
// Allocate a EncAsRepPart Container
Asn1Container encAsRepPartContainer = new EncAsRepPartContainer( stream );
Asn1Decoder kerberosDecoder = new Asn1Decoder();
// Decode the EncAsRepPart PDU
try
{
kerberosDecoder.decode( stream, encAsRepPartContainer );
}
catch ( DecoderException de )
{
throw new KerberosException( ErrorType.KRB_AP_ERR_BAD_INTEGRITY, de );
}
// get the decoded EncAsRepPart
EncAsRepPart encAsRepPart = ( ( EncAsRepPartContainer ) encAsRepPartContainer ).getEncAsRepPart();
return encAsRepPart;
}
}