blob: 3a5f49765c61e844254fd3c3eb699042702f52a3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.shared.ldap.codec.message;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.directory.shared.asn1.EncoderException;
import org.apache.directory.shared.asn1.ber.tlv.TLV;
import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
import org.apache.directory.shared.asn1.ber.tlv.Value;
import org.apache.directory.shared.asn1.util.Asn1StringUtils;
import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.codec.LdapConstants;
import org.apache.directory.shared.ldap.codec.MessageEncoderException;
import org.apache.directory.shared.ldap.codec.controls.CodecControl;
import org.apache.directory.shared.ldap.entry.BinaryValue;
import org.apache.directory.shared.ldap.entry.Entry;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.apache.directory.shared.ldap.entry.Modification;
import org.apache.directory.shared.ldap.message.*;
import org.apache.directory.shared.ldap.message.control.Control;
import org.apache.directory.shared.ldap.name.DN;
import org.apache.directory.shared.ldap.util.StringTools;
import org.apache.directory.shared.util.Strings;
/**
* LDAP BER encoder.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class LdapEncoder
{
/**
* Generate the PDU which contains the encoded object.
*
* The generation is done in two phases :
* - first, we compute the length of each part and the
* global PDU length
* - second, we produce the PDU.
*
* <pre>
* 0x30 L1
* |
* +--> 0x02 L2 MessageId
* +--> ProtocolOp
* +--> Controls
*
* L2 = Length(MessageId)
* L1 = Length(0x02) + Length(L2) + L2 + Length(ProtocolOp) + Length(Controls)
* LdapMessageLength = Length(0x30) + Length(L1) + L1
* </pre>
*
* @param message The message to encode
* @return A ByteBuffer that contains the PDU
* @throws EncoderException If anything goes wrong.
*/
public ByteBuffer encodeMessage( Message message ) throws EncoderException
{
int length = computeMessageLength( message );
ByteBuffer buffer = ByteBuffer.allocate( length );
try
{
try
{
// The LdapMessage Sequence
buffer.put( UniversalTag.SEQUENCE.getValue() );
// The length has been calculated by the computeLength method
buffer.put( TLV.getBytes( ( (AbstractMessage) message ).getMessageLength() ) );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
// The message Id
Value.encode( buffer, message.getMessageId() );
// Add the protocolOp part
encodeProtocolOp( buffer, message );
// Do the same thing for Controls, if any.
Map<String, Control> controls = message.getControls();
if ( ( controls != null ) && ( controls.size() > 0 ) )
{
// Encode the controls
buffer.put( ( byte ) LdapConstants.CONTROLS_TAG );
buffer.put( TLV.getBytes( ( ( AbstractMessage ) message ).getControlsLength() ) );
// Encode each control
for ( Control control : controls.values() )
{
( ( CodecControl ) control ).encode( buffer );
}
}
}
catch ( EncoderException ee )
{
MessageEncoderException exception = new MessageEncoderException( message.getMessageId(), ee.getMessage() );
throw exception;
}
buffer.flip();
return buffer;
}
/**
* Compute the LdapMessage length LdapMessage :
* 0x30 L1
* |
* +--> 0x02 0x0(1-4) [0..2^31-1] (MessageId)
* +--> protocolOp
* [+--> Controls]
*
* MessageId length = Length(0x02) + length(MessageId) + MessageId.length
* L1 = length(ProtocolOp)
* LdapMessage length = Length(0x30) + Length(L1) + MessageId length + L1
*/
private int computeMessageLength( Message message )
{
// The length of the MessageId. It's the sum of
// - the tag (0x02), 1 byte
// - the length of the Id length, 1 byte
// - the Id length, 1 to 4 bytes
int ldapMessageLength = 1 + 1 + Value.getNbBytes( message.getMessageId() );
// Get the protocolOp length
ldapMessageLength += computeProtocolOpLength( message );
Map<String, Control> controls = message.getControls();
// Do the same thing for Controls, if any.
if ( controls.size() > 0 )
{
// Controls :
// 0xA0 L3
// |
// +--> 0x30 L4
// +--> 0x30 L5
// +--> ...
// +--> 0x30 Li
// +--> ...
// +--> 0x30 Ln
//
// L3 = Length(0x30) + Length(L5) + L5
// + Length(0x30) + Length(L6) + L6
// + ...
// + Length(0x30) + Length(Li) + Li
// + ...
// + Length(0x30) + Length(Ln) + Ln
//
// LdapMessageLength = LdapMessageLength + Length(0x90)
// + Length(L3) + L3
int controlsSequenceLength = 0;
// We may have more than one control. ControlsLength is L4.
for ( Control control : controls.values() )
{
controlsSequenceLength += ( ( CodecControl ) control ).computeLength();
}
// Computes the controls length
// 1 + Length.getNbBytes( controlsSequenceLength ) + controlsSequenceLength;
( ( AbstractMessage ) message ).setControlsLength( controlsSequenceLength );
// Now, add the tag and the length of the controls length
ldapMessageLength += 1 + TLV.getNbBytes( controlsSequenceLength ) + controlsSequenceLength;
}
// Store the messageLength
( ( AbstractMessage ) message ).setMessageLength( ldapMessageLength );
// finally, calculate the global message size :
// length(Tag) + Length(length) + length
return 1 + ldapMessageLength + TLV.getNbBytes( ldapMessageLength );
}
/**
* Compute the LdapResult length
*
* LdapResult :
* 0x0A 01 resultCode (0..80)
* 0x04 L1 matchedDN (L1 = Length(matchedDN))
* 0x04 L2 errorMessage (L2 = Length(errorMessage))
* [0x83 L3] referrals
* |
* +--> 0x04 L4 referral
* +--> 0x04 L5 referral
* +--> ...
* +--> 0x04 Li referral
* +--> ...
* +--> 0x04 Ln referral
*
* L1 = Length(matchedDN)
* L2 = Length(errorMessage)
* L3 = n*Length(0x04) + sum(Length(L4) .. Length(Ln)) + sum(L4..Ln)
* L4..n = Length(0x04) + Length(Li) + Li
* Length(LdapResult) = Length(0x0x0A) +
* Length(0x01) + 1 + Length(0x04) + Length(L1) + L1 + Length(0x04) +
* Length(L2) + L2 + Length(0x83) + Length(L3) + L3
*/
private int computeLdapResultLength( LdapResult internalLdapResult )
{
LdapResultImpl ldapResult = ( LdapResultImpl ) internalLdapResult;
int ldapResultLength = 0;
// The result code : always 3 bytes
ldapResultLength = 1 + 1 + 1;
// The matchedDN length
if ( ldapResult.getMatchedDn() == null )
{
ldapResultLength += 1 + 1;
}
else
{
byte[] matchedDNBytes = Strings.getBytesUtf8(StringTools
.trimLeft(ldapResult.getMatchedDn().getName()));
ldapResultLength += 1 + TLV.getNbBytes( matchedDNBytes.length ) + matchedDNBytes.length;
ldapResult.setMatchedDnBytes( matchedDNBytes );
}
// The errorMessage length
byte[] errorMessageBytes = Strings.getBytesUtf8(ldapResult.getErrorMessage());
ldapResultLength += 1 + TLV.getNbBytes( errorMessageBytes.length ) + errorMessageBytes.length;
ldapResult.setErrorMessageBytes( errorMessageBytes );
int referralLength = computeReferralLength( ldapResult.getReferral() );
if ( referralLength != 0 )
{
// The referrals
ldapResultLength += 1 + TLV.getNbBytes( referralLength ) + referralLength;
}
return ldapResultLength;
}
/**
* Encode the LdapResult message to a PDU.
*
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private ByteBuffer encodeLdapResult( ByteBuffer buffer, LdapResult internalLdapResult ) throws EncoderException
{
LdapResultImpl ldapResult = ( LdapResultImpl ) internalLdapResult;
if ( buffer == null )
{
throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
}
try
{
// The result code
buffer.put( UniversalTag.ENUMERATED.getValue() );
buffer.put( ( byte ) 1 );
buffer.put( ( byte ) ldapResult.getResultCode().getValue() );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
// The matchedDN
Value.encode( buffer, ldapResult.getMatchedDnBytes() );
// The error message
Value.encode( buffer, ldapResult.getErrorMessageBytes() );
// The referrals, if any
Referral referral = ldapResult.getReferral();
if ( referral != null )
{
encodeReferral( buffer, referral );
}
return buffer;
}
/**
* Encode the Referral message to a PDU.
*
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeReferral( ByteBuffer buffer, Referral referral ) throws EncoderException
{
Collection<byte[]> ldapUrlsBytes = referral.getLdapUrlsBytes();
if ( ( ldapUrlsBytes != null ) && ( ldapUrlsBytes.size() != 0 ) )
{
// Encode the referrals sequence
// The referrals length MUST have been computed before !
buffer.put( ( byte ) LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG );
buffer.put( TLV.getBytes( referral.getReferralLength() ) );
// Each referral
for ( byte[] ldapUrlBytes : ldapUrlsBytes )
{
// Encode the current referral
Value.encode( buffer, ldapUrlBytes );
}
}
}
/**
* Compute the AbandonRequest length
*
* AbandonRequest :
* 0x50 0x0(1..4) abandoned MessageId
*
* Length(AbandonRequest) = Length(0x50) + 1 + Length(abandoned MessageId)
*/
private int computeAbandonRequestLength( AbandonRequestImpl abandonRequest )
{
int length = 1 + 1 + Value.getNbBytes(abandonRequest.getAbandoned());
return length;
}
/**
* Compute the AddRequest length
*
* AddRequest :
*
* 0x68 L1
* |
* +--> 0x04 L2 entry
* +--> 0x30 L3 (attributes)
* |
* +--> 0x30 L4-1 (attribute)
* | |
* | +--> 0x04 L5-1 type
* | +--> 0x31 L6-1 (values)
* | |
* | +--> 0x04 L7-1-1 value
* | +--> ...
* | +--> 0x04 L7-1-n value
* |
* +--> 0x30 L4-2 (attribute)
* | |
* | +--> 0x04 L5-2 type
* | +--> 0x31 L6-2 (values)
* | |
* | +--> 0x04 L7-2-1 value
* | +--> ...
* | +--> 0x04 L7-2-n value
* |
* +--> ...
* |
* +--> 0x30 L4-m (attribute)
* |
* +--> 0x04 L5-m type
* +--> 0x31 L6-m (values)
* |
* +--> 0x04 L7-m-1 value
* +--> ...
* +--> 0x04 L7-m-n value
*/
private int computeAddRequestLength( org.apache.directory.shared.ldap.codec.message.AddRequestImpl addRequest )
{
Entry entry = addRequest.getEntry();
if ( entry == null )
{
throw new IllegalArgumentException( I18n.err( I18n.ERR_04481_ENTRY_NULL_VALUE ) );
}
// The entry DN
int addRequestLength = 1 + TLV.getNbBytes( DN.getNbBytes( entry.getDn() ) ) + DN.getNbBytes( entry.getDn() );
// The attributes sequence
int entryLength = 0;
if ( entry.size() != 0 )
{
List<Integer> attributesLength = new LinkedList<Integer>();
List<Integer> valuesLength = new LinkedList<Integer>();
// Compute the attributes length
for ( EntryAttribute attribute : entry )
{
int localAttributeLength = 0;
int localValuesLength = 0;
// Get the type length
int idLength = attribute.getId().getBytes().length;
localAttributeLength = 1 + TLV.getNbBytes( idLength ) + idLength;
// The values
if ( attribute.size() != 0 )
{
localValuesLength = 0;
for ( org.apache.directory.shared.ldap.entry.Value<?> value : attribute )
{
int valueLength = value.getBytes().length;
localValuesLength += 1 + TLV.getNbBytes( valueLength ) + valueLength;
}
localAttributeLength += 1 + TLV.getNbBytes( localValuesLength ) + localValuesLength;
}
// add the attribute length to the attributes length
entryLength += 1 + TLV.getNbBytes( localAttributeLength ) + localAttributeLength;
attributesLength.add( localAttributeLength );
valuesLength.add( localValuesLength );
}
addRequest.setAttributesLength( attributesLength );
addRequest.setValuesLength( valuesLength );
addRequest.setEntryLength( entryLength );
}
addRequestLength += 1 + TLV.getNbBytes( entryLength ) + entryLength;
addRequest.setAddRequestLength( addRequestLength );
// Return the result.
return 1 + TLV.getNbBytes( addRequestLength ) + addRequestLength;
}
/**
* Compute the AddResponse length
*
* AddResponse :
*
* 0x69 L1
* |
* +--> LdapResult
*
* L1 = Length(LdapResult)
*
* Length(AddResponse) = Length(0x69) + Length(L1) + L1
*/
private int computeAddResponseLength( org.apache.directory.shared.ldap.codec.message.AddResponseImpl addResponse )
{
int addResponseLength = computeLdapResultLength( addResponse.getLdapResult() );
addResponse.setAddResponseLength( addResponseLength );
return 1 + TLV.getNbBytes( addResponseLength ) + addResponseLength;
}
/**
* Compute the BindRequest length
*
* BindRequest :
* <pre>
* 0x60 L1
* |
* +--> 0x02 0x01 (1..127) version
* +--> 0x04 L2 name
* +--> authentication
*
* L2 = Length(name)
* L3/4 = Length(authentication)
* Length(BindRequest) = Length(0x60) + Length(L1) + L1 + Length(0x02) + 1 + 1 +
* Length(0x04) + Length(L2) + L2 + Length(authentication)
* </pre>
*/
private int computeBindRequestLength( org.apache.directory.shared.ldap.codec.message.BindRequestImpl bindRequest )
{
int bindRequestLength = 1 + 1 + 1; // Initialized with version
// The name
bindRequestLength += 1 + TLV.getNbBytes( DN.getNbBytes( bindRequest.getName() ) )
+ DN.getNbBytes( bindRequest.getName() );
byte[] credentials = bindRequest.getCredentials();
// The authentication
if ( bindRequest.isSimple() )
{
// Compute a SimpleBind operation
if ( credentials != null )
{
bindRequestLength += 1 + TLV.getNbBytes( credentials.length ) + credentials.length;
}
else
{
bindRequestLength += 1 + 1;
}
}
else
{
byte[] mechanismBytes = Strings.getBytesUtf8(bindRequest.getSaslMechanism());
int saslMechanismLength = 1 + TLV.getNbBytes( mechanismBytes.length ) + mechanismBytes.length;
int saslCredentialsLength = 0;
if ( credentials != null )
{
saslCredentialsLength = 1 + TLV.getNbBytes( credentials.length ) + credentials.length;
}
int saslLength = 1 + TLV.getNbBytes( saslMechanismLength + saslCredentialsLength ) + saslMechanismLength
+ saslCredentialsLength;
bindRequestLength += saslLength;
// Store the mechanism and credentials lengths
bindRequest.setSaslMechanismLength( saslMechanismLength );
bindRequest.setSaslCredentialsLength( saslCredentialsLength );
}
bindRequest.setBindRequestLength( bindRequestLength );
// Return the result.
return 1 + TLV.getNbBytes( bindRequestLength ) + bindRequestLength;
}
/**
* Compute the BindResponse length
*
* BindResponse :
* <pre>
* 0x61 L1
* |
* +--> LdapResult
* +--> [serverSaslCreds]
*
* L1 = Length(LdapResult) [ + Length(serverSaslCreds) ]
* Length(BindResponse) = Length(0x61) + Length(L1) + L1
* </pre>
*/
private int computeBindResponseLength( org.apache.directory.shared.ldap.codec.message.BindResponseImpl bindResponse )
{
int ldapResultLength = computeLdapResultLength( bindResponse.getLdapResult() );
int bindResponseLength = ldapResultLength;
byte[] serverSaslCreds = bindResponse.getServerSaslCreds();
if ( serverSaslCreds != null )
{
bindResponseLength += 1 + TLV.getNbBytes( serverSaslCreds.length ) + serverSaslCreds.length;
}
bindResponse.setBindResponseLength( bindResponseLength );
return 1 + TLV.getNbBytes( bindResponseLength ) + bindResponseLength;
}
/**
* Compute the CompareRequest length
*
* CompareRequest :
* 0x6E L1
* |
* +--> 0x04 L2 entry
* +--> 0x30 L3 (ava)
* |
* +--> 0x04 L4 attributeDesc
* +--> 0x04 L5 assertionValue
*
* L3 = Length(0x04) + Length(L4) + L4 + Length(0x04) +
* Length(L5) + L5
* Length(CompareRequest) = Length(0x6E) + Length(L1) + L1 +
* Length(0x04) + Length(L2) + L2 + Length(0x30) + Length(L3) + L3
*
* @return The CompareRequest PDU's length
*/
private int computeCompareRequestLength( org.apache.directory.shared.ldap.codec.message.CompareRequestImpl compareRequest )
{
// The entry DN
DN entry = compareRequest.getName();
int compareRequestLength = 1 + TLV.getNbBytes( DN.getNbBytes( entry ) ) + DN.getNbBytes( entry );
// The attribute value assertion
byte[] attributeIdBytes = Strings.getBytesUtf8(compareRequest.getAttributeId());
int avaLength = 1 + TLV.getNbBytes( attributeIdBytes.length ) + attributeIdBytes.length;
compareRequest.setAttrIdBytes( attributeIdBytes );
if ( compareRequest.getAssertionValue() instanceof BinaryValue )
{
byte[] value = compareRequest.getAssertionValue().getBytes();
avaLength += 1 + TLV.getNbBytes( value.length ) + value.length;
compareRequest.setAttrValBytes( value );
}
else
{
byte[] value = Strings.getBytesUtf8(compareRequest.getAssertionValue().getString());
avaLength += 1 + TLV.getNbBytes( value.length ) + value.length;
compareRequest.setAttrValBytes( value );
}
compareRequest.setAvaLength( avaLength );
compareRequestLength += 1 + TLV.getNbBytes( avaLength ) + avaLength;
compareRequest.setCompareRequestLength( compareRequestLength );
return 1 + TLV.getNbBytes( compareRequestLength ) + compareRequestLength;
}
/**
* Compute the CompareResponse length
*
* CompareResponse :
*
* 0x6F L1
* |
* +--> LdapResult
*
* L1 = Length(LdapResult)
*
* Length(CompareResponse) = Length(0x6F) + Length(L1) + L1
*/
private int computeCompareResponseLength( org.apache.directory.shared.ldap.codec.message.CompareResponseImpl compareResponse )
{
int compareResponseLength = computeLdapResultLength( compareResponse.getLdapResult() );
compareResponse.setCompareResponseLength( compareResponseLength );
return 1 + TLV.getNbBytes( compareResponseLength ) + compareResponseLength;
}
/**
* Compute the DelRequest length
*
* DelRequest :
* 0x4A L1 entry
*
* L1 = Length(entry)
* Length(DelRequest) = Length(0x4A) + Length(L1) + L1
*/
private int computeDeleteRequestLength( org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl deleteRequest )
{
// The entry
return 1 + TLV.getNbBytes( DN.getNbBytes( deleteRequest.getName() ) ) + DN.getNbBytes( deleteRequest.getName() );
}
/**
* Compute the DelResponse length
*
* DelResponse :
*
* 0x6B L1
* |
* +--> LdapResult
*
* L1 = Length(LdapResult)
*
* Length(DelResponse) = Length(0x6B) + Length(L1) + L1
*/
private int computeDeleteResponseLength( org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl deleteResponse )
{
int deleteResponseLength = computeLdapResultLength( deleteResponse.getLdapResult() );
deleteResponse.setDeleteResponseLength( deleteResponseLength );
return 1 + TLV.getNbBytes( deleteResponseLength ) + deleteResponseLength;
}
/**
* Compute the ExtendedRequest length
*
* ExtendedRequest :
*
* 0x77 L1
* |
* +--> 0x80 L2 name
* [+--> 0x81 L3 value]
*
* L1 = Length(0x80) + Length(L2) + L2
* [+ Length(0x81) + Length(L3) + L3]
*
* Length(ExtendedRequest) = Length(0x77) + Length(L1) + L1
*/
private int computeExtendedRequestLength( org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl extendedRequest )
{
byte[] requestNameBytes = Strings.getBytesUtf8(extendedRequest.getRequestName());
extendedRequest.setRequestNameBytes( requestNameBytes );
int extendedRequestLength = 1 + TLV.getNbBytes( requestNameBytes.length ) + requestNameBytes.length;
if ( extendedRequest.getRequestValue() != null )
{
extendedRequestLength += 1 + TLV.getNbBytes( extendedRequest.getRequestValue().length )
+ extendedRequest.getRequestValue().length;
}
extendedRequest.setExtendedRequestLength( extendedRequestLength );
return 1 + TLV.getNbBytes( extendedRequestLength ) + extendedRequestLength;
}
/**
* Compute the ExtendedResponse length
*
* ExtendedResponse :
*
* 0x78 L1
* |
* +--> LdapResult
* [+--> 0x8A L2 name
* [+--> 0x8B L3 response]]
*
* L1 = Length(LdapResult)
* [ + Length(0x8A) + Length(L2) + L2
* [ + Length(0x8B) + Length(L3) + L3]]
*
* Length(ExtendedResponse) = Length(0x78) + Length(L1) + L1
*
* @return The ExtendedResponse length
*/
private int computeExtendedResponseLength( org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl extendedResponse )
{
int ldapResultLength = computeLdapResultLength( extendedResponse.getLdapResult() );
int extendedResponseLength = ldapResultLength;
String id = extendedResponse.getResponseName();
if ( !Strings.isEmpty(id) )
{
byte[] idBytes = Strings.getBytesUtf8(id);
extendedResponse.setResponseNameBytes( idBytes );
int idLength = idBytes.length;
extendedResponseLength += 1 + TLV.getNbBytes( idLength ) + idLength;
}
byte[] encodedValue = extendedResponse.getResponseValue();
if ( encodedValue != null )
{
extendedResponseLength += 1 + TLV.getNbBytes( encodedValue.length ) + encodedValue.length;
}
extendedResponse.setExtendedResponseLength( extendedResponseLength );
return 1 + TLV.getNbBytes( extendedResponseLength ) + extendedResponseLength;
}
/**
* Compute the intermediateResponse length
*
* intermediateResponse :
*
* 0x79 L1
* |
* [+--> 0x80 L2 name
* [+--> 0x81 L3 response]]
*
* L1 = [ + Length(0x80) + Length(L2) + L2
* [ + Length(0x81) + Length(L3) + L3]]
*
* Length(IntermediateResponse) = Length(0x79) + Length(L1) + L1
*
* @return The IntermediateResponse length
*/
private int computeIntermediateResponseLength( org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl intermediateResponse )
{
int intermediateResponseLength = 0;
if ( !Strings.isEmpty(intermediateResponse.getResponseName()) )
{
byte[] responseNameBytes = Strings.getBytesUtf8(intermediateResponse.getResponseName());
int responseNameLength = responseNameBytes.length;
intermediateResponseLength += 1 + TLV.getNbBytes( responseNameLength ) + responseNameLength;
intermediateResponse.setResponseNameBytes( responseNameBytes );
}
byte[] encodedValue = intermediateResponse.getResponseValue();
if ( encodedValue != null )
{
intermediateResponseLength += 1 + TLV.getNbBytes( encodedValue.length ) + encodedValue.length;
}
intermediateResponse.setIntermediateResponseLength( intermediateResponseLength );
return 1 + TLV.getNbBytes( intermediateResponseLength ) + intermediateResponseLength;
}
/**
* Compute the ModifyRequest length
*
* ModifyRequest :
*
* 0x66 L1
* |
* +--> 0x04 L2 object
* +--> 0x30 L3 modifications
* |
* +--> 0x30 L4-1 modification sequence
* | |
* | +--> 0x0A 0x01 (0..2) operation
* | +--> 0x30 L5-1 modification
* | |
* | +--> 0x04 L6-1 type
* | +--> 0x31 L7-1 vals
* | |
* | +--> 0x04 L8-1-1 attributeValue
* | +--> 0x04 L8-1-2 attributeValue
* | +--> ...
* | +--> 0x04 L8-1-i attributeValue
* | +--> ...
* | +--> 0x04 L8-1-n attributeValue
* |
* +--> 0x30 L4-2 modification sequence
* . |
* . +--> 0x0A 0x01 (0..2) operation
* . +--> 0x30 L5-2 modification
* |
* +--> 0x04 L6-2 type
* +--> 0x31 L7-2 vals
* |
* +--> 0x04 L8-2-1 attributeValue
* +--> 0x04 L8-2-2 attributeValue
* +--> ...
* +--> 0x04 L8-2-i attributeValue
* +--> ...
* +--> 0x04 L8-2-n attributeValue
*/
private int computeModifyRequestLength( ModifyRequestImpl modifyRequest )
{
// Initialized with name
int modifyRequestLength = 1 + TLV.getNbBytes( DN.getNbBytes( modifyRequest.getName() ) )
+ DN.getNbBytes( modifyRequest.getName() );
// All the changes length
int changesLength = 0;
Collection<Modification> modifications = modifyRequest.getModifications();
if ( ( modifications != null ) && ( modifications.size() != 0 ) )
{
List<Integer> changeLength = new LinkedList<Integer>();
List<Integer> modificationLength = new LinkedList<Integer>();
List<Integer> valuesLength = new LinkedList<Integer>();
for ( Modification modification : modifications )
{
// Modification sequence length initialized with the operation
int localModificationSequenceLength = 1 + 1 + 1;
int localValuesLength = 0;
// Modification length initialized with the type
int typeLength = modification.getAttribute().getId().length();
int localModificationLength = 1 + TLV.getNbBytes( typeLength ) + typeLength;
// Get all the values
if ( modification.getAttribute().size() != 0 )
{
for ( org.apache.directory.shared.ldap.entry.Value<?> value : modification.getAttribute() )
{
localValuesLength += 1 + TLV.getNbBytes( value.getBytes().length ) + value.getBytes().length;
}
}
localModificationLength += 1 + TLV.getNbBytes( localValuesLength ) + localValuesLength;
// Compute the modificationSequenceLength
localModificationSequenceLength += 1 + TLV.getNbBytes( localModificationLength )
+ localModificationLength;
// Add the tag and the length
changesLength += 1 + TLV.getNbBytes( localModificationSequenceLength )
+ localModificationSequenceLength;
// Store the arrays of values
valuesLength.add( localValuesLength );
modificationLength.add( localModificationLength );
changeLength.add( localModificationSequenceLength );
}
// Add the modifications length to the modificationRequestLength
modifyRequestLength += 1 + TLV.getNbBytes( changesLength ) + changesLength;
modifyRequest.setChangeLength( changeLength );
modifyRequest.setModificationLength( modificationLength );
modifyRequest.setValuesLength( valuesLength );
}
modifyRequest.setChangesLength( changesLength );
modifyRequest.setModifyRequestLength( modifyRequestLength );
return 1 + TLV.getNbBytes( modifyRequestLength ) + modifyRequestLength;
}
/**
* Compute the ModifyResponse length
*
* ModifyResponse :
* <pre>
* 0x67 L1
* |
* +--> LdapResult
*
* L1 = Length(LdapResult)
* Length(ModifyResponse) = Length(0x67) + Length(L1) + L1
* </pre>
*/
private int computeModifyResponseLength( ModifyResponseImpl modifyResponse )
{
int modifyResponseLength = computeLdapResultLength( modifyResponse.getLdapResult() );
modifyResponse.setModifyResponseLength( modifyResponseLength );
return 1 + TLV.getNbBytes( modifyResponseLength ) + modifyResponseLength;
}
/**
* Compute the ModifyDNRequest length
*
* ModifyDNRequest :
* <pre>
* 0x6C L1
* |
* +--> 0x04 L2 entry
* +--> 0x04 L3 newRDN
* +--> 0x01 0x01 (true/false) deleteOldRDN (3 bytes)
* [+--> 0x80 L4 newSuperior ]
*
* L2 = Length(0x04) + Length(Length(entry)) + Length(entry)
* L3 = Length(0x04) + Length(Length(newRDN)) + Length(newRDN)
* L4 = Length(0x80) + Length(Length(newSuperior)) + Length(newSuperior)
* L1 = L2 + L3 + 3 [+ L4]
*
* Length(ModifyDNRequest) = Length(0x6C) + Length(L1) + L1
* </pre>
*
* @return The PDU's length of a ModifyDN Request
*/
private int computeModifyDnRequestLength( ModifyDnRequestImpl modifyDnResponse )
{
int newRdnlength = Strings.getBytesUtf8(modifyDnResponse.getNewRdn().getName()).length;
int modifyDNRequestLength = 1 + TLV.getNbBytes( DN.getNbBytes( modifyDnResponse.getName() ) )
+ DN.getNbBytes( modifyDnResponse.getName() ) + 1 + TLV.getNbBytes( newRdnlength ) + newRdnlength + 1 + 1
+ 1; // deleteOldRDN
if ( modifyDnResponse.getNewSuperior() != null )
{
modifyDNRequestLength += 1 + TLV.getNbBytes( DN.getNbBytes( modifyDnResponse.getNewSuperior() ) )
+ DN.getNbBytes( modifyDnResponse.getNewSuperior() );
}
modifyDnResponse.setModifyDnRequestLength( modifyDNRequestLength );
return 1 + TLV.getNbBytes( modifyDNRequestLength ) + modifyDNRequestLength;
}
/**
* Compute the ModifyDNResponse length
*
* ModifyDNResponse :
* <pre>
* 0x6D L1
* |
* +--> LdapResult
*
* L1 = Length(LdapResult)
* Length(ModifyDNResponse) = Length(0x6D) + Length(L1) + L1
* </pre>
*/
private int computeModifyDnResponseLength( ModifyDnResponseImpl modifyDnResponse )
{
int modifyDnResponseLength = computeLdapResultLength( modifyDnResponse.getLdapResult() );
modifyDnResponse.setModifyDnResponseLength( modifyDnResponseLength );
return 1 + TLV.getNbBytes( modifyDnResponseLength ) + modifyDnResponseLength;
}
private int computeReferralLength( Referral referral )
{
if ( referral != null )
{
Collection<String> ldapUrls = referral.getLdapUrls();
if ( ( ldapUrls != null ) && ( ldapUrls.size() != 0 ) )
{
int referralLength = 0;
// Each referral
for ( String ldapUrl : ldapUrls )
{
byte[] ldapUrlBytes = Strings.getBytesUtf8(ldapUrl);
referralLength += 1 + TLV.getNbBytes( ldapUrlBytes.length ) + ldapUrlBytes.length;
referral.addLdapUrlBytes( ldapUrlBytes );
}
referral.setReferralLength( referralLength );
return referralLength;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
/**
* Compute the SearchRequest length
*
* SearchRequest :
* <pre>
* 0x63 L1
* |
* +--> 0x04 L2 baseObject
* +--> 0x0A 0x01 scope
* +--> 0x0A 0x01 derefAliases
* +--> 0x02 0x0(1..4) sizeLimit
* +--> 0x02 0x0(1..4) timeLimit
* +--> 0x01 0x01 typesOnly
* +--> filter.computeLength()
* +--> 0x30 L3 (Attribute description list)
* |
* +--> 0x04 L4-1 Attribute description
* +--> 0x04 L4-2 Attribute description
* +--> ...
* +--> 0x04 L4-i Attribute description
* +--> ...
* +--> 0x04 L4-n Attribute description
* </pre>
*/
private int computeSearchRequestLength( SearchRequestImpl searchRequest )
{
int searchRequestLength = 0;
// The baseObject
searchRequestLength += 1 + TLV.getNbBytes( DN.getNbBytes( searchRequest.getBase() ) )
+ DN.getNbBytes( searchRequest.getBase() );
// The scope
searchRequestLength += 1 + 1 + 1;
// The derefAliases
searchRequestLength += 1 + 1 + 1;
// The sizeLimit
searchRequestLength += 1 + 1 + Value.getNbBytes( searchRequest.getSizeLimit() );
// The timeLimit
searchRequestLength += 1 + 1 + Value.getNbBytes( searchRequest.getTimeLimit() );
// The typesOnly
searchRequestLength += 1 + 1 + 1;
// The filter
searchRequestLength += searchRequest.getCurrentFilter().computeLength();
// The attributes description list
int attributeDescriptionListLength = 0;
if ( ( searchRequest.getAttributes() != null ) && ( searchRequest.getAttributes().size() != 0 ) )
{
// Compute the attributes length
for ( String attribute : searchRequest.getAttributes() )
{
// add the attribute length to the attributes length
int idLength = Strings.getBytesUtf8(attribute).length;
attributeDescriptionListLength += 1 + TLV.getNbBytes( idLength ) + idLength;
}
}
searchRequest.setAttributeDescriptionListLength( attributeDescriptionListLength );
searchRequestLength += 1 + TLV.getNbBytes( attributeDescriptionListLength ) + attributeDescriptionListLength;
searchRequest.setSearchRequestLength( searchRequestLength );
// Return the result.
return 1 + TLV.getNbBytes( searchRequestLength ) + searchRequestLength;
}
/**
* Compute the SearchResultDone length
*
* SearchResultDone :
* <pre>
* 0x65 L1
* |
* +--> LdapResult
*
* L1 = Length(LdapResult)
* Length(SearchResultDone) = Length(0x65) + Length(L1) + L1
* </pre>
*/
private int computeSearchResultDoneLength( SearchResultDoneImpl searchResultDone )
{
int searchResultDoneLength = computeLdapResultLength( searchResultDone.getLdapResult() );
searchResultDone.setSearchResultDoneLength( searchResultDoneLength );
return 1 + TLV.getNbBytes( searchResultDoneLength ) + searchResultDoneLength;
}
/**
* Compute the SearchResultEntry length
*
* SearchResultEntry :
* <pre>
* 0x64 L1
* |
* +--> 0x04 L2 objectName
* +--> 0x30 L3 (attributes)
* |
* +--> 0x30 L4-1 (partial attributes list)
* | |
* | +--> 0x04 L5-1 type
* | +--> 0x31 L6-1 (values)
* | |
* | +--> 0x04 L7-1-1 value
* | +--> ...
* | +--> 0x04 L7-1-n value
* |
* +--> 0x30 L4-2 (partial attributes list)
* | |
* | +--> 0x04 L5-2 type
* | +--> 0x31 L6-2 (values)
* | |
* | +--> 0x04 L7-2-1 value
* | +--> ...
* | +--> 0x04 L7-2-n value
* |
* +--> ...
* |
* +--> 0x30 L4-m (partial attributes list)
* |
* +--> 0x04 L5-m type
* +--> 0x31 L6-m (values)
* |
* +--> 0x04 L7-m-1 value
* +--> ...
* +--> 0x04 L7-m-n value
* </pre>
*/
private int computeSearchResultEntryLength( SearchResultEntryImpl searchResultEntry )
{
DN dn = searchResultEntry.getObjectName();
byte[] dnBytes = Strings.getBytesUtf8(dn.getName());
// The entry
int searchResultEntryLength = 1 + TLV.getNbBytes( dnBytes.length ) + dnBytes.length;
searchResultEntry.setObjectNameBytes( dnBytes );
// The attributes sequence
int attributesLength = 0;
Entry entry = searchResultEntry.getEntry();
if ( ( entry != null ) && ( entry.size() != 0 ) )
{
List<Integer> attributeLength = new LinkedList<Integer>();
List<Integer> valsLength = new LinkedList<Integer>();
// Store those lists in the object
searchResultEntry.setAttributeLength( attributeLength );
searchResultEntry.setValsLength( valsLength );
// Compute the attributes length
for ( EntryAttribute attribute : entry )
{
int localAttributeLength = 0;
int localValuesLength = 0;
// Get the type length
int idLength = attribute.getId().getBytes().length;
localAttributeLength = 1 + TLV.getNbBytes( idLength ) + idLength;
if ( attribute.size() != 0 )
{
// The values
if ( attribute.size() > 0 )
{
localValuesLength = 0;
for ( org.apache.directory.shared.ldap.entry.Value<?> value : attribute )
{
byte[] binaryValue = value.getBytes();
localValuesLength += 1 + TLV.getNbBytes( binaryValue.length ) + binaryValue.length;
}
localAttributeLength += 1 + TLV.getNbBytes( localValuesLength ) + localValuesLength;
}
else
{
// We have to deal with the special wase where
// we don't have a value.
// It will be encoded as an empty OCTETSTRING,
// so it will be two byte slong (0x04 0x00)
localAttributeLength += 1 + 1;
}
}
else
{
// We have no values. We will just have an empty SET OF :
// 0x31 0x00
localAttributeLength += 1 + 1;
}
// add the attribute length to the attributes length
attributesLength += 1 + TLV.getNbBytes( localAttributeLength ) + localAttributeLength;
// Store the lengths of the encoded attributes and values
attributeLength.add( localAttributeLength );
valsLength.add( localValuesLength );
}
// Store the lengths of the entry
searchResultEntry.setAttributesLength( attributesLength );
}
searchResultEntryLength += 1 + TLV.getNbBytes( attributesLength ) + attributesLength;
// Store the length of the response
searchResultEntry.setSearchResultEntryLength( searchResultEntryLength );
// Return the result.
return 1 + TLV.getNbBytes( searchResultEntryLength ) + searchResultEntryLength;
}
/**
* Compute the SearchResultReference length
*
* SearchResultReference :
* <pre>
* 0x73 L1
* |
* +--> 0x04 L2 reference
* +--> 0x04 L3 reference
* +--> ...
* +--> 0x04 Li reference
* +--> ...
* +--> 0x04 Ln reference
*
* L1 = n*Length(0x04) + sum(Length(Li)) + sum(Length(reference[i]))
*
* Length(SearchResultReference) = Length(0x73 + Length(L1) + L1
* </pre>
*/
private int computeSearchResultReferenceLength( SearchResultReferenceImpl searchResultReference )
{
int searchResultReferenceLength = 0;
// We may have more than one reference.
Referral referral = searchResultReference.getReferral();
int referralLength = computeReferralLength( referral );
if ( referralLength != 0 )
{
searchResultReference.setReferral( referral );
searchResultReferenceLength = referralLength;
}
// Store the length of the response
searchResultReference.setSearchResultReferenceLength( searchResultReferenceLength );
return 1 + TLV.getNbBytes( searchResultReferenceLength ) + searchResultReferenceLength;
}
/**
* Compute the UnBindRequest length
*
* UnBindRequest :
* 0x42 00
*/
private int computeUnbindRequestLength( )
{
return 2; // Always 2
}
/**
* Encode the Abandon protocolOp part
*/
private void encodeAbandonRequest( ByteBuffer buffer, AbandonRequestImpl abandonRequest ) throws EncoderException
{
try
{
// The tag
buffer.put( LdapConstants.ABANDON_REQUEST_TAG );
// The length. It has to be evaluated depending on
// the abandoned messageId value.
buffer.put( ( byte ) Value.getNbBytes( abandonRequest.getAbandoned() ) );
// The abandoned messageId
buffer.put( Value.getBytes( abandonRequest.getAbandoned() ) );
}
catch ( BufferOverflowException boe )
{
String msg = I18n.err( I18n.ERR_04005 );
throw new EncoderException( msg );
}
}
/**
* Encode the AddRequest message to a PDU.
*
* AddRequest :
*
* 0x68 LL
* 0x04 LL entry
* 0x30 LL attributesList
* 0x30 LL attributeList
* 0x04 LL attributeDescription
* 0x31 LL attributeValues
* 0x04 LL attributeValue
* ...
* 0x04 LL attributeValue
* ...
* 0x30 LL attributeList
* 0x04 LL attributeDescription
* 0x31 LL attributeValue
* 0x04 LL attributeValue
* ...
* 0x04 LL attributeValue
*
* @param buffer The buffer where to put the PDU
*/
private void encodeAddRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.AddRequestImpl addRequest ) throws EncoderException
{
try
{
// The AddRequest Tag
buffer.put( LdapConstants.ADD_REQUEST_TAG );
buffer.put( TLV.getBytes( addRequest.getAddRequestLength() ) );
// The entry
Value.encode( buffer, DN.getBytes( addRequest.getEntryDn() ) );
// The attributes sequence
buffer.put( UniversalTag.SEQUENCE.getValue() );
buffer.put( TLV.getBytes( addRequest.getEntryLength() ) );
// The partial attribute list
Entry entry = addRequest.getEntry();
if ( entry.size() != 0 )
{
int attributeNumber = 0;
// Compute the attributes length
for ( EntryAttribute attribute : entry )
{
// The attributes list sequence
buffer.put( UniversalTag.SEQUENCE.getValue() );
int localAttributeLength = addRequest.getAttributesLength().get( attributeNumber );
buffer.put( TLV.getBytes( localAttributeLength ) );
// The attribute type
Value.encode( buffer, attribute.getId() );
// The values
buffer.put( UniversalTag.SET.getValue() );
int localValuesLength = addRequest.getValuesLength().get( attributeNumber );
buffer.put( TLV.getBytes( localValuesLength ) );
if ( attribute.size() != 0 )
{
for ( org.apache.directory.shared.ldap.entry.Value<?> value : attribute )
{
if ( value.isBinary() )
{
Value.encode( buffer, value.getBytes() );
}
else
{
Value.encode(buffer, value.getString());
}
}
}
// Go to the next attribute number;
attributeNumber++;
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( "The PDU buffer size is too small !" );
}
}
/**
* Encode the AddResponse message to a PDU.
*
* @param buffer The buffer where to put the PDU
*/
private void encodeAddResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.AddResponseImpl addResponse ) throws EncoderException
{
try
{
// The AddResponse Tag
buffer.put( LdapConstants.ADD_RESPONSE_TAG );
buffer.put( TLV.getBytes( addResponse.getAddResponseLength() ) );
// The LdapResult
encodeLdapResult( buffer, addResponse.getLdapResult() );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the BindRequest message to a PDU.
*
* BindRequest :
* <pre>
* 0x60 LL
* 0x02 LL version 0x80 LL simple
* 0x04 LL name /
* authentication.encode()
* \ 0x83 LL mechanism [0x04 LL credential]
* </pre>
*
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeBindRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.BindRequestImpl bindRequest ) throws EncoderException
{
try
{
// The BindRequest Tag
buffer.put( LdapConstants.BIND_REQUEST_TAG );
buffer.put( TLV.getBytes( bindRequest.getBindRequestLength() ) );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
// The version (LDAP V3 only)
Value.encode( buffer, 3 );
// The name
Value.encode( buffer, DN.getBytes( bindRequest.getName() ) );
byte[] credentials = bindRequest.getCredentials();
// The authentication
if ( bindRequest.isSimple() )
{
// Simple authentication
try
{
// The simpleAuthentication Tag
buffer.put( ( byte ) LdapConstants.BIND_REQUEST_SIMPLE_TAG );
if ( credentials != null )
{
buffer.put( TLV.getBytes( credentials.length ) );
if ( credentials.length != 0 )
{
buffer.put( credentials );
}
}
else
{
buffer.put( ( byte ) 0 );
}
}
catch ( BufferOverflowException boe )
{
String msg = I18n.err( I18n.ERR_04005 );
throw new EncoderException( msg );
}
}
else
{
// SASL Bind
try
{
// The saslAuthentication Tag
buffer.put( ( byte ) LdapConstants.BIND_REQUEST_SASL_TAG );
byte[] mechanismBytes = Strings.getBytesUtf8(bindRequest.getSaslMechanism());
buffer.put( TLV
.getBytes( bindRequest.getSaslMechanismLength() + bindRequest.getSaslCredentialsLength() ) );
Value.encode( buffer, mechanismBytes );
if ( credentials != null )
{
Value.encode( buffer, credentials );
}
}
catch ( BufferOverflowException boe )
{
String msg = I18n.err( I18n.ERR_04005 );
throw new EncoderException( msg );
}
}
}
/**
* Encode the BindResponse message to a PDU.
*
* BindResponse :
* <pre>
* LdapResult.encode
* [0x87 LL serverSaslCreds]
* </pre>
*
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeBindResponse( ByteBuffer bb, org.apache.directory.shared.ldap.codec.message.BindResponseImpl bindResponse ) throws EncoderException
{
try
{
// The BindResponse Tag
bb.put( LdapConstants.BIND_RESPONSE_TAG );
bb.put( TLV.getBytes( bindResponse.getBindResponseLength() ) );
// The LdapResult
encodeLdapResult( bb, bindResponse.getLdapResult() );
// The serverSaslCredential, if any
byte[] serverSaslCreds = bindResponse.getServerSaslCreds();
if ( serverSaslCreds != null )
{
bb.put( ( byte ) LdapConstants.SERVER_SASL_CREDENTIAL_TAG );
bb.put( TLV.getBytes( serverSaslCreds.length ) );
if ( serverSaslCreds.length != 0 )
{
bb.put( serverSaslCreds );
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the CompareRequest message to a PDU.
*
* CompareRequest :
* 0x6E LL
* 0x04 LL entry
* 0x30 LL attributeValueAssertion
* 0x04 LL attributeDesc
* 0x04 LL assertionValue
*
* @param buffer The buffer where to put the PDU
*/
private void encodeCompareRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.CompareRequestImpl compareRequest ) throws EncoderException
{
try
{
// The CompareRequest Tag
buffer.put( LdapConstants.COMPARE_REQUEST_TAG );
buffer.put( TLV.getBytes( compareRequest.getCompareRequestLength() ) );
// The entry
Value.encode( buffer, DN.getBytes( compareRequest.getName() ) );
// The attributeValueAssertion sequence Tag
buffer.put( UniversalTag.SEQUENCE.getValue() );
buffer.put( TLV.getBytes( compareRequest.getAvaLength() ) );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
// The attributeDesc
Value.encode( buffer, compareRequest.getAttrIdBytes() );
// The assertionValue
Value.encode( buffer, ( byte[] ) compareRequest.getAttrValBytes() );
}
/**
* Encode the CompareResponse message to a PDU.
*
* @param buffer The buffer where to put the PDU
*/
private void encodeCompareResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.CompareResponseImpl compareResponse )
throws EncoderException
{
try
{
// The CompareResponse Tag
buffer.put( LdapConstants.COMPARE_RESPONSE_TAG );
buffer.put( TLV.getBytes( compareResponse.getCompareResponseLength() ) );
// The LdapResult
encodeLdapResult( buffer, compareResponse.getLdapResult() );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the DelRequest message to a PDU.
*
* DelRequest :
* 0x4A LL entry
*
* @param buffer The buffer where to put the PDU
*/
private void encodeDeleteRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl deleteRequest ) throws EncoderException
{
try
{
// The DelRequest Tag
buffer.put( LdapConstants.DEL_REQUEST_TAG );
// The entry
buffer.put( TLV.getBytes( DN.getNbBytes( deleteRequest.getName() ) ) );
buffer.put( DN.getBytes( deleteRequest.getName() ) );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the DelResponse message to a PDU.
*
* @param buffer The buffer where to put the PDU
*/
private void encodeDeleteResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl deleteResponse ) throws EncoderException
{
try
{
// The DelResponse Tag
buffer.put( LdapConstants.DEL_RESPONSE_TAG );
buffer.put( TLV.getBytes( deleteResponse.getDeleteResponseLength() ) );
// The LdapResult
encodeLdapResult( buffer, deleteResponse.getLdapResult() );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the ExtendedRequest message to a PDU.
*
* ExtendedRequest :
*
* 0x80 LL resquest name
* [0x81 LL request value]
*
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeExtendedRequest( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl extendedRequest )
throws EncoderException
{
try
{
// The BindResponse Tag
buffer.put( LdapConstants.EXTENDED_REQUEST_TAG );
buffer.put( TLV.getBytes( extendedRequest.getExtendedRequestLength() ) );
// The requestName, if any
if ( extendedRequest.getRequestNameBytes() == null )
{
throw new EncoderException( I18n.err( I18n.ERR_04043 ) );
}
buffer.put( ( byte ) LdapConstants.EXTENDED_REQUEST_NAME_TAG );
buffer.put( TLV.getBytes( extendedRequest.getRequestNameBytes().length ) );
if ( extendedRequest.getRequestNameBytes().length != 0 )
{
buffer.put( extendedRequest.getRequestNameBytes() );
}
// The requestValue, if any
if ( extendedRequest.getRequestValue() != null )
{
buffer.put( ( byte ) LdapConstants.EXTENDED_REQUEST_VALUE_TAG );
buffer.put( TLV.getBytes( extendedRequest.getRequestValue().length ) );
if ( extendedRequest.getRequestValue().length != 0 )
{
buffer.put( extendedRequest.getRequestValue() );
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the ExtendedResponse message to a PDU.
* ExtendedResponse :
* LdapResult.encode()
* [0x8A LL response name]
* [0x8B LL response]
*
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeExtendedResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl extendedResponse )
throws EncoderException
{
try
{
// The ExtendedResponse Tag
buffer.put( LdapConstants.EXTENDED_RESPONSE_TAG );
buffer.put( TLV.getBytes( extendedResponse.getExtendedResponseLength() ) );
// The LdapResult
encodeLdapResult( buffer, extendedResponse.getLdapResult() );
// The ID, if any
byte[] idBytes = extendedResponse.getResponseNameBytes();
if ( idBytes != null )
{
buffer.put( ( byte ) LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG );
buffer.put( TLV.getBytes( idBytes.length ) );
if ( idBytes.length != 0 )
{
buffer.put( idBytes );
}
}
// The encodedValue, if any
byte[] encodedValue = extendedResponse.getResponseValue();
if ( encodedValue != null )
{
buffer.put( ( byte ) LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG );
buffer.put( TLV.getBytes( encodedValue.length ) );
if ( encodedValue.length != 0 )
{
buffer.put( encodedValue );
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the IntermediateResponse message to a PDU.
* IntermediateResponse :
* 0x79 LL
* [0x80 LL response name]
* [0x81 LL responseValue]
*
* @param buffer The buffer where to put the PDU
*/
private void encodeIntermediateResponse( ByteBuffer buffer, org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl intermediateResponse )
throws EncoderException
{
try
{
// The ExtendedResponse Tag
buffer.put( LdapConstants.INTERMEDIATE_RESPONSE_TAG );
buffer.put( TLV.getBytes( intermediateResponse.getIntermediateResponseLength() ) );
// The responseName, if any
byte[] responseNameBytes = intermediateResponse.getResponseNameBytes();
if ( ( responseNameBytes != null ) && ( responseNameBytes.length != 0 ) )
{
buffer.put( ( byte ) LdapConstants.INTERMEDIATE_RESPONSE_NAME_TAG );
buffer.put( TLV.getBytes( responseNameBytes.length ) );
buffer.put( responseNameBytes );
}
// The encodedValue, if any
byte[] encodedValue = intermediateResponse.getResponseValue();
if ( encodedValue != null )
{
buffer.put( ( byte ) LdapConstants.INTERMEDIATE_RESPONSE_VALUE_TAG );
buffer.put( TLV.getBytes( encodedValue.length ) );
if ( encodedValue.length != 0 )
{
buffer.put( encodedValue );
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the ModifyRequest message to a PDU.
*
* ModifyRequest :
* <pre>
* 0x66 LL
* 0x04 LL object
* 0x30 LL modifiations
* 0x30 LL modification sequence
* 0x0A 0x01 operation
* 0x30 LL modification
* 0x04 LL type
* 0x31 LL vals
* 0x04 LL attributeValue
* ...
* 0x04 LL attributeValue
* ...
* 0x30 LL modification sequence
* 0x0A 0x01 operation
* 0x30 LL modification
* 0x04 LL type
* 0x31 LL vals
* 0x04 LL attributeValue
* ...
* 0x04 LL attributeValue
* </pre>
*
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeModifyRequest( ByteBuffer buffer, ModifyRequestImpl modifyRequest ) throws EncoderException
{
try
{
// The AddRequest Tag
buffer.put( LdapConstants.MODIFY_REQUEST_TAG );
buffer.put( TLV.getBytes( modifyRequest.getModifyRequestLength() ) );
// The entry
Value.encode( buffer, DN.getBytes( modifyRequest.getName() ) );
// The modifications sequence
buffer.put( UniversalTag.SEQUENCE.getValue() );
buffer.put( TLV.getBytes( modifyRequest.getChangesLength() ) );
// The modifications list
Collection<Modification> modifications = modifyRequest.getModifications();
if ( ( modifications != null ) && ( modifications.size() != 0 ) )
{
int modificationNumber = 0;
// Compute the modifications length
for ( Modification modification : modifications )
{
// The modification sequence
buffer.put( UniversalTag.SEQUENCE.getValue() );
int localModificationSequenceLength = modifyRequest.getChangeLength().get( modificationNumber );
buffer.put( TLV.getBytes( localModificationSequenceLength ) );
// The operation. The value has to be changed, it's not
// the same value in DirContext and in RFC 2251.
buffer.put( UniversalTag.ENUMERATED.getValue() );
buffer.put( ( byte ) 1 );
buffer.put( ( byte ) modification.getOperation().getValue() );
// The modification
buffer.put( UniversalTag.SEQUENCE.getValue() );
int localModificationLength = modifyRequest.getModificationLength().get( modificationNumber );
buffer.put( TLV.getBytes( localModificationLength ) );
// The modification type
Value.encode( buffer, modification.getAttribute().getId() );
// The values
buffer.put( UniversalTag.SET.getValue() );
int localValuesLength = modifyRequest.getValuesLength().get( modificationNumber );
buffer.put( TLV.getBytes( localValuesLength ) );
if ( modification.getAttribute().size() != 0 )
{
for ( org.apache.directory.shared.ldap.entry.Value<?> value : modification.getAttribute() )
{
if ( !value.isBinary() )
{
Value.encode( buffer, value.getString() );
}
else
{
Value.encode( buffer, value.getBytes() );
}
}
}
// Go to the next modification number;
modificationNumber++;
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the ModifyResponse message to a PDU.
*
* @param buffer The buffer where to put the PDU
*/
private void encodeModifyResponse( ByteBuffer buffer, ModifyResponseImpl modifyResponse ) throws EncoderException
{
try
{
// The ModifyResponse Tag
buffer.put( LdapConstants.MODIFY_RESPONSE_TAG );
buffer.put( TLV.getBytes( modifyResponse.getModifyResponseLength() ) );
// The LdapResult
encodeLdapResult( buffer, modifyResponse.getLdapResult() );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the ModifyDNRequest message to a PDU.
*
* ModifyDNRequest :
* <pre>
* 0x6C LL
* 0x04 LL entry
* 0x04 LL newRDN
* 0x01 0x01 deleteOldRDN
* [0x80 LL newSuperior]
* </pre>
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeModifyDnRequest( ByteBuffer buffer, ModifyDnRequestImpl modifyDnRequest )
throws EncoderException
{
try
{
// The ModifyDNRequest Tag
buffer.put( LdapConstants.MODIFY_DN_REQUEST_TAG );
buffer.put( TLV.getBytes( modifyDnRequest.getModifyDnResponseLength() ) );
// The entry
Value.encode( buffer, DN.getBytes( modifyDnRequest.getName() ) );
// The newRDN
Value.encode( buffer, modifyDnRequest.getNewRdn().getName() );
// The flag deleteOldRdn
Value.encode( buffer, modifyDnRequest.getDeleteOldRdn() );
// The new superior, if any
if ( modifyDnRequest.getNewSuperior() != null )
{
// Encode the reference
buffer.put( ( byte ) LdapConstants.MODIFY_DN_REQUEST_NEW_SUPERIOR_TAG );
int newSuperiorLength = DN.getNbBytes( modifyDnRequest.getNewSuperior() );
buffer.put( TLV.getBytes( newSuperiorLength ) );
if ( newSuperiorLength != 0 )
{
buffer.put( DN.getBytes( modifyDnRequest.getNewSuperior() ) );
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the ModifyDnResponse message to a PDU.
*
* @param buffer The buffer where to put the PDU
*/
private void encodeModifyDnResponse( ByteBuffer buffer, ModifyDnResponseImpl modifyDnResponse )
throws EncoderException
{
try
{
// The ModifyResponse Tag
buffer.put( LdapConstants.MODIFY_DN_RESPONSE_TAG );
buffer.put( TLV.getBytes( modifyDnResponse.getModifyDnResponseLength() ) );
// The LdapResult
encodeLdapResult( buffer, modifyDnResponse.getLdapResult() );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the SearchRequest message to a PDU.
*
* SearchRequest :
* <pre>
* 0x63 LL
* 0x04 LL baseObject
* 0x0A 01 scope
* 0x0A 01 derefAliases
* 0x02 0N sizeLimit
* 0x02 0N timeLimit
* 0x01 0x01 typesOnly
* filter.encode()
* 0x30 LL attributeDescriptionList
* 0x04 LL attributeDescription
* ...
* 0x04 LL attributeDescription
* </pre>
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeSearchRequest( ByteBuffer buffer, SearchRequestImpl searchRequest ) throws EncoderException
{
try
{
// The SearchRequest Tag
buffer.put( LdapConstants.SEARCH_REQUEST_TAG );
buffer.put( TLV.getBytes( searchRequest.getSearchRequestLength() ) );
// The baseObject
Value.encode( buffer, DN.getBytes( searchRequest.getBase() ) );
// The scope
Value.encodeEnumerated( buffer, searchRequest.getScope().getScope() );
// The derefAliases
Value.encodeEnumerated( buffer, searchRequest.getDerefAliases().getValue() );
// The sizeLimit
Value.encode( buffer, searchRequest.getSizeLimit() );
// The timeLimit
Value.encode( buffer, searchRequest.getTimeLimit() );
// The typesOnly
Value.encode( buffer, searchRequest.getTypesOnly() );
// The filter
searchRequest.getCurrentFilter().encode( buffer );
// The attributeDescriptionList
buffer.put( UniversalTag.SEQUENCE.getValue() );
buffer.put( TLV.getBytes( searchRequest.getAttributeDescriptionListLength() ) );
if ( ( searchRequest.getAttributes() != null ) && ( searchRequest.getAttributes().size() != 0 ) )
{
// encode each attribute
for ( String attribute : searchRequest.getAttributes() )
{
Value.encode( buffer, attribute );
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the SearchResultDone message to a PDU.
*
* @param buffer The buffer where to put the PDU
*/
private void encodeSearchResultDone( ByteBuffer buffer, SearchResultDoneImpl searchResultDone )
throws EncoderException
{
try
{
// The searchResultDone Tag
buffer.put( LdapConstants.SEARCH_RESULT_DONE_TAG );
buffer.put( TLV.getBytes( searchResultDone.getSearchResultDoneLength() ) );
// The LdapResult
encodeLdapResult( buffer, searchResultDone.getLdapResult() );
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the SearchResultEntry message to a PDU.
*
* SearchResultEntry :
* <pre>
* 0x64 LL
* 0x04 LL objectName
* 0x30 LL attributes
* 0x30 LL partialAttributeList
* 0x04 LL type
* 0x31 LL vals
* 0x04 LL attributeValue
* ...
* 0x04 LL attributeValue
* ...
* 0x30 LL partialAttributeList
* 0x04 LL type
* 0x31 LL vals
* 0x04 LL attributeValue
* ...
* 0x04 LL attributeValue
* </pre>
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeSearchResultEntry( ByteBuffer buffer, SearchResultEntryImpl searchResultEntry )
throws EncoderException
{
try
{
// The SearchResultEntry Tag
buffer.put( LdapConstants.SEARCH_RESULT_ENTRY_TAG );
buffer.put( TLV.getBytes( searchResultEntry.getSearchResultEntryLength() ) );
// The objectName
Value.encode( buffer, searchResultEntry.getObjectNameBytes() );
// The attributes sequence
buffer.put( UniversalTag.SEQUENCE.getValue() );
buffer.put( TLV.getBytes( searchResultEntry.getAttributesLength() ) );
// The partial attribute list
Entry entry = searchResultEntry.getEntry();
if ( ( entry != null ) && ( entry.size() != 0 ) )
{
int attributeNumber = 0;
// Compute the attributes length
for ( EntryAttribute attribute : entry )
{
// The partial attribute list sequence
buffer.put( UniversalTag.SEQUENCE.getValue() );
int localAttributeLength = searchResultEntry.getAttributeLength().get( attributeNumber );
buffer.put( TLV.getBytes( localAttributeLength ) );
// The attribute type
Value.encode( buffer, Asn1StringUtils.asciiStringToByte( attribute.getUpId() ) );
// The values
buffer.put( UniversalTag.SET.getValue() );
int localValuesLength = searchResultEntry.getValsLength().get( attributeNumber );
buffer.put( TLV.getBytes( localValuesLength ) );
if ( attribute.size() > 0 )
{
for ( org.apache.directory.shared.ldap.entry.Value<?> value : attribute )
{
if ( !value.isBinary() )
{
Value.encode( buffer, value.getString() );
}
else
{
Value.encode( buffer, value.getBytes() );
}
}
}
// Go to the next attribute number;
attributeNumber++;
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Encode the Unbind protocolOp part
*/
private void encodeUnbindRequest( ByteBuffer buffer ) throws EncoderException
{
try
{
// The tag
buffer.put( LdapConstants.UNBIND_REQUEST_TAG );
// The length is always null.
buffer.put( ( byte ) 0 );
}
catch ( BufferOverflowException boe )
{
String msg = I18n.err( I18n.ERR_04005 );
throw new EncoderException( msg );
}
}
/**
* Encode the SearchResultReference message to a PDU.
*
* SearchResultReference :
* <pre>
* 0x73 LL
* 0x04 LL reference
* [0x04 LL reference]*
* </pre>
* @param buffer The buffer where to put the PDU
* @return The PDU.
*/
private void encodeSearchResultReference( ByteBuffer buffer, SearchResultReferenceImpl searchResultReference )
throws EncoderException
{
try
{
// The SearchResultReference Tag
buffer.put( LdapConstants.SEARCH_RESULT_REFERENCE_TAG );
buffer.put( TLV.getBytes( searchResultReference.getSearchResultReferenceLength() ) );
// The referrals, if any
Referral referral = searchResultReference.getReferral();
if ( referral != null )
{
// Each referral
for ( byte[] ldapUrlBytes : referral.getLdapUrlsBytes() )
{
// Encode the current referral
Value.encode( buffer, ldapUrlBytes );
}
}
}
catch ( BufferOverflowException boe )
{
throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
}
}
/**
* Compute the protocolOp length
*/
private int computeProtocolOpLength( Message message )
{
switch ( message.getType() )
{
case ABANDON_REQUEST:
return computeAbandonRequestLength( (AbandonRequestImpl) message );
case ADD_REQUEST:
return computeAddRequestLength( (org.apache.directory.shared.ldap.codec.message.AddRequestImpl) message );
case ADD_RESPONSE:
return computeAddResponseLength( (org.apache.directory.shared.ldap.codec.message.AddResponseImpl) message );
case BIND_REQUEST:
return computeBindRequestLength( (org.apache.directory.shared.ldap.codec.message.BindRequestImpl) message );
case BIND_RESPONSE:
return computeBindResponseLength( (org.apache.directory.shared.ldap.codec.message.BindResponseImpl) message );
case COMPARE_REQUEST:
return computeCompareRequestLength( (org.apache.directory.shared.ldap.codec.message.CompareRequestImpl) message );
case COMPARE_RESPONSE:
return computeCompareResponseLength( (org.apache.directory.shared.ldap.codec.message.CompareResponseImpl) message );
case DEL_REQUEST:
return computeDeleteRequestLength( (org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl) message );
case DEL_RESPONSE:
return computeDeleteResponseLength( (org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl) message );
case EXTENDED_REQUEST:
return computeExtendedRequestLength( (org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl) message );
case EXTENDED_RESPONSE:
return computeExtendedResponseLength( (org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl) message );
case INTERMEDIATE_RESPONSE:
return computeIntermediateResponseLength( (org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl) message );
case MODIFY_REQUEST:
return computeModifyRequestLength( ( ModifyRequestImpl ) message );
case MODIFY_RESPONSE:
return computeModifyResponseLength( ( ModifyResponseImpl ) message );
case MODIFYDN_REQUEST:
return computeModifyDnRequestLength( ( ModifyDnRequestImpl ) message );
case MODIFYDN_RESPONSE:
return computeModifyDnResponseLength( ( ModifyDnResponseImpl ) message );
case SEARCH_REQUEST:
return computeSearchRequestLength( ( SearchRequestImpl ) message );
case SEARCH_RESULT_DONE:
return computeSearchResultDoneLength( ( SearchResultDoneImpl ) message );
case SEARCH_RESULT_ENTRY:
return computeSearchResultEntryLength( ( SearchResultEntryImpl ) message );
case SEARCH_RESULT_REFERENCE:
return computeSearchResultReferenceLength( ( SearchResultReferenceImpl ) message );
case UNBIND_REQUEST:
return computeUnbindRequestLength( );
default:
return 0;
}
}
private void encodeProtocolOp( ByteBuffer bb, Message message ) throws EncoderException
{
switch ( message.getType() )
{
case ABANDON_REQUEST:
encodeAbandonRequest( bb, (AbandonRequestImpl) message );
break;
case ADD_REQUEST:
encodeAddRequest( bb, (org.apache.directory.shared.ldap.codec.message.AddRequestImpl) message );
break;
case ADD_RESPONSE:
encodeAddResponse( bb, (org.apache.directory.shared.ldap.codec.message.AddResponseImpl) message );
break;
case BIND_REQUEST:
encodeBindRequest( bb, (org.apache.directory.shared.ldap.codec.message.BindRequestImpl) message );
break;
case BIND_RESPONSE:
encodeBindResponse( bb, (org.apache.directory.shared.ldap.codec.message.BindResponseImpl) message );
break;
case COMPARE_REQUEST:
encodeCompareRequest( bb, (org.apache.directory.shared.ldap.codec.message.CompareRequestImpl) message );
break;
case COMPARE_RESPONSE:
encodeCompareResponse( bb, (org.apache.directory.shared.ldap.codec.message.CompareResponseImpl) message );
break;
case DEL_REQUEST:
encodeDeleteRequest( bb, (org.apache.directory.shared.ldap.codec.message.DeleteRequestImpl) message );
break;
case DEL_RESPONSE:
encodeDeleteResponse( bb, (org.apache.directory.shared.ldap.codec.message.DeleteResponseImpl) message );
break;
case EXTENDED_REQUEST:
encodeExtendedRequest( bb, (org.apache.directory.shared.ldap.codec.message.ExtendedRequestImpl) message );
break;
case EXTENDED_RESPONSE:
encodeExtendedResponse( bb, (org.apache.directory.shared.ldap.codec.message.ExtendedResponseImpl) message );
break;
case INTERMEDIATE_RESPONSE:
encodeIntermediateResponse( bb, (org.apache.directory.shared.ldap.codec.message.IntermediateResponseImpl) message );
break;
case MODIFY_REQUEST:
encodeModifyRequest( bb, ( ModifyRequestImpl ) message );
break;
case MODIFY_RESPONSE:
encodeModifyResponse( bb, ( ModifyResponseImpl ) message );
break;
case MODIFYDN_REQUEST:
encodeModifyDnRequest( bb, ( ModifyDnRequestImpl ) message );
break;
case MODIFYDN_RESPONSE:
encodeModifyDnResponse( bb, ( ModifyDnResponseImpl ) message );
break;
case SEARCH_REQUEST:
encodeSearchRequest( bb, ( SearchRequestImpl ) message );
break;
case SEARCH_RESULT_DONE:
encodeSearchResultDone( bb, ( SearchResultDoneImpl ) message );
break;
case SEARCH_RESULT_ENTRY:
encodeSearchResultEntry( bb, ( SearchResultEntryImpl ) message );
break;
case SEARCH_RESULT_REFERENCE:
encodeSearchResultReference( bb, ( SearchResultReferenceImpl ) message );
break;
case UNBIND_REQUEST:
encodeUnbindRequest( bb );
break;
}
}
}