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.ber.tlv.Value;
028 import org.apache.directory.shared.asn1.codec.EncoderException;
029 import org.apache.directory.shared.ldap.codec.LdapConstants;
030 import org.apache.directory.shared.ldap.util.StringTools;
031 import org.slf4j.Logger;
032 import org.slf4j.LoggerFactory;
033
034
035 /**
036 * A ldapObject which stores the SASL authentication of a BindRequest.
037 *
038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
039 * @version $Rev: 664290 $, $Date: 2008-06-07 08:28:06 +0200 (Sam, 07 jui 2008) $,
040 */
041 public class SaslCredentials extends LdapAuthentication
042 {
043 /** The logger */
044 private static Logger log = LoggerFactory.getLogger( SimpleAuthentication.class );
045
046 /** Speedup for logs */
047 private static final boolean IS_DEBUG = log.isDebugEnabled();
048
049 // ~ Instance fields
050 // ----------------------------------------------------------------------------
051
052 /**
053 * Any mechanism defined in RFC 2222 : KERBEROS_V4, GSSAPI, SKEY, EXTERNAL
054 */
055 private String mechanism;
056
057 /** The mechanism bytes */
058 private byte[] mechanismBytes;
059
060 /** optional credentials of the user */
061 private byte[] credentials;
062
063 /** The mechanism length */
064 private int mechanismLength;
065
066 /** The credentials length */
067 private int credentialsLength;
068
069
070 /**
071 * @see Asn1Object#Asn1Object
072 */
073 public SaslCredentials()
074 {
075 super();
076 }
077
078 // ~ Methods
079 // ------------------------------------------------------------------------------------
080
081 /**
082 * Get the credentials
083 *
084 * @return The credentials
085 */
086 public byte[] getCredentials()
087 {
088 if ( credentials == null )
089 {
090 return null;
091 }
092
093 final byte[] copy = new byte[ credentials.length ];
094 System.arraycopy( credentials, 0, copy, 0, credentials.length );
095 return copy;
096 }
097
098
099 /**
100 * Set the credentials
101 *
102 * @param credentials The credentials
103 */
104 public void setCredentials( byte[] credentials )
105 {
106 if ( credentials != null )
107 {
108 this.credentials = new byte[ credentials.length ];
109 System.arraycopy( credentials, 0, this.credentials, 0, credentials.length );
110 } else {
111 this.credentials = null;
112 }
113 }
114
115
116 /**
117 * Get the mechanism
118 *
119 * @return The mechanism
120 */
121 public String getMechanism()
122 {
123
124 return ( ( mechanism == null ) ? null : mechanism );
125 }
126
127
128 /**
129 * Set the mechanism
130 *
131 * @param mechanism The mechanism
132 */
133 public void setMechanism( String mechanism )
134 {
135 this.mechanism = mechanism;
136 }
137
138
139 /**
140 * Compute the Sasl authentication length
141 *
142 * Sasl authentication :
143 *
144 * 0xA3 L1
145 * 0x04 L2 mechanism
146 * [0x04 L3 credentials]
147 *
148 * L2 = Length(mechanism)
149 * L3 = Length(credentials)
150 * L1 = L2 + L3
151 *
152 * Length(Sasl authentication) = Length(0xA3) + Length(L1) +
153 * Length(0x04) + Length(L2) + Length(mechanism)
154 * [+ Length(0x04) + Length(L3) + Length(credentials)]
155 */
156 public int computeLength()
157 {
158 mechanismBytes = StringTools.getBytesUtf8( mechanism );
159 mechanismLength = 1 + TLV.getNbBytes( mechanismBytes.length ) + mechanismBytes.length;
160 credentialsLength = 0;
161
162 if ( credentials != null )
163 {
164 credentialsLength = 1 + TLV.getNbBytes( credentials.length ) + credentials.length;
165 }
166
167 int saslLength = 1 + TLV.getNbBytes( mechanismLength + credentialsLength ) + mechanismLength
168 + credentialsLength;
169
170 if ( IS_DEBUG )
171 {
172 log.debug( "SASL Authentication length : {}", Integer.valueOf( saslLength ) );
173 }
174
175 return saslLength;
176 }
177
178
179 /**
180 * Encode the sasl authentication to a PDU.
181 *
182 * SimpleAuthentication :
183 * 0xA3 L1
184 * 0x04 L2 mechanism
185 * [0x04 L3 credentials]
186 *
187 * @param buffer The buffer where to put the PDU
188 * @return The PDU.
189 */
190 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
191 {
192 if ( buffer == null )
193 {
194 log.error( "Cannot put a PDU in a null buffer !" );
195 throw new EncoderException( "Cannot put a PDU in a null buffer !" );
196 }
197
198 try
199 {
200 // The saslAuthentication Tag
201 buffer.put( ( byte ) LdapConstants.BIND_REQUEST_SASL_TAG );
202
203 buffer.put( TLV.getBytes( mechanismLength + credentialsLength ) );
204
205 Value.encode( buffer, mechanism );
206
207 if ( credentials != null )
208 {
209 Value.encode( buffer, credentials );
210 }
211 }
212 catch ( BufferOverflowException boe )
213 {
214 log.error( "The PDU buffer size is too small !" );
215 throw new EncoderException( "The PDU buffer size is too small !" );
216 }
217
218 return buffer;
219 }
220
221
222 /**
223 * Get a String representation of a SaslCredential
224 *
225 * @return A SaslCredential String
226 */
227 public String toString()
228 {
229
230 StringBuffer sb = new StringBuffer();
231
232 sb.append( " Sasl credentials\n" );
233 sb.append( " Mechanism :'" ).append( mechanism ).append( "'\n" );
234
235 if ( credentials != null )
236 {
237 sb.append( " Credentials :'" ).
238 append( StringTools.dumpBytes( credentials ) ).
239 append( "'\n" );
240 }
241
242 return sb.toString();
243 }
244 }