| /* |
| * 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; |
| } |
| } |
| } |