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 package org.apache.directory.server.kerberos.shared.io.decoder; 021 022 023 import java.io.IOException; 024 import java.nio.ByteBuffer; 025 import java.util.Enumeration; 026 027 import org.apache.directory.server.kerberos.shared.messages.ErrorMessage; 028 import org.apache.directory.server.kerberos.shared.messages.ErrorMessageModifier; 029 import org.apache.directory.server.kerberos.shared.messages.value.KerberosPrincipalModifier; 030 import org.apache.directory.shared.asn1.der.ASN1InputStream; 031 import org.apache.directory.shared.asn1.der.DERApplicationSpecific; 032 import org.apache.directory.shared.asn1.der.DEREncodable; 033 import org.apache.directory.shared.asn1.der.DERGeneralString; 034 import org.apache.directory.shared.asn1.der.DERGeneralizedTime; 035 import org.apache.directory.shared.asn1.der.DERInteger; 036 import org.apache.directory.shared.asn1.der.DEROctetString; 037 import org.apache.directory.shared.asn1.der.DERSequence; 038 import org.apache.directory.shared.asn1.der.DERTaggedObject; 039 040 041 /** 042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 043 * @version $Rev$, $Date$ 044 */ 045 public class ErrorMessageDecoder 046 { 047 /** 048 * Decodes a {@link ByteBuffer} into an {@link ErrorMessage}. 049 * 050 * KRB-ERROR ::= [APPLICATION 30] SEQUENCE 051 * 052 * @param in 053 * @return The {@link ErrorMessage}. 054 * @throws IOException 055 */ 056 public ErrorMessage decode( ByteBuffer in ) throws IOException 057 { 058 ASN1InputStream ais = new ASN1InputStream( in ); 059 060 DERApplicationSpecific app = ( DERApplicationSpecific ) ais.readObject(); 061 062 DERSequence errorMessage = ( DERSequence ) app.getObject(); 063 064 return decodeErrorMessageSequence( errorMessage ); 065 } 066 067 068 /* 069 KRB-ERROR ::= [APPLICATION 30] SEQUENCE { 070 pvno [0] INTEGER (5), 071 msg-type [1] INTEGER (30), 072 ctime [2] KerberosTime OPTIONAL, 073 cusec [3] Microseconds OPTIONAL, 074 stime [4] KerberosTime, 075 susec [5] Microseconds, 076 error-code [6] Int32, 077 crealm [7] Realm OPTIONAL, 078 cname [8] PrincipalName OPTIONAL, 079 realm [9] Realm -- service realm --, 080 sname [10] PrincipalName -- service name --, 081 e-text [11] KerberosString OPTIONAL, 082 e-data [12] OCTET STRING OPTIONAL 083 } 084 */ 085 private ErrorMessage decodeErrorMessageSequence( DERSequence sequence ) 086 { 087 ErrorMessageModifier errorModifier = new ErrorMessageModifier(); 088 KerberosPrincipalModifier clientModifier = new KerberosPrincipalModifier(); 089 KerberosPrincipalModifier serverModifier = new KerberosPrincipalModifier(); 090 091 for ( Enumeration<DEREncodable> e = sequence.getObjects(); e.hasMoreElements(); ) 092 { 093 DERTaggedObject object = ( DERTaggedObject ) e.nextElement(); 094 int tag = object.getTagNo(); 095 DEREncodable derObject = object.getObject(); 096 097 switch ( tag ) 098 { 099 case 0: 100 // DERInteger tag0 = ( DERInteger ) derObject; 101 // int pvno = tag0.intValue(); 102 break; 103 case 1: 104 // DERInteger tag1 = ( DERInteger ) derObject; 105 // msgType = MessageType.getTypeByOrdinal( tag1.intValue() ); 106 break; 107 case 2: 108 DERGeneralizedTime tag2 = ( DERGeneralizedTime ) derObject; 109 errorModifier.setClientTime( KerberosTimeDecoder.decode( tag2 ) ); 110 break; 111 case 3: 112 DERInteger tag3 = ( DERInteger ) derObject; 113 errorModifier.setClientMicroSecond( tag3.intValue() ); 114 break; 115 case 4: 116 DERGeneralizedTime tag4 = ( DERGeneralizedTime ) derObject; 117 errorModifier.setServerTime( KerberosTimeDecoder.decode( tag4 ) ); 118 break; 119 case 5: 120 DERInteger tag5 = ( DERInteger ) derObject; 121 errorModifier.setServerMicroSecond( tag5.intValue() ); 122 break; 123 case 6: 124 DERInteger tag6 = ( DERInteger ) derObject; 125 errorModifier.setErrorCode( tag6.intValue() ); 126 break; 127 case 7: 128 DERGeneralString tag7 = ( DERGeneralString ) derObject; 129 clientModifier.setRealm( tag7.getString() ); 130 break; 131 case 8: 132 DERSequence tag8 = ( DERSequence ) derObject; 133 clientModifier.setPrincipalName( PrincipalNameDecoder.decode( tag8 ) ); 134 break; 135 case 9: 136 DERGeneralString tag9 = ( DERGeneralString ) derObject; 137 serverModifier.setRealm( tag9.getString() ); 138 break; 139 case 10: 140 DERSequence tag10 = ( DERSequence ) derObject; 141 serverModifier.setPrincipalName( PrincipalNameDecoder.decode( tag10 ) ); 142 break; 143 case 11: 144 DERGeneralString tag11 = ( DERGeneralString ) derObject; 145 errorModifier.setExplanatoryText( tag11.getString() ); 146 break; 147 case 12: 148 DEROctetString tag12 = ( DEROctetString ) derObject; 149 errorModifier.setExplanatoryData( tag12.getOctets() ); 150 break; 151 } 152 } 153 154 errorModifier.setClientPrincipal( clientModifier.getKerberosPrincipal() ); 155 errorModifier.setServerPrincipal( serverModifier.getKerberosPrincipal() ); 156 157 return errorModifier.getErrorMessage(); 158 } 159 }