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.shared.ldap.codec.bind;
021
022
023 import java.nio.BufferOverflowException;
024 import java.nio.ByteBuffer;
025
026 import org.apache.directory.shared.asn1.ber.tlv.TLV;
027 import org.apache.directory.shared.asn1.codec.EncoderException;
028 import org.apache.directory.shared.ldap.codec.LdapConstants;
029 import org.apache.directory.shared.ldap.codec.LdapResponseCodec;
030 import org.apache.directory.shared.ldap.util.StringTools;
031
032
033 /**
034 * A BindResponse Message.
035 *
036 * Its syntax is :
037 * BindResponse ::= [APPLICATION 1] SEQUENCE {
038 * COMPONENTS OF LDAPResult,
039 * serverSaslCreds [7] OCTET STRING OPTIONAL }
040 *
041 * LdapResult ::= resultCode matchedDN errorMessage (referrals)*
042 *
043 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
044 * @version $Rev: 764131 $, $Date: 2009-04-11 03:03:00 +0200 (Sam, 11 avr 2009) $,
045 */
046 public class BindResponseCodec extends LdapResponseCodec
047 {
048 // ~ Instance fields
049 // ----------------------------------------------------------------------------
050
051 /** The server credentials */
052 private byte[] serverSaslCreds;
053
054 /** The bind response length */
055 private int bindResponseLength;
056
057
058 // ~ Constructors
059 // -------------------------------------------------------------------------------
060
061 /**
062 * Creates a new BindResponse object.
063 */
064 public BindResponseCodec()
065 {
066 super();
067 }
068
069
070 // ~ Methods
071 // ------------------------------------------------------------------------------------
072
073 /**
074 * Get the message type
075 *
076 * @return Returns the type.
077 */
078 public int getMessageType()
079 {
080 return LdapConstants.BIND_RESPONSE;
081 }
082
083
084 /**
085 * @return Returns the serverSaslCreds.
086 */
087 public byte[] getServerSaslCreds()
088 {
089 if ( serverSaslCreds == null )
090 {
091 return null;
092 }
093
094 final byte[] copy = new byte[ serverSaslCreds.length ];
095 System.arraycopy( serverSaslCreds, 0, copy, 0, serverSaslCreds.length );
096 return copy;
097 }
098
099
100 /**
101 * Set the server sasl credentials
102 *
103 * @param serverSaslCreds The serverSaslCreds to set.
104 */
105 public void setServerSaslCreds( byte[] serverSaslCreds )
106 {
107 if ( serverSaslCreds != null )
108 {
109 this.serverSaslCreds = new byte[ serverSaslCreds.length ];
110 System.arraycopy( serverSaslCreds, 0, this.serverSaslCreds, 0, serverSaslCreds.length );
111 } else {
112 this.serverSaslCreds = null;
113 }
114 }
115
116
117 /**
118 * Compute the BindResponse length
119 *
120 * BindResponse :
121 * 0x61 L1
122 * |
123 * +--> LdapResult
124 * +--> [serverSaslCreds]
125 *
126 * L1 = Length(LdapResult) [ + Length(serverSaslCreds) ]
127 * Length(BindResponse) = Length(0x61) + Length(L1) + L1
128 */
129 public int computeLength()
130 {
131 int ldapResponseLength = super.computeLength();
132
133 bindResponseLength = ldapResponseLength;
134
135 if ( serverSaslCreds != null )
136 {
137 bindResponseLength += 1 + TLV.getNbBytes( serverSaslCreds.length )
138 + serverSaslCreds.length;
139 }
140
141 return 1 + TLV.getNbBytes( bindResponseLength ) + bindResponseLength;
142 }
143
144
145 /**
146 * Encode the BindResponse message to a PDU. BindResponse :
147 * LdapResult.encode [0x87 LL serverSaslCreds]
148 *
149 * @param buffer The buffer where to put the PDU
150 * @return The PDU.
151 */
152 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
153 {
154 if ( buffer == null )
155 {
156 throw new EncoderException( "Cannot put a PDU in a null buffer !" );
157 }
158
159 try
160 {
161 // The BindResponse Tag
162 buffer.put( LdapConstants.BIND_RESPONSE_TAG );
163 buffer.put( TLV.getBytes( bindResponseLength ) );
164
165 // The LdapResult
166 super.encode( buffer );
167
168 // The serverSaslCredential, if any
169 if ( serverSaslCreds != null )
170 {
171 buffer.put( ( byte ) LdapConstants.SERVER_SASL_CREDENTIAL_TAG );
172
173 buffer.put( TLV.getBytes( serverSaslCreds.length ) );
174
175 if ( serverSaslCreds.length != 0 )
176 {
177 buffer.put( serverSaslCreds );
178 }
179 }
180 }
181 catch ( BufferOverflowException boe )
182 {
183 throw new EncoderException( "The PDU buffer size is too small !" );
184 }
185
186 return buffer;
187 }
188
189
190 /**
191 * Get a String representation of a BindResponse
192 *
193 * @return A BindResponse String
194 */
195 public String toString()
196 {
197 StringBuffer sb = new StringBuffer();
198
199 sb.append( " BindResponse\n" );
200 sb.append( super.toString() );
201
202 if ( serverSaslCreds != null )
203 {
204 sb.append( " Server sasl credentials : '" ).
205 append( StringTools.dumpBytes( serverSaslCreds ) ).
206 append( "'\n" );
207 }
208
209 return sb.toString();
210 }
211 }