Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 85856 invoked from network); 4 Nov 2010 23:49:38 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 4 Nov 2010 23:49:38 -0000 Received: (qmail 24162 invoked by uid 500); 4 Nov 2010 23:50:10 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 24107 invoked by uid 500); 4 Nov 2010 23:50:09 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 24100 invoked by uid 99); 4 Nov 2010 23:50:09 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Nov 2010 23:50:09 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Nov 2010 23:50:05 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id E38B12388A40; Thu, 4 Nov 2010 23:48:50 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1031354 [4/4] - in /directory/apacheds/trunk/kerberos-codec: ./ .settings/ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/directory/ src/main/java/org/apache/directory/shared/ src/main/j... Date: Thu, 04 Nov 2010 23:48:50 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101104234850.E38B12388A40@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/messages/Ticket.java URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/messages/Ticket.java?rev=1031354&view=auto ============================================================================== --- directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/messages/Ticket.java (added) +++ directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/messages/Ticket.java Thu Nov 4 23:48:49 2010 @@ -0,0 +1,550 @@ +/* + * 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.shared.kerberos.messages; + + +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.text.ParseException; + +import javax.security.auth.kerberos.KerberosPrincipal; + +import org.apache.directory.server.i18n.I18n; +import org.apache.directory.shared.asn1.ber.tlv.TLV; +import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; +import org.apache.directory.shared.asn1.ber.tlv.Value; +import org.apache.directory.shared.asn1.codec.EncoderException; +import org.apache.directory.shared.kerberos.KerberosConstants; +import org.apache.directory.shared.kerberos.KerberosMessageType; +import org.apache.directory.shared.kerberos.KerberosUtils; +import org.apache.directory.shared.kerberos.components.EncryptedData; +import org.apache.directory.shared.kerberos.components.PrincipalName; +import org.apache.directory.shared.kerberos.exceptions.ErrorType; +import org.apache.directory.shared.kerberos.exceptions.InvalidTicketException; +import org.apache.directory.shared.ldap.util.StringTools; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sun.security.krb5.internal.EncTicketPart; + + +/** + * Ticket message component as handed out by the ticket granting service. + * + * @author Apache Directory Project + */ +public class Ticket extends KerberosMessage +{ + /** The logger */ + private static final Logger LOG = LoggerFactory.getLogger( Ticket.class ); + + /** Speedup for logs */ + private static final boolean IS_DEBUG = LOG.isDebugEnabled(); + + /** Constant for the {@link Ticket} version number (5) */ + public static final int TICKET_VNO = KerberosConstants.KERBEROS_V5; + + /** The Kerberos version number. Should be 5 */ + private int tktvno; + + /** A storage for a byte array representation of the realm */ + private byte[] realmBytes; + + /** The server principal name */ + private PrincipalName sName; + + /** The server realm */ + private String realm; + + /** The encoded part */ + private EncryptedData encPart; + + /** The decoded ticket part */ + private EncTicketPart encTicketPart; + + // Storage for computed lengths + private transient int tktvnoLength; + private transient int realmLength; + private transient int sNameLength; + private transient int encPartLength; + private transient int ticketSeqLength; + private transient int ticketLength; + + /** + * Creates a new instance of Ticket. + * + * @param serverPrincipal The server principal + * @param encPart The encoded part + */ + public Ticket( KerberosPrincipal serverPrincipal, EncryptedData encPart ) throws InvalidTicketException + { + this( TICKET_VNO, serverPrincipal, encPart ); + + setServerPrincipal( serverPrincipal ); + } + + + /** + * Creates a new instance of Ticket. + */ + public Ticket() + { + super( KerberosMessageType.TICKET ); + } + + + /** + * Creates a new instance of Ticket. + * + * @param tktvno The Kerberos version number + * @param serverPrincipal The server principal + * @param encPart The encoded part + */ + public Ticket( int tktvno, KerberosPrincipal serverPrincipal, EncryptedData encPart ) throws InvalidTicketException + { + super( KerberosMessageType.TICKET ); + this.tktvno = tktvno; + this.encPart = encPart; + setServerPrincipal( serverPrincipal ); + } + + + /** + * Sets the {@link EncTicketPart}. + * + * @param decryptedPart + */ + public void setEncTicketPart( EncTicketPart decryptedPart ) + { + encTicketPart = decryptedPart; + } + + + /** + * Returns the version number. + * + * @return The version number. + */ + public int getTktVno() + { + return tktvno; + } + + + /** + * Set the ticket version number + * @param tktvno the ticket version number + */ + public void setTktVno( int tktvno ) + { + this.tktvno = tktvno; + } + + + /** + * Returns the server {@link PrincipalName}. + * + * @return The server {@link PrincipalName}. + */ + public PrincipalName getSName() + { + return sName; + } + + + /** + * Returns the server {@link KerberosPrincipal}. + * + * @return The server {@link KerberosPrincipal}. + */ + public KerberosPrincipal getServerPrincipal() + { + return KerberosUtils.getKerberosPrincipal( sName, realm ); + } + + + /** + * Set the server principalName + * @param sName the server principalName + */ + public void setSName( PrincipalName sName ) + { + this.sName = sName; + } + + + /** + * Set the server KerberosPrincipal + * @param serverPrincipal the server KerberosPrincipal + */ + public void setServerPrincipal( KerberosPrincipal serverPrincipal ) throws InvalidTicketException + { + try + { + sName = new PrincipalName( serverPrincipal.getName(), serverPrincipal.getNameType() ); + realm = serverPrincipal.getRealm(); + } + catch ( ParseException pe ) + { + LOG.error( I18n.err( I18n.ERR_135, serverPrincipal, pe.getLocalizedMessage() ) ); + throw new InvalidTicketException( ErrorType.KRB_ERR_GENERIC, I18n.err( I18n.ERR_136, pe.getLocalizedMessage() ) ); + } + } + + + /** + * Returns the server realm. + * + * @return The server realm. + */ + public String getRealm() + { + return realm; + } + + + /** + * Set the server realm + * @param realm the server realm + */ + public void setRealm( String realm ) + { + this.realm = realm; + } + + + /** + * Returns the {@link EncryptedData}. + * + * @return The {@link EncryptedData}. + */ + public EncryptedData getEncPart() + { + return encPart; + } + + + /** + * Set the encrypted ticket part + * @param encPart the encrypted ticket part + */ + public void setEncPart( EncryptedData encPart ) + { + this.encPart = encPart; + } + + + /** + * Returns the {@link EncTicketPart}. + * + * @return The {@link EncTicketPart}. + */ + public EncTicketPart getEncTicketPart() + { + return encTicketPart; + } + + + /** + * Returns the {@link AuthorizationData}. + * + * @return The {@link AuthorizationData}. + * + public AuthorizationData getAuthorizationData() + { + return encTicketPart.getAuthorizationData(); + } + */ + + /** + * Returns the auth {@link KerberosTime}. + * + * @return The auth {@link KerberosTime}. + * + public KerberosTime getAuthTime() + { + return encTicketPart.getAuthTime(); + } + */ + + /** + * Returns the client {@link HostAddresses}. + * + * @return The client {@link HostAddresses}. + * + public HostAddresses getClientAddresses() + { + return encTicketPart.getClientAddresses(); + } + */ + + /** + * Returns the client {@link KerberosPrincipal}. + * + * @return The client {@link KerberosPrincipal}. + * + public KerberosPrincipal getClientPrincipal() + { + return encTicketPart.getClientPrincipal(); + } + */ + + /** + * Returns the client {@link PrincipalName}. + * + * @return The client {@link PrincipalName}. + * + public PrincipalName getClientPrincipalName() + { + return encTicketPart.getClientPrincipalName(); + } + */ + + /** + * Returns the client realm. + * + * @return The client realm. + * + public String getClientRealm() + { + return encTicketPart.getClientRealm(); + } + */ + + /** + * Returns the end {@link KerberosTime}. + * + * @return The end {@link KerberosTime}. + * + public KerberosTime getEndTime() + { + return encTicketPart.getEndTime(); + } + */ + + /** + * Returns the {@link TicketFlags}. + * + * @return The {@link TicketFlags}. + * + public TicketFlags getFlags() + { + return encTicketPart.getFlags(); + } + */ + + /** + * Returns the integer value for the {@link TicketFlags}. + * + * @return The {@link TicketFlags}. + * + public int getFlagsIntValue() + { + return encTicketPart.getFlags().getIntValue(); + } + */ + + /** + * Returns the renew till {@link KerberosTime}. + * + * @return The renew till {@link KerberosTime}. + * + public KerberosTime getRenewTill() + { + return encTicketPart.getRenewTill(); + } + */ + + /** + * Returns the session {@link EncryptionKey}. + * + * @return The session {@link EncryptionKey}. + * + public EncryptionKey getSessionKey() + { + return encTicketPart.getSessionKey(); + } + */ + + /** + * Returns the start {@link KerberosTime}. + * + * @return The start {@link KerberosTime}. + * + public KerberosTime getStartTime() + { + return encTicketPart.getStartTime(); + } + */ + + /** + * Returns the {@link TransitedEncoding}. + * + * @return The {@link TransitedEncoding}. + * + public TransitedEncoding getTransitedEncoding() + { + return encTicketPart.getTransitedEncoding(); + } + */ + + /** + * Returns the flag at the given index. + * + * @param flag + * @return true if the flag at the given index is set. + * + public boolean getFlag( int flag ) + { + return encTicketPart.getFlags().isFlagSet( flag ); + } + */ + + /** + * Compute the Ticket length + * + * Ticket : + * + * 0x61 L1 Ticket [APPLICATION 1] + * | + * +--> 0x30 L2 Ticket SEQUENCE + * | + * +--> 0xA0 L3 tkt-vno tag + * | | + * | +--> 0x02 L3-1 tkt-vno (int, 5) + * | + * +--> 0xA1 L4 realm tag + * | | + * | +--> 0x1B L4-1 realm (KerberosString) + * | + * +--> 0xA2 L5 sname (PrincipalName) + * | + * +--> 0xA3 L6 enc-part (EncryptedData) + */ + public int computeLength() + { + // Compute the Ticket version length. + tktvnoLength = 1 + TLV.getNbBytes( tktvno ) + Value.getNbBytes( tktvno ); + + // Compute the Ticket realm length. + realmBytes = StringTools.getBytesUtf8( realm ); + realmLength = 1 + TLV.getNbBytes( realmBytes.length ) + realmBytes.length; + + // Compute the principal length + sNameLength = sName.computeLength(); + + // Compute the encrypted data + encPartLength = encPart.computeLength(); + + // Compute the sequence size + ticketSeqLength = + 1 + TLV.getNbBytes( tktvnoLength ) + tktvnoLength + + 1 + TLV.getNbBytes( realmLength ) + realmLength + + 1 + TLV.getNbBytes( sNameLength ) + sNameLength + + 1 + TLV.getNbBytes( encPartLength ) + encPartLength; + + // compute the global size + ticketLength = 1 + TLV.getNbBytes( ticketSeqLength ) + ticketSeqLength; + + return 1 + TLV.getNbBytes( ticketLength ) + ticketLength; + } + + /** + * Encode the Ticket message to a PDU. + * + * Ticket : + * + * 0x61 LL + * 0x30 LL + * 0xA0 LL tktvno + * 0xA1 LL realm + * 0xA2 LL + * sname (PrincipalName) + * 0xA3 LL + * enc-part (EncryptedData) + * + * @return The constructed PDU. + */ + public ByteBuffer encode() throws EncoderException + { + ByteBuffer buffer = ByteBuffer.allocate( computeLength() ); + + try + { + // The Ticket APPLICATION Tag + buffer.put( (byte)0x61 ); + buffer.put( TLV.getBytes( ticketLength ) ); + + // The Ticket SEQUENCE Tag + buffer.put( UniversalTag.SEQUENCE.getValue() ); + buffer.put( TLV.getBytes( ticketSeqLength ) ); + + // The tkt-vno Tag and value + buffer.put( ( byte ) 0xA0 ); + buffer.put( TLV.getBytes( tktvnoLength ) ); + Value.encode( buffer, tktvno ); + + // The realm Tag and value + buffer.put( ( byte ) 0xA1 ); + buffer.put( TLV.getBytes( realmLength ) ); + buffer.put( UniversalTag.GENERAL_STRING.getValue() ); + buffer.put( TLV.getBytes( realmBytes.length ) ); + buffer.put( realmBytes ); + + // The sname Tag and value + buffer.put( ( byte ) 0xA2 ); + buffer.put( TLV.getBytes( sNameLength ) ); + sName.encode( buffer ); + + // The encPartLength Tag and value + buffer.put( ( byte ) 0xA3 ); + buffer.put( TLV.getBytes( encPartLength ) ); + encPart.encode( buffer ); + } + catch ( BufferOverflowException boe ) + { + LOG.error( I18n.err( I18n.ERR_137, 1 + TLV.getNbBytes( ticketLength ) + ticketLength, + buffer.capacity() ) ); + throw new EncoderException( I18n.err( I18n.ERR_138 ) ); + } + + if ( IS_DEBUG ) + { + LOG.debug( "Ticket encoding : {}", StringTools.dumpBytes( buffer.array() ) ); + LOG.debug( "Ticket initial value : {}", toString() ); + } + + return buffer; + } + + + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append( "Ticket :\n" ); + sb.append( " tkt-vno : " ).append( tktvno ).append( "\n" ); + sb.append( " realm : " ).append( realm ).append( "\n" ); + sb.append( " sname : " ).append( sName ).append( "\n" ); + sb.append( " enc-part : " ).append( encPart ).append( "\n" ); + + return sb.toString(); + } +} Added: directory/apacheds/trunk/kerberos-codec/src/test/java/org/apache/directory/shared/kerberos/codec/TicketDecoderTest.java URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-codec/src/test/java/org/apache/directory/shared/kerberos/codec/TicketDecoderTest.java?rev=1031354&view=auto ============================================================================== --- directory/apacheds/trunk/kerberos-codec/src/test/java/org/apache/directory/shared/kerberos/codec/TicketDecoderTest.java (added) +++ directory/apacheds/trunk/kerberos-codec/src/test/java/org/apache/directory/shared/kerberos/codec/TicketDecoderTest.java Thu Nov 4 23:48:49 2010 @@ -0,0 +1,122 @@ +/* + * 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.shared.kerberos.codec; + + +import static org.junit.Assert.fail; + +import java.nio.ByteBuffer; + +import org.apache.directory.junit.tools.Concurrent; +import org.apache.directory.junit.tools.ConcurrentJunitRunner; +import org.apache.directory.shared.asn1.ber.Asn1Container; +import org.apache.directory.shared.asn1.ber.Asn1Decoder; +import org.apache.directory.shared.asn1.codec.DecoderException; +import org.apache.directory.shared.kerberos.messages.KerberosMessage; +import org.apache.directory.shared.ldap.util.StringTools; +import org.junit.Test; +import org.junit.runner.RunWith; + + +/** + * @author Apache Directory Project + */ +@RunWith(ConcurrentJunitRunner.class) +@Concurrent() +public class TicketDecoderTest +{ + /** The encoder instance */ + //LdapEncoder encoder = new LdapEncoder(); + + /** + * Test the decoding of a Ticket message + */ + @Test + public void testDecodeTicket() + { + Asn1Decoder kerberosDecoder = new Asn1Decoder(); + + ByteBuffer stream = ByteBuffer.allocate( 0x35 ); + byte LL = 0; + + stream.put( new byte[] + { 0x61, 0x2C, // Ticket + 0x30, 0x2A, + (byte)0xA0, 0x03, // tkt-vno + 0x02, 0x01, 0x05, // 5 + (byte)0xA1, 0x0D, // realm + 0x1B, 0x0B, 'E', 'X', 'A', 'M', 'P', 'L', 'E', '.', 'C', 'O', 'M', + (byte)0xA2, 0x14, // sname + 0x30, 0x12, + (byte)0xA1, 0x03, // name-type + 0x02, 0x01, 0x01, // NT-PRINCIPAL + (byte)0xA2, 0x0B, // name-string + 0x30, 0x09, + 0x1B, 0x07, 'h', 'n', 'e', 'l', 's', 'o', 'n', + (byte)0xA3, 0x02, 0x01, 0x02 // enc-part + } ); + + String decodedPdu = StringTools.dumpBytes( stream.array() ); + stream.flip(); + + // Allocate a KerberosMessage Container + Asn1Container kerberosMessageContainer = new KerberosMessageContainer(); + + // Decode the Ticket PDU + try + { + kerberosDecoder.decode( stream, kerberosMessageContainer ); + } + catch ( DecoderException de ) + { + de.printStackTrace(); + fail( de.getMessage() ); + } + + // Check the decoded BindRequest + KerberosMessage ticket = ( ( KerberosMessageContainer ) kerberosMessageContainer ).getMessage(); + + /* + assertEquals( 1, bindRequest.getMessageId() ); + assertTrue( bindRequest.isVersion3() ); + assertEquals( "uid=akarasulu,dc=example,dc=com", bindRequest.getName().toString() ); + assertTrue( bindRequest.isSimple() ); + assertEquals( "password", StringTools.utf8ToString( bindRequest.getCredentials() ) ); + + // Check the encoding + try + { + ByteBuffer bb = encoder.encodeMessage( bindRequest ); + + // Check the length + assertEquals( 0x35, bb.limit() ); + + String encodedPdu = StringTools.dumpBytes( bb.array() ); + + assertEquals( encodedPdu, decodedPdu ); + } + catch ( EncoderException ee ) + { + ee.printStackTrace(); + fail( ee.getMessage() ); + } + */ + } +}