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