Search in sources :

Example 71 with Control

use of org.apache.directory.api.ldap.model.message.Control in project directory-ldap-api by apache.

the class AddControl method action.

/**
 * {@inheritDoc}
 */
public void action(LdapMessageContainer<MessageDecorator<? extends Message>> container) throws DecoderException {
    TLV tlv = container.getCurrentTLV();
    // We have to handle the special case of a 0 length OID
    if (tlv.getLength() == 0) {
        String msg = I18n.err(I18n.ERR_04097_NULL_CONTROL_OID);
        LOG.error(msg);
        // This will generate a PROTOCOL_ERROR
        throw new DecoderException(msg);
    }
    byte[] value = tlv.getValue().getData();
    String oidValue = Strings.asciiBytesToString(value);
    // The OID is encoded as a String, not an Object Id
    if (!Oid.isOid(oidValue)) {
        String msg = I18n.err(I18n.ERR_04098_INVALID_CONTROL_OID, oidValue);
        LOG.error(msg);
        // This will generate a PROTOCOL_ERROR
        throw new DecoderException(msg);
    }
    Message message = container.getMessage();
    Control control = container.getLdapCodecService().newControl(oidValue);
    message.addControl(control);
    // We can have an END transition
    container.setGrammarEndAllowed(true);
    if (IS_DEBUG) {
        LOG.debug("Control OID : {}", oidValue);
    }
}
Also used : DecoderException(org.apache.directory.api.asn1.DecoderException) Control(org.apache.directory.api.ldap.model.message.Control) Message(org.apache.directory.api.ldap.model.message.Message) TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Example 72 with Control

use of org.apache.directory.api.ldap.model.message.Control in project directory-ldap-api by apache.

the class LdapEncoder method computeMessageLength.

/**
 * Compute the LdapMessage length LdapMessage :
 * <pre>
 * 0x30 L1
 *   |
 *   +--&gt; 0x02 0x0(1-4) [0..2^31-1] (MessageId)
 *   +--&gt; protocolOp
 *   [+--&gt; Controls]
 *
 * MessageId length = Length(0x02) + length(MessageId) + MessageId.length
 * L1 = length(ProtocolOp)
 * LdapMessage length = Length(0x30) + Length(L1) + MessageId length + L1
 * </pre>
 *
 * @param messageDecorator the decorated Message who's length is to be encoded
 */
private int computeMessageLength(MessageDecorator<? extends Message> messageDecorator) {
    // 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 + BerValue.getNbBytes(messageDecorator.getDecorated().getMessageId());
    // Get the protocolOp length
    ldapMessageLength += messageDecorator.computeLength();
    Map<String, Control> controls = messageDecorator.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()) {
            int controlLength = computeControlLength(control);
            controlsSequenceLength += 1 + TLV.getNbBytes(controlLength) + controlLength;
        }
        // Computes the controls length
        // 1 + Length.getNbBytes( controlsSequenceLength ) + controlsSequenceLength
        messageDecorator.setControlsLength(controlsSequenceLength);
        // Now, add the tag and the length of the controls length
        ldapMessageLength += 1 + TLV.getNbBytes(controlsSequenceLength) + controlsSequenceLength;
    }
    // Store the messageLength
    messageDecorator.setMessageLength(ldapMessageLength);
    return 1 + ldapMessageLength + TLV.getNbBytes(ldapMessageLength);
}
Also used : Control(org.apache.directory.api.ldap.model.message.Control)

Example 73 with Control

use of org.apache.directory.api.ldap.model.message.Control in project directory-ldap-api by apache.

the class LdapEncoder method encodeMessage.

