| /* |
| * 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.assertTrue; |
| |
| import java.lang.reflect.Field; |
| import java.nio.ByteBuffer; |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.directory.api.asn1.DecoderException; |
| import org.apache.directory.api.asn1.ber.Asn1Decoder; |
| import org.apache.directory.api.util.Network; |
| import org.apache.directory.api.util.Strings; |
| import org.apache.directory.shared.kerberos.KerberosTime; |
| import org.apache.directory.shared.kerberos.codec.krbCredInfo.KrbCredInfoContainer; |
| import org.apache.directory.shared.kerberos.codec.types.EncryptionType; |
| import org.apache.directory.shared.kerberos.codec.types.PrincipalNameType; |
| import org.apache.directory.shared.kerberos.components.EncryptionKey; |
| import org.apache.directory.shared.kerberos.components.HostAddress; |
| import org.apache.directory.shared.kerberos.components.HostAddresses; |
| import org.apache.directory.shared.kerberos.components.KrbCredInfo; |
| import org.apache.directory.shared.kerberos.components.PrincipalName; |
| import org.apache.directory.shared.kerberos.flags.TicketFlag; |
| import org.apache.directory.shared.kerberos.flags.TicketFlags; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| |
| /** |
| * Test cases for KrbCredInfo codec. |
| * |
| * This test class assumes that the encoding of KrbCredInfo class is correct and highly relies on its functionality |
| * to generate test PDUs instead of generating them by hand. Also note that the accuracy of this test case depends on |
| * the accuracy of the encoding done by the components constituted in KrbCredInfo ASN.1 structure |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| public class KrbCredInfoDecoderTest |
| { |
| private EncryptionKey key; |
| private String pRealm; |
| private PrincipalName pName; |
| private TicketFlags ticketFlags; |
| private KerberosTime authTime; |
| private KerberosTime startTime; |
| private KerberosTime endTime; |
| private KerberosTime renewtill; |
| private String sRealm; |
| private PrincipalName sName; |
| private HostAddresses clientAddresses; |
| |
| private List<FieldValueHolder> optionalFieldValueList; |
| |
| class FieldValueHolder |
| { |
| String fieldName; |
| Object value; |
| |
| |
| FieldValueHolder( String fieldName, Object value ) |
| { |
| this.fieldName = fieldName; |
| this.value = value; |
| } |
| |
| |
| @Override |
| public String toString() |
| { |
| return "FieldValueHolder [fieldName=" + fieldName + ", value=" + value + "]"; |
| } |
| } |
| |
| |
| @Before |
| public void setup() throws Exception |
| { |
| optionalFieldValueList = new ArrayList<FieldValueHolder>(); |
| |
| key = new EncryptionKey( EncryptionType.DES3_CBC_MD5, new byte[] |
| { 0, 1 } ); |
| |
| pRealm = "prealm"; |
| // NOTE: we have to add each field manually cause order is important |
| optionalFieldValueList.add( new FieldValueHolder( "pRealm", pRealm ) ); |
| |
| ticketFlags = new TicketFlags( TicketFlag.INITIAL.getValue() ); |
| optionalFieldValueList.add( new FieldValueHolder( "ticketFlags", ticketFlags ) ); |
| |
| authTime = new KerberosTime( new Date().getTime() ); |
| optionalFieldValueList.add( new FieldValueHolder( "authTime", authTime ) ); |
| |
| startTime = new KerberosTime( new Date().getTime() ); |
| optionalFieldValueList.add( new FieldValueHolder( "startTime", startTime ) ); |
| |
| endTime = new KerberosTime( new Date().getTime() ); |
| optionalFieldValueList.add( new FieldValueHolder( "endTime", endTime ) ); |
| |
| renewtill = new KerberosTime( new Date().getTime() ); |
| optionalFieldValueList.add( new FieldValueHolder( "renewtill", renewtill ) ); |
| |
| sRealm = "srealm"; |
| optionalFieldValueList.add( new FieldValueHolder( "sRealm", sRealm ) ); |
| |
| pName = new PrincipalName( "pname", PrincipalNameType.KRB_NT_PRINCIPAL ); |
| optionalFieldValueList.add( new FieldValueHolder( "pName", pName ) ); |
| |
| sName = new PrincipalName( "sname", PrincipalNameType.KRB_NT_PRINCIPAL ); |
| optionalFieldValueList.add( new FieldValueHolder( "sName", sName ) ); |
| |
| clientAddresses = new HostAddresses( new HostAddress[] |
| { new HostAddress( Network.LOOPBACK ) } ); |
| optionalFieldValueList.add( new FieldValueHolder( "clientAddresses", clientAddresses ) ); |
| } |
| |
| |
| @Test |
| public void testKrbCredInfo() throws Exception |
| { |
| // algorithm: |
| // start from the first mandatory element and then add one of the subsequent OPTIONAL elements(in order) then |
| // start adding/removing subsequent OPTIONAL elements(those which fall after the above OPTIONAL element) |
| // one by one and then test decoding |
| |
| int size = optionalFieldValueList.size(); |
| |
| for ( int i = 0; i < size; i++ ) |
| { |
| KrbCredInfo expected = new KrbCredInfo(); |
| expected.setKey( key ); |
| Map<String, Field> krbCredInfoFieldNameMap = getFieldMap( expected ); |
| |
| List<FieldValueHolder> presentFieldList = new ArrayList<FieldValueHolder>(); |
| |
| FieldValueHolder fieldValHolder = optionalFieldValueList.get( i ); |
| presentFieldList.add( fieldValHolder ); |
| |
| Field f = krbCredInfoFieldNameMap.get( Strings.toLowerCaseAscii( fieldValHolder.fieldName ) ); |
| f.set( expected, fieldValHolder.value ); |
| |
| for ( int j = i + 1; j < size; j++ ) |
| { |
| fieldValHolder = optionalFieldValueList.get( j ); |
| presentFieldList.add( fieldValHolder ); |
| f = krbCredInfoFieldNameMap.get( Strings.toLowerCaseAscii( fieldValHolder.fieldName ) ); |
| f.set( expected, fieldValHolder.value ); |
| } |
| |
| ByteBuffer stream = ByteBuffer.allocate( expected.computeLength() ); |
| expected.encode( stream ); |
| stream.flip(); |
| |
| KrbCredInfoContainer container = new KrbCredInfoContainer(); |
| container.setStream( stream ); |
| |
| try |
| { |
| Asn1Decoder.decode( stream, container ); |
| } |
| catch ( DecoderException e ) |
| { |
| // NOTE: keep this sysout for easy debugging (no need to setup a logger) |
| System.out.println( "failed sequence:\n" + expected ); |
| throw e; |
| } |
| |
| KrbCredInfo actual = container.getKrbCredInfo(); |
| assertValues( presentFieldList, actual ); |
| } |
| |
| } |
| |
| |
| @Test |
| public void testKrbCredInfoWithEachOptElement() throws Exception |
| { |
| // algorithm: |
| // start from the first mandatory element and add ONLY one OPTIONAL element and then test decoding |
| |
| int size = optionalFieldValueList.size(); |
| for ( int i = size - 1; i >= 0; i-- ) |
| { |
| KrbCredInfo expected = new KrbCredInfo(); |
| expected.setKey( key ); |
| Map<String, Field> krbCredInfoFieldNameMap = getFieldMap( expected ); |
| |
| List<FieldValueHolder> presentFieldList = new ArrayList<FieldValueHolder>(); |
| |
| FieldValueHolder fieldValHolder = optionalFieldValueList.get( i ); |
| presentFieldList.add( fieldValHolder ); |
| |
| Field f = krbCredInfoFieldNameMap.get( Strings.toLowerCaseAscii( fieldValHolder.fieldName ) ); |
| f.set( expected, fieldValHolder.value ); |
| |
| ByteBuffer stream = ByteBuffer.allocate( expected.computeLength() ); |
| expected.encode( stream ); |
| stream.flip(); |
| |
| KrbCredInfoContainer container = new KrbCredInfoContainer(); |
| container.setStream( stream ); |
| |
| try |
| { |
| Asn1Decoder.decode( stream, container ); |
| } |
| catch ( DecoderException e ) |
| { |
| // NOTE: keep this sysout for easy debugging (no need to setup a logger) |
| System.out.println( "failed sequence:\n" + expected ); |
| throw e; |
| } |
| |
| KrbCredInfo actual = container.getKrbCredInfo(); |
| assertValues( presentFieldList, actual ); |
| } |
| } |
| |
| |
| /** |
| * compare the values that are inserted into the KrbCredInfo objects before encoding to |
| * those that are obtained from decoded KrbCredInfo |
| * |
| * @param presentFieldList the list of values that were inserted in the KrbCredInfo class before encoding |
| * @param decoded the decoded KrbCredInfo object |
| */ |
| private void assertValues( List<FieldValueHolder> presentFieldList, KrbCredInfo decoded ) throws Exception |
| { |
| Map<String, Field> krbCredInfoFieldNameMap = getFieldMap( decoded ); |
| |
| for ( FieldValueHolder fh : presentFieldList ) |
| { |
| Field actualField = krbCredInfoFieldNameMap.get( Strings.toLowerCaseAscii( fh.fieldName ) ); |
| Object decodedValue = actualField.get( decoded ); |
| |
| //System.out.println( fh.fieldName + " expected: " + fh.value + " , actual: " + decodedValue ); |
| |
| assertTrue( decodedValue.equals( fh.value ) ); |
| } |
| } |
| |
| |
| /** |
| * create a map with the field's name and field objects of the KrbCreInfo |
| * |
| * @param source the KrbCredInfo object |
| */ |
| private Map<String, Field> getFieldMap( KrbCredInfo source ) |
| { |
| Field[] fields = source.getClass().getDeclaredFields(); |
| |
| Map<String, Field> fieldNameMap = new HashMap<String, Field>(); |
| |
| for ( Field f : fields ) |
| { |
| f.setAccessible( true ); |
| fieldNameMap.put( Strings.toLowerCaseAscii( f.getName() ), f ); |
| } |
| |
| return fieldNameMap; |
| } |
| } |