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.server.kerberos.changepwd.messages; 021 022 023import java.nio.ByteBuffer; 024 025import org.apache.directory.api.asn1.DecoderException; 026import org.apache.directory.api.asn1.EncoderException; 027import org.apache.directory.api.asn1.ber.Asn1Decoder; 028import org.apache.directory.api.util.Strings; 029import org.apache.directory.server.kerberos.changepwd.exceptions.ChangePasswdErrorType; 030import org.apache.directory.server.kerberos.changepwd.exceptions.ChangePasswordException; 031import org.apache.directory.shared.kerberos.codec.krbError.KrbErrorContainer; 032import org.apache.directory.shared.kerberos.messages.KrbError; 033 034 035/** 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 */ 039public class ChangePasswordError extends AbstractPasswordMessage 040{ 041 private KrbError krbError; 042 043 private short krbErrorLen; 044 private short messageLength; 045 046 public ChangePasswordError( KrbError krbError ) 047 { 048 this( PVNO, krbError ); 049 } 050 051 /** 052 * Creates a new instance of ChangePasswordError. 053 * 054 * @param versionNumber The version number 055 * @param krbError The KRB-ERROR 056 */ 057 public ChangePasswordError( short versionNumber, KrbError krbError ) 058 { 059 super( versionNumber ); 060 061 this.krbError = krbError; 062 } 063 064 065 /** 066 * Returns the {@link KrbError}. 067 * 068 * @return The {@link KrbError}. 069 */ 070 public KrbError getKrbError() 071 { 072 return krbError; 073 } 074 075 076 @Override 077 public short computeLength() 078 { 079 krbErrorLen = ( short ) krbError.computeLength(); 080 messageLength = ( short ) ( HEADER_LENGTH + krbErrorLen ); 081 082 return messageLength; 083 } 084 085 @Override 086 public ByteBuffer encode( ByteBuffer buf ) throws EncoderException 087 { 088 buf.putShort( messageLength ); 089 090 buf.putShort( getVersionNumber() ); 091 092 buf.putShort( ( short )0 ); // zero means, what follows is an error 093 094 krbError.encode( buf ); 095 096 return buf; 097 } 098 099 /** 100 * Decodes a {@link ByteBuffer} into a {@link ChangePasswordError}. 101 * 102 * @param buf The buffer containing the ChangePasswordError to decode 103 * @return The {@link ChangePasswordError}. 104 * @throws ChangePasswordException If the decoding failed 105 */ 106 public static ChangePasswordError decode( ByteBuffer buf ) throws ChangePasswordException 107 { 108 short messageLength = buf.getShort(); 109 110 short pvno = buf.getShort(); 111 112 // AP_REQ length will be 0 for error messages 113 buf.getShort(); // authHeader length 114 115 int errorLength = messageLength - HEADER_LENGTH; 116 117 byte[] errorBytes = new byte[errorLength]; 118 119 buf.get( errorBytes ); 120 ByteBuffer errorBuffer = ByteBuffer.wrap( errorBytes ); 121 122 KrbErrorContainer container = new KrbErrorContainer( errorBuffer ); 123 124 try 125 { 126 Asn1Decoder.decode( errorBuffer, container ); 127 } 128 catch( DecoderException e ) 129 { 130 throw new ChangePasswordException( ChangePasswdErrorType.KRB5_KPASSWD_MALFORMED, e ); 131 } 132 133 KrbError errorMessage = container.getKrbError(); 134 135 return new ChangePasswordError( pvno, errorMessage ); 136 } 137 138 public ChangePasswdErrorType getResultCode() 139 { 140 ByteBuffer buf = ByteBuffer.wrap( krbError.getEData() ); 141 142 return ChangePasswdErrorType.getTypeByValue( buf.getShort() ); 143 } 144 145 public String getResultString() 146 { 147 byte[] edata = krbError.getEData(); 148 149 // first two bytes contain the result code 150 return Strings.utf8ToString( edata, 2, edata.length - 2 ); 151 } 152}