/**
 * 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
 *   |
 *   +--&gt; 0x02 L2 MessageId
 *   +--&gt; ProtocolOp
 *   +--&gt; 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 {
    MessageDecorator<? extends Message> decorator = MessageDecorator.getDecorator(codec, message);
    int length = computeMessageLength(decorator);
    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(decorator.getMessageLength()));
        } catch (BufferOverflowException boe) {
            throw new EncoderException(I18n.err(I18n.ERR_04005), boe);
        }
        // The message Id
        BerValue.encode(buffer, message.getMessageId());
        // Add the protocolOp part
        decorator.encode(buffer);
        // Do the same thing for Controls, if any.
        Map<String, Control> controls = decorator.getControls();
        if ((controls != null) && (controls.size() > 0)) {
            // Encode the controls
            buffer.put((byte) LdapCodecConstants.CONTROLS_TAG);
            buffer.put(TLV.getBytes(decorator.getControlsLength()));
            // Encode each control
            for (Control control : controls.values()) {
                encodeControl(buffer, control);
                // The OctetString tag if the value is not null
                int controlValueLength = ((CodecControl<?>) control).computeLength();
                if (controlValueLength > 0) {
                    buffer.put(UniversalTag.OCTET_STRING.getValue());
                    buffer.put(TLV.getBytes(controlValueLength));
                    // And now, the value
                    ((org.apache.directory.api.ldap.codec.api.CodecControl<?>) control).encode(buffer);
                }
            }
        }
    } catch (EncoderException ee) {
        throw new MessageEncoderException(message.getMessageId(), ee.getMessage(), ee);
    }
    buffer.flip();
    return buffer;
}
Also used : ByteBuffer(java.nio.ByteBuffer) EncoderException(org.apache.directory.api.asn1.EncoderException) Control(org.apache.directory.api.ldap.model.message.Control) BufferOverflowException(java.nio.BufferOverflowException)

Example 74 with Control

use of org.apache.directory.api.ldap.model.message.Control in project directory-ldap-api by apache.

the class MessageDecorator method addControl.

/**
 * {@inheritDoc}
 */
@SuppressWarnings("unchecked")
@Override
public Message addControl(Control control) {
    Control decorated;
    CodecControl<? extends Control> controlDecorator;
    if (control instanceof ControlDecorator) {
        controlDecorator = (org.apache.directory.api.ldap.codec.api.CodecControl<? extends Control>) control;
        decorated = controlDecorator.getDecorated();
    } else {
        controlDecorator = codec.newControl(control);
        decorated = control;
    }
    decoratedMessage.addControl(decorated);
    controls.put(control.getOid(), controlDecorator);
    currentControl = controlDecorator;
    return this;
}
Also used : Control(org.apache.directory.api.ldap.model.message.Control)

Example 75 with Control

use of org.apache.directory.api.ldap.model.message.Control in project directory-ldap-api by apache.

the class EndTransactionResponseTest method testEndTransactionResponseUpdateControls.

/**
 * Test the decoding of a EndTransactionResponse with updateControls
 */
@Test
public void testEndTransactionResponseUpdateControls() throws DecoderException, EncoderException {
    Asn1Decoder decoder = new Asn1Decoder();
    ByteBuffer bb = ByteBuffer.allocate(0xAC);
    bb.put(new byte[] { // EndTransactionResponse ::= SEQUENCE {
    0x30, // EndTransactionResponse ::= SEQUENCE {
    (byte) 0x81, // EndTransactionResponse ::= SEQUENCE {
    (byte) 0xA9, // UpdateControls
    0x30, // UpdateControls
    (byte) 0x81, // UpdateControls
    (byte) 0xA6, // updateControl
    0x30, // updateControl
    0x5F, // messageID
    0x02, // messageID
    0x01, // messageID
    0x01, // controls
    0x30, // controls
    0x5A, // Control ::= SEQUENCE {
    0x30, // Control ::= SEQUENCE {
    0x1A, // controlType LDAPOID,
    0x04, // controlType LDAPOID,
    0x0D, '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '1', // criticality BOOLEAN DEFAULT FALSE,
    0x01, // criticality BOOLEAN DEFAULT FALSE,
    0x01, // criticality BOOLEAN DEFAULT FALSE,
    (byte) 0xFF, // controlValue OCTET STRING OPTIONAL }
    0x04, // controlValue OCTET STRING OPTIONAL }
    0x06, 'a', 'b', 'c', 'd', 'e', 'f', // Control ::= SEQUENCE {
    0x30, // Control ::= SEQUENCE {
    0x17, // controlType LDAPOID,
    0x04, // controlType LDAPOID,
    0x0D, '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '2', // controlValue OCTET STRING OPTIONAL }
    0x04, // controlValue OCTET STRING OPTIONAL }
    0x06, 'g', 'h', 'i', 'j', 'k', 'l', // Control ::= SEQUENCE {
    0x30, // Control ::= SEQUENCE {
    0x12, // controlType LDAPOID,
    0x04, // controlType LDAPOID,
    0x0D, '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '3', // criticality BOOLEAN DEFAULT FALSE}
    0x01, // criticality BOOLEAN DEFAULT FALSE}
    0x01, // criticality BOOLEAN DEFAULT FALSE}
    (byte) 0xFF, // Control ::= SEQUENCE {
    0x30, // Control ::= SEQUENCE {
    0x0F, // controlType LDAPOID}
    0x04, // controlType LDAPOID}
    0x0D, '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '4', // updateControl
    0x30, // updateControl
    0x43, // messageID
    0x02, // messageID
    0x01, // messageID
    0x02, // controls
    0x30, // controls
    0x3E, // Control ::= SEQUENCE {
    0x30, // Control ::= SEQUENCE {
    0x17, // controlType LDAPOID,
    0x04, // controlType LDAPOID,
    0x0D, '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '2', // controlValue OCTET STRING OPTIONAL }
    0x04, // controlValue OCTET STRING OPTIONAL }
    0x06, 'g', 'h', 'i', 'j', 'k', 'l', // Control ::= SEQUENCE {
    0x30, // Control ::= SEQUENCE {
    0x12, // controlType LDAPOID,
    0x04, // controlType LDAPOID,
    0x0D, '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '3', // criticality BOOLEAN DEFAULT FALSE}
    0x01, // criticality BOOLEAN DEFAULT FALSE}
    0x01, // criticality BOOLEAN DEFAULT FALSE}
    (byte) 0xFF, // Control ::= SEQUENCE {
    0x30, // Control ::= SEQUENCE {
    0x0F, // controlType LDAPOID}
    0x04, // controlType LDAPOID}
    0x0D, '1', '.', '3', '.', '6', '.', '1', '.', '5', '.', '5', '.', '4' });
    String decodedPdu = Strings.dumpBytes(bb.array());
    bb.flip();
    EndTransactionResponseContainer container = new EndTransactionResponseContainer();
    try {
        decoder.decode(bb, container);
    } catch (DecoderException de) {
        de.printStackTrace();
        fail(de.getMessage());
    }
    EndTransactionResponse endTransactionResponse = container.getEndTransactionResponse();
    assertEquals(-1, endTransactionResponse.getFailedMessageId());
    assertEquals(2, endTransactionResponse.getUpdateControls().size());
    UpdateControls updateControls1 = endTransactionResponse.getUpdateControls().get(0);
    assertEquals(1, updateControls1.getMessageId());
    assertNotNull(updateControls1.getControls());
    assertEquals(4, updateControls1.getControls().size());
    for (Control control : updateControls1.getControls()) {
        switch(control.getOid()) {
            case "1.3.6.1.5.5.1":
                assertTrue(control.isCritical());
                assertEquals("abcdef", Strings.utf8ToString(((CodecControl<?>) control).getValue()));
                break;
            case "1.3.6.1.5.5.2":
                assertFalse(control.isCritical());
                assertEquals("ghijkl", Strings.utf8ToString(((CodecControl<?>) control).getValue()));
                break;
            case "1.3.6.1.5.5.3":
                assertTrue(control.isCritical());
                assertNull(((CodecControl<?>) control).getValue());
                break;
            case "1.3.6.1.5.5.4":
                assertFalse(control.isCritical());
                assertNull(((CodecControl<?>) control).getValue());
                break;
            default:
                fail();
                break;
        }
    }
    UpdateControls updateControls2 = endTransactionResponse.getUpdateControls().get(1);
    assertEquals(2, updateControls2.getMessageId());
    assertNotNull(updateControls2.getControls());
    assertEquals(3, updateControls2.getControls().size());
    for (Control control : updateControls2.getControls()) {
        switch(control.getOid()) {
            case "1.3.6.1.5.5.2":
                assertFalse(control.isCritical());
                assertEquals("ghijkl", Strings.utf8ToString(((CodecControl<?>) control).getValue()));
                break;
            case "1.3.6.1.5.5.3":
                assertTrue(control.isCritical());
                assertNull(((CodecControl<?>) control).getValue());
                break;
            case "1.3.6.1.5.5.4":
                assertFalse(control.isCritical());
                assertNull(((CodecControl<?>) control).getValue());
                break;
            default:
                fail();
                break;
        }
    }
    // Check the length
    assertEquals(0xAC, ((EndTransactionResponseDecorator) endTransactionResponse).computeLengthInternal());
    // Check the encoding
    ByteBuffer bb1 = ((EndTransactionResponseDecorator) endTransactionResponse).encodeInternal();
    String encodedPdu = Strings.dumpBytes(bb1.array());
    assertEquals(encodedPdu, decodedPdu);
}
Also used : DecoderException(org.apache.directory.api.asn1.DecoderException) Control(org.apache.directory.api.ldap.model.message.Control) CodecControl(org.apache.directory.api.ldap.codec.api.CodecControl) UpdateControls(org.apache.directory.api.ldap.extras.extended.endTransaction.UpdateControls) Asn1Decoder(org.apache.directory.api.asn1.ber.Asn1Decoder) CodecControl(org.apache.directory.api.ldap.codec.api.CodecControl) EndTransactionResponse(org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionResponse) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Aggregations

Control (org.apache.directory.api.ldap.model.message.Control)145 Test (org.junit.Test)124 DsmlControl (org.apache.directory.api.dsmlv2.DsmlControl)85 DecoderException (org.apache.directory.api.asn1.DecoderException)45 AbstractTest (org.apache.directory.api.dsmlv2.AbstractTest)45 Dsmlv2Parser (org.apache.directory.api.dsmlv2.Dsmlv2Parser)45 AbstractResponseTest (org.apache.directory.api.dsmlv2.AbstractResponseTest)40 Dsmlv2ResponseParser (org.apache.directory.api.dsmlv2.Dsmlv2ResponseParser)40 ByteBuffer (java.nio.ByteBuffer)39 CodecControl (org.apache.directory.api.ldap.codec.api.CodecControl)38 EncoderException (org.apache.directory.api.asn1.EncoderException)37 Asn1Decoder (org.apache.directory.api.asn1.ber.Asn1Decoder)37 AbstractCodecServiceTest (org.apache.directory.api.ldap.codec.osgi.AbstractCodecServiceTest)36 LdapURLEncodingException (org.apache.directory.api.ldap.model.exception.LdapURLEncodingException)36 LdapMessageContainer (org.apache.directory.api.ldap.codec.api.LdapMessageContainer)35 SearchResponse (org.apache.directory.api.dsmlv2.response.SearchResponse)12 LdapException (org.apache.directory.api.ldap.model.exception.LdapException)12 BindRequest (org.apache.directory.api.ldap.model.message.BindRequest)11 AbandonRequest (org.apache.directory.api.ldap.model.message.AbandonRequest)9 SearchRequest (org.apache.directory.api.ldap.model.message.SearchRequest)9