You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2006/10/02 01:07:49 UTC
svn commit: r451836 [2/11] - in /directory/branches/shared/0.9.5/ldap/src:
main/java/org/apache/directory/shared/ldap/codec/
main/java/org/apache/directory/shared/ldap/codec/abandon/
main/java/org/apache/directory/shared/ldap/codec/actions/ main/java/o...
Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java?view=diff&rev=451836&r1=451835&r2=451836
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java Sun Oct 1 16:07:44 2006
@@ -20,17 +20,90 @@
package org.apache.directory.shared.ldap.codec;
+import javax.naming.InvalidNameException;
+import javax.naming.NamingException;
+
import org.apache.directory.shared.asn1.ber.IAsn1Container;
import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar;
import org.apache.directory.shared.asn1.ber.grammar.GrammarAction;
import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition;
+import org.apache.directory.shared.asn1.ber.grammar.IAction;
import org.apache.directory.shared.asn1.ber.grammar.IGrammar;
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.codec.DecoderException;
+import org.apache.directory.shared.asn1.primitives.OID;
+import org.apache.directory.shared.asn1.util.BooleanDecoder;
+import org.apache.directory.shared.asn1.util.BooleanDecoderException;
import org.apache.directory.shared.asn1.util.IntegerDecoder;
import org.apache.directory.shared.asn1.util.IntegerDecoderException;
+import org.apache.directory.shared.ldap.codec.abandon.AbandonRequest;
+import org.apache.directory.shared.ldap.codec.actions.AttributeDescAction;
+import org.apache.directory.shared.ldap.codec.actions.ControlValueAction;
+import org.apache.directory.shared.ldap.codec.actions.ControlsInitAction;
+import org.apache.directory.shared.ldap.codec.actions.ErrorMessageAction;
+import org.apache.directory.shared.ldap.codec.actions.InitAndFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitApproxMatchFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitAssertionValueFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitAttributeDescFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitAttributeDescListAction;
+import org.apache.directory.shared.ldap.codec.actions.InitEqualityMatchFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitExtensibleMatchFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitGreaterOrEqualFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitLessOrEqualFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitNotFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitOrFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitPresentFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.InitReferralsAction;
+import org.apache.directory.shared.ldap.codec.actions.InitSubstringsFilterAction;
+import org.apache.directory.shared.ldap.codec.actions.MatchedDNAction;
+import org.apache.directory.shared.ldap.codec.actions.ModifyAttributeValueAction;
+import org.apache.directory.shared.ldap.codec.actions.ReferralAction;
+import org.apache.directory.shared.ldap.codec.actions.ResponseAction;
+import org.apache.directory.shared.ldap.codec.actions.ResponseNameAction;
+import org.apache.directory.shared.ldap.codec.actions.ResultCodeAction;
+import org.apache.directory.shared.ldap.codec.actions.SearchResultAttributeValueAction;
+import org.apache.directory.shared.ldap.codec.actions.ServerSASLCredsAction;
+import org.apache.directory.shared.ldap.codec.actions.StoreAnyAction;
+import org.apache.directory.shared.ldap.codec.actions.StoreFinalAction;
+import org.apache.directory.shared.ldap.codec.actions.StoreMatchValueAction;
+import org.apache.directory.shared.ldap.codec.actions.StoreReferenceAction;
+import org.apache.directory.shared.ldap.codec.actions.StoreTypeMatchingRuleAction;
+import org.apache.directory.shared.ldap.codec.actions.ValueAction;
+import org.apache.directory.shared.ldap.codec.add.AddRequest;
+import org.apache.directory.shared.ldap.codec.add.AddResponse;
+import org.apache.directory.shared.ldap.codec.bind.BindRequest;
+import org.apache.directory.shared.ldap.codec.bind.BindResponse;
+import org.apache.directory.shared.ldap.codec.bind.SaslCredentials;
+import org.apache.directory.shared.ldap.codec.bind.SimpleAuthentication;
+import org.apache.directory.shared.ldap.codec.compare.CompareRequest;
+import org.apache.directory.shared.ldap.codec.compare.CompareResponse;
+import org.apache.directory.shared.ldap.codec.del.DelRequest;
+import org.apache.directory.shared.ldap.codec.del.DelResponse;
+import org.apache.directory.shared.ldap.codec.extended.ExtendedRequest;
+import org.apache.directory.shared.ldap.codec.extended.ExtendedResponse;
+import org.apache.directory.shared.ldap.codec.modify.ModifyRequest;
+import org.apache.directory.shared.ldap.codec.modify.ModifyResponse;
+import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNRequest;
+import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNResponse;
+import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
+import org.apache.directory.shared.ldap.codec.search.SearchRequest;
+import org.apache.directory.shared.ldap.codec.search.SearchResultDone;
+import org.apache.directory.shared.ldap.codec.search.SearchResultEntry;
+import org.apache.directory.shared.ldap.codec.search.SearchResultReference;
+import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
+import org.apache.directory.shared.ldap.codec.unbind.UnBindRequest;
+import org.apache.directory.shared.ldap.message.AddResponseImpl;
+import org.apache.directory.shared.ldap.message.BindResponseImpl;
+import org.apache.directory.shared.ldap.message.CompareResponseImpl;
+import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
+import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
+import org.apache.directory.shared.ldap.message.ModifyResponseImpl;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.message.SearchResponseDoneImpl;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.name.Rdn;
import org.apache.directory.shared.ldap.util.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,22 +144,22 @@
statesEnum = LdapStatesEnum.getInstance();
// Create the transitions table
- super.transitions = new GrammarTransition[LdapStatesEnum.LAST_LDAP_MESSAGE_STATE][256];
+ super.transitions = new GrammarTransition[LdapStatesEnum.LAST_LDAP_STATE][256];
// ============================================================================================
- // LdapMessage
+ // Transition from START to LdapMessage
// ============================================================================================
- // LDAPMessage --> SEQUENCE { ... (Tag)
- // We have a LDAPMessage, and the tag must be 0x30
- super.transitions[LdapStatesEnum.LDAP_MESSAGE_TAG][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
- LdapStatesEnum.LDAP_MESSAGE_TAG, LdapStatesEnum.LDAP_MESSAGE_VALUE, null );
-
- // LDAPMessage --> SEQUENCE { ... (Value)
- // Nothing to do, it's a constructed TLV. It's just a phantom transition
- // ...
- super.transitions[LdapStatesEnum.LDAP_MESSAGE_VALUE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
- LdapStatesEnum.LDAP_MESSAGE_VALUE, LdapStatesEnum.LDAP_MESSAGE_ID_TAG, new GrammarAction(
- "LdapMessage initialization" )
+ // This is the starting state :
+ // LDAPMessage --> SEQUENCE { ...
+ //
+ // We have a LDAPMessage, and the tag must be 0x30.
+ //
+ // The next state will be LDAP_MESSAGE_STATE
+ //
+ // We will just check that the length is not null
+ super.transitions[LdapStatesEnum.START_STATE][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( LdapStatesEnum.START_STATE, LdapStatesEnum.LDAP_MESSAGE_STATE, UniversalTag.SEQUENCE_TAG,
+ new GrammarAction( "LdapMessage initialization" )
{
public void action( IAsn1Container container ) throws DecoderException
{
@@ -96,9 +169,10 @@
TLV tlv = ldapMessageContainer.getCurrentTLV();
// The Length should not be null
- if ( tlv.getLength().getLength() == 0 )
+ if ( tlv.getLength() == 0 )
{
log.error( "The LdapMessage has a zero length. This is not allowed" );
+
// This will generate a PROTOCOL_ERROR
throw new DecoderException( "The LdapMessage should not be empty" );
}
@@ -108,26 +182,27 @@
// Then stores it into the container
ldapMessageContainer.setLdapMessage( ldapMessage );
- ldapMessageContainer.grammarEndAllowed( false );
return;
}
} );
// --------------------------------------------------------------------------------------------
- // LdapMessage Message ID
+ // Transition from LdapMessage to Message ID
// --------------------------------------------------------------------------------------------
- // LDAPMessage --> ... MessageId ...(Tag)
- // The tag must be 0x02. Nothing special to do.
- super.transitions[LdapStatesEnum.LDAP_MESSAGE_ID_TAG][UniversalTag.INTEGER_TAG] = new GrammarTransition(
- LdapStatesEnum.LDAP_MESSAGE_ID_TAG, LdapStatesEnum.LDAP_MESSAGE_ID_VALUE, null );
-
- // LDAPMessage --> ... MessageId ...(Value)
+ // LDAPMessage --> ... MessageId ...
+ //
// Checks that MessageId is in [0 .. 2147483647] and store the value in
// the LdapMessage Object
+ //
// (2147483647 = Integer.MAX_VALUE)
- super.transitions[LdapStatesEnum.LDAP_MESSAGE_ID_VALUE][UniversalTag.INTEGER_TAG] = new GrammarTransition(
- LdapStatesEnum.LDAP_MESSAGE_ID_VALUE, LdapStatesEnum.PROTOCOL_OP_TAG, new GrammarAction( "Store MessageId" )
+ // The next state will be MESSAGE_ID_STATE
+ //
+ // The message ID will be temporarely stored in the container, because we can't store it
+ // into an object.
+ super.transitions[LdapStatesEnum.LDAP_MESSAGE_STATE][UniversalTag.INTEGER_TAG] =
+ new GrammarTransition(LdapStatesEnum.LDAP_MESSAGE_STATE, LdapStatesEnum.MESSAGE_ID_STATE, UniversalTag.INTEGER_TAG,
+ new GrammarAction( "Store MessageId" )
{
public void action( IAsn1Container container ) throws DecoderException
{
@@ -140,7 +215,7 @@
TLV tlv = ldapMessageContainer.getCurrentTLV();
// The Length should not be null
- if ( tlv.getLength().getLength() == 0 )
+ if ( tlv.getLength() == 0 )
{
log.error( "The messageId has a zero length. This is not allowed" );
@@ -155,6 +230,7 @@
int messageId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
ldapMessage.setMessageId( messageId );
+ ldapMessageContainer.setMessageId( messageId );
if ( IS_DEBUG )
{
@@ -175,6 +251,7 @@
} );
// ********************************************************************************************
+ // We have a ProtocolOp :
// If the Tag is 0x42, then it's an UnBindRequest.
// If the Tag is 0x4A, then it's a DelRequest.
// If the Tag is 0x50, then it's an AbandonRequest.
@@ -195,199 +272,6233 @@
// If the Tag is 0x73, then it's a SearchResultReference.
// If the Tag is 0x77, then it's an ExtendedRequest.
// If the Tag is 0x78, then it's an ExtendedResponse.
+ //
+ // We create the associated object in this transition, and store it into the container.
// ********************************************************************************************
// --------------------------------------------------------------------------------------------
- // UnBindRequest Message.
+ // Transition from Message ID to UnBindRequest Message.
// --------------------------------------------------------------------------------------------
// LdapMessage ::= ... UnBindRequest ...
- // unbindRequest ::= [APPLICATION 2] NULL (Tag)
+ // unbindRequest ::= [APPLICATION 2] NULL
// We have to switch to the UnBindRequest grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.UNBIND_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.UNBIND_REQUEST_GRAMMAR_SWITCH, null );
+ super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.UNBIND_REQUEST_TAG] =
+ new GrammarTransition( LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.UNBIND_REQUEST_STATE, LdapConstants.UNBIND_REQUEST_TAG,
+ new GrammarAction( "Unbind Request initialization" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
- // --------------------------------------------------------------------------------------------
- // DelRequest Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... DelRequest ...
- // delRequest ::= [APPLICATION 10] LDAPDN (Tag)
- // We have to switch to the DelRequest grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.DEL_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.DEL_REQUEST_GRAMMAR_SWITCH, null );
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
- // --------------------------------------------------------------------------------------------
- // AbandonRequest Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... AbandonRequest ...
- // AbandonRequest ::= [APPLICATION 16] MessageID (Tag)
- // We have to switch to the AbandonRequest grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.ABANDON_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.ABANDON_REQUEST_GRAMMAR_SWITCH, null );
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+ int expectedLength = tlv.getLength();
- // --------------------------------------------------------------------------------------------
- // BindRequest Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... BindRequest ...
- // BindRequest ::= [APPLICATION 0] SEQUENCE { ... (Tag)
- // Nothing to do while the length is not checked.
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.BIND_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.BIND_REQUEST_GRAMMAR_SWITCH, null );
+ // The Length should be null
+ if ( expectedLength != 0 )
+ {
+ log.error( "The length of a UnBindRequest must be null, the actual value is {}", new Integer(
+ expectedLength ) );
+
+ // This will generate a PROTOCOL_ERROR
+ throw new DecoderException( "The length of a UnBindRequest must be null" );
+ }
+
+ UnBindRequest unBindRequest = new UnBindRequest();
+
+ unBindRequest.setParent( ldapMessage );
- // --------------------------------------------------------------------------------------------
- // BindResponse Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... BindResponse ...
- // BindResponse ::= [APPLICATION 1] SEQUENCE { ... (Tag)
- // We have to switch to the BindResponse grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.BIND_RESPONSE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.BIND_RESPONSE_GRAMMAR_SWITCH, null );
+ // And we associate it to the ldapMessage Object
+ ldapMessage.setProtocolOP( unBindRequest );
- // --------------------------------------------------------------------------------------------
- // SearchRequest Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... SearchRequest ...
- // SearchRequest ::= [APPLICATION 3] SEQUENCE { ... (Tag)
- // Nothing to do while the length is not checked.
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.SEARCH_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.SEARCH_REQUEST_GRAMMAR_SWITCH, null );
+ // We can quit now
+ ldapMessageContainer.grammarEndAllowed( true );
- // --------------------------------------------------------------------------------------------
- // SearchResultEntry Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... SearchResultEntry ...
- // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ... (Tag)
- // Nothing to do while the length is not checked.
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.SEARCH_RESULT_ENTRY_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.SEARCH_RESULT_ENTRY_GRAMMAR_SWITCH, null );
+ return;
+ }
+ } );
// --------------------------------------------------------------------------------------------
- // SearchResultDone Message.
+ // transition from UnBindRequest Message to Controls.
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... SearchResultDone ...
- // SearchResultDone ::= [APPLICATION 5] SEQUENCE { ... (Tag)
- // We have to switch to the SearchResultDone grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.SEARCH_RESULT_DONE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.SEARCH_RESULT_DONE_GRAMMAR_SWITCH, null );
+ // unbindRequest UnbindRequest,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ super.transitions[LdapStatesEnum.UNBIND_REQUEST_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.UNBIND_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
// --------------------------------------------------------------------------------------------
- // ModifyRequest Message.
+ // Transition from Message ID to DelRequest Message.
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... ModifyRequest ...
- // ModifyRequest ::= [APPLICATION 6] SEQUENCE { ... (Tag)
- // We have to switch to the ModifyRequest grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.MODIFY_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.MODIFY_REQUEST_GRAMMAR_SWITCH, null );
+ // LdapMessage ::= ... DelRequest ...
+ // delRequest ::= [APPLICATION 10] LDAPDN
+ //
+ // We store the DN to bve deleted into the DelRequest object
+ super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.DEL_REQUEST_TAG] =
+ new GrammarTransition( LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.DEL_REQUEST_STATE, LdapConstants.DEL_REQUEST_TAG,
+ new GrammarAction( "Init del Request" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
- // --------------------------------------------------------------------------------------------
- // ModifydResponse Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... ModifyResponse ...
- // ModifyResponse ::= [APPLICATION 7] SEQUENCE { ... (Tag)
- // We have to switch to the ModifyResponse grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.MODIFY_RESPONSE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.MODIFY_RESPONSE_GRAMMAR_SWITCH, null );
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
- // --------------------------------------------------------------------------------------------
- // AddRequest Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... AddRequest ...
- // AddRequest ::= [APPLICATION 8] SEQUENCE { ... (Tag)
- // We have to switch to the AddRequest grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.ADD_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.ADD_REQUEST_GRAMMAR_SWITCH, null );
+ // We can allocate the DelRequest Object
+ DelRequest delRequest = new DelRequest();
- // --------------------------------------------------------------------------------------------
- // AddResponse Message.
- // --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... AddResponse ...
- // AddResponse ::= [APPLICATION 9] LDAPResult (Tag)
- // We have to switch to the AddResponse grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.ADD_RESPONSE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.ADD_RESPONSE_GRAMMAR_SWITCH, null );
+ // And store the DN into it
+ // Get the Value and store it in the DelRequest
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ // We have to handle the special case of a 0 length matched
+ // DN
+ LdapDN entry = null;
+
+ if ( tlv.getLength() == 0 )
+ {
+ // This will generate a PROTOCOL_ERROR
+ throw new DecoderException( "The entry must not be null" );
+ }
+ else
+ {
+ byte[] dnBytes = tlv.getValue().getData();
+
+ try
+ {
+ entry = new LdapDN( dnBytes );
+ }
+ catch ( InvalidNameException ine )
+ {
+ String msg = "The DN to delete : " + StringTools.utf8ToString( dnBytes ) +
+ " (" + StringTools.dumpBytes( dnBytes )
+ + ") is invalid";
+ log.error( "{} : {}", msg, ine.getMessage() );
+
+ DeleteResponseImpl response = new DeleteResponseImpl( ldapMessage.getMessageId() );
+ throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALIDDNSYNTAX, LdapDN.EMPTY_LDAPDN, ine );
+ }
+
+ delRequest.setEntry( entry );
+ }
+
+ // then we associate it to the ldapMessage Object
+ ldapMessage.setProtocolOP( delRequest );
+
+ // We can have an END transition
+ ldapMessageContainer.grammarEndAllowed( true );
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "Deleting DN {}", entry );
+ }
+ }
+ } );
// --------------------------------------------------------------------------------------------
- // DelResponse Message.
+ // transition from DelRequest Message to Controls.
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... DelResponse ...
- // DelResponse ::= [APPLICATION 11] LDAPResult (Tag)
- // We have to switch to the DelResponse grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.DEL_RESPONSE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.DEL_RESPONSE_GRAMMAR_SWITCH, null );
+ // delRequest DelRequest,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ super.transitions[LdapStatesEnum.DEL_REQUEST_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.DEL_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
// --------------------------------------------------------------------------------------------
- // ModifydDNRequest Message.
+ // Transition from Message ID to AbandonRequest Message.
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... ModifyDNRequest ...
- // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { ... (Tag)
- // We have to switch to the ModifyDNRequest grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.MODIFY_DN_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.MODIFY_DN_REQUEST_GRAMMAR_SWITCH, null );
+ // LdapMessage ::= ... AbandonRequest ...
+ // AbandonRequest ::= [APPLICATION 16] MessageID
+ //
+ // Create the AbandonRequest object, and store the ID in it
+ super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.ABANDON_REQUEST_TAG] =
+ new GrammarTransition( LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.ABANDON_REQUEST_STATE, LdapConstants.ABANDON_REQUEST_TAG,
+ new GrammarAction( "Init Abandon Request" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+
+ // The current TLV should be a integer
+ // We get it and store it in MessageId
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ Value value = tlv.getValue();
+
+ if ( ( value == null ) || ( value.getData() == null ) )
+ {
+ String msg = "The AbandonRequest messageId must not be null";
+ log.error( msg );
+
+ // This will generate a PROTOCOL_ERROR
+ throw new DecoderException( msg );
+ }
+
+ try
+ {
+ int abandonnedMessageId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
+
+ // Ok, the Message ID is correct. We have to store it
+ // in the AbandonRequest Object
+ AbandonRequest abandonRequest = new AbandonRequest();
+ abandonRequest.setAbandonedMessageId( abandonnedMessageId );
+ ldapMessage.setProtocolOP( abandonRequest );
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "AbandonMessage Id has been decoded : {}", new Integer( abandonnedMessageId ) );
+ }
+
+ ldapMessageContainer.grammarEndAllowed( true );
+ return;
+ }
+ catch ( IntegerDecoderException ide )
+ {
+ log.error( "The Abandonned Message Id {} is invalid : {}. The message ID must be between (0 .. 2 147 483 647)",
+ StringTools.dumpBytes( value.getData() ), ide.getMessage() );
+
+ // This will generate a PROTOCOL_ERROR
+ throw new DecoderException( ide.getMessage() );
+ }
+ }
+ } );
// --------------------------------------------------------------------------------------------
- // ModifydResponse Message.
+ // transition from AbandonRequest Message to Controls.
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... ModifyDNResponse ...
- // ModifyDNResponse ::= [APPLICATION 13] SEQUENCE { ... (Tag)
- // We have to switch to the ModifyDNResponse grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.MODIFY_DN_RESPONSE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.MODIFY_DN_RESPONSE_GRAMMAR_SWITCH, null );
-
+ // abandonRequest AbandonRequest,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ super.transitions[LdapStatesEnum.ABANDON_REQUEST_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.ABANDON_REQUEST_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
// --------------------------------------------------------------------------------------------
- // CompareResquest Message.
+ // Transition from Message ID to BindRequest Message.
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... CompareRequest ...
- // CompareRequest ::= [APPLICATION 14] SEQUENCE {
- // We have to switch to the CompareRequest grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.COMPARE_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.COMPARE_REQUEST_GRAMMAR_SWITCH, null );
+ // LdapMessage ::= ... BindRequest ...
+ // BindRequest ::= [APPLICATION 0] SEQUENCE { ...
+ //
+ // We have to allocate a BindRequest
+ super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.BIND_REQUEST_TAG] =
+ new GrammarTransition( LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.BIND_REQUEST_STATE, LdapConstants.BIND_REQUEST_TAG,
+ new GrammarAction(
+ "Init BindRequest" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+
+ // We will check that the request is not null
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ if ( tlv.getLength() == 0 )
+ {
+ String msg = "The BindRequest must not be null";
+ log.error( msg );
+
+ // This will generate a PROTOCOL_ERROR
+ throw new DecoderException( msg );
+ }
+
+ // Now, we can allocate the BindRequest Object
+ ldapMessage.setProtocolOP( new BindRequest() );
+ }
+ } );
// --------------------------------------------------------------------------------------------
- // CompareResponse Message.
+ // Transition from BindRequest to version
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... CompareResponse ...
- // CompareResponse ::= [APPLICATION 15] LDAPResult (Tag)
- // We have to switch to the CompareResponse grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.COMPARE_RESPONSE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.COMPARE_RESPONSE_GRAMMAR_SWITCH, null );
+ // BindRequest ::= [APPLICATION 0] SEQUENCE {
+ // version INTEGER (1 .. 127),
+ // ....
+ //
+ // The Ldap version is parsed and stored into the BindRequest object
+ super.transitions[LdapStatesEnum.BIND_REQUEST_STATE][UniversalTag.INTEGER_TAG] =
+ new GrammarTransition( LdapStatesEnum.BIND_REQUEST_STATE, LdapStatesEnum.VERSION_STATE, UniversalTag.INTEGER_TAG,
+ new GrammarAction( "Store version" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ BindRequest bindRequestMessage = ldapMessageContainer.getLdapMessage().getBindRequest();
+
+ // The current TLV should be a integer between 1 and 127
+ // We get it and store it in Version
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ Value value = tlv.getValue();
+
+ try
+ {
+ int version = IntegerDecoder.parse( value, 1, 127 );
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "Ldap version ", new Integer( version ) );
+ }
+
+ bindRequestMessage.setVersion( version );
+ }
+ catch ( IntegerDecoderException ide )
+ {
+ log.error( "The version {} is invalid : {}. The version must be between (0 .. 127)",
+ StringTools.dumpBytes( value.getData() ), ide.getMessage() );
+
+ // This will generate a PROTOCOL_ERROR
+ throw new DecoderException( ide.getMessage() );
+ }
+ return;
+ }
+ } );
+
// --------------------------------------------------------------------------------------------
- // SearchResultReference Message.
+ // Transition from version to name
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... SearchResultReference ...
- // SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL (Tag)
- // We have to switch to the SearchResultReference grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.SEARCH_RESULT_REFERENCE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.SEARCH_RESULT_REFERENCE_GRAMMAR_SWITCH, null );
+ // BindRequest ::= [APPLICATION 0] SEQUENCE {
+ // ....
+ // name LDAPDN,
+ // ....
+ //
+ // The Ldap version is parsed and stored into the BindRequest object
+ super.transitions[LdapStatesEnum.VERSION_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.VERSION_STATE, LdapStatesEnum.NAME_STATE, UniversalTag.OCTET_STRING_TAG,
+ new GrammarAction( "Store Bind Name value" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException, InvalidNameException
+ {
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+ BindRequest bindRequestMessage = ldapMessage.getBindRequest();
+
+ // Get the Value and store it in the BindRequest
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ // We have to handle the special case of a 0 length name
+ if ( tlv.getLength() == 0 )
+ {
+ bindRequestMessage.setName( LdapDN.EMPTY_LDAPDN );
+ }
+ else
+ {
+ LdapDN name = LdapDN.EMPTY_LDAPDN;
+ byte[] dnBytes = tlv.getValue().getData();
+
+ try
+ {
+ name = new LdapDN( dnBytes );
+ }
+ catch ( InvalidNameException ine )
+ {
+ String msg = "Incorrect DN given : " + StringTools.utf8ToString( dnBytes ) +
+ " (" + StringTools.dumpBytes( dnBytes )
+ + ") is invalid";
+ log.error( "{} : {}", msg, ine.getMessage() );
+
+ BindResponseImpl response = new BindResponseImpl( ldapMessage.getMessageId() );
+
+ throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALIDDNSYNTAX, LdapDN.EMPTY_LDAPDN, ine );
+ }
+
+ bindRequestMessage.setName( name );
+ }
+ if ( IS_DEBUG )
+ {
+ log.debug( " The Bind name is {}", bindRequestMessage.getName() );
+ }
+
+ return;
+ }
+ } );
+
// --------------------------------------------------------------------------------------------
- // ExtendedRequest Message.
+ // Transition from name to Simple Authentication
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... ExtendedRequest ...
- // ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
- // We have to switch to the ExtendedRequest grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.EXTENDED_REQUEST_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.EXTENDED_REQUEST_GRAMMAR_SWITCH, null );
+ // BindRequest ::= [APPLICATION 0] SEQUENCE {
+ // ....
+ // authentication AuthenticationChoice }
+ //
+ // AuthenticationChoice ::= CHOICE {
+ // simple [0] OCTET STRING,
+ // ...
+ //
+ // We have to create an Authentication Object to store the credentials.
+ super.transitions[LdapStatesEnum.NAME_STATE][LdapConstants.BIND_REQUEST_SIMPLE_TAG] =
+ new GrammarTransition( LdapStatesEnum.NAME_STATE, LdapStatesEnum.SIMPLE_STATE, LdapConstants.BIND_REQUEST_SIMPLE_TAG,
+ new GrammarAction( "Store Bind Simple Authentication value" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+ BindRequest bindRequestMessage = ldapMessageContainer.getLdapMessage().getBindRequest();
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ // Allocate the Authentication Object
+ SimpleAuthentication authentication = null;
+
+ authentication = new SimpleAuthentication();
+
+ authentication.setParent( bindRequestMessage );
+
+ bindRequestMessage.setAuthentication( authentication );
+
+ // We have to handle the special case of a 0 length simple
+ if ( tlv.getLength() == 0 )
+ {
+ authentication.setSimple( StringTools.EMPTY_BYTES );
+ }
+ else
+ {
+ authentication.setSimple( tlv.getValue().getData() );
+ }
+
+ // We can have an END transition
+ ldapMessageContainer.grammarEndAllowed( true );
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "The simple authentication is : {}", authentication.getSimple() );
+ }
+ }
+ } );
// --------------------------------------------------------------------------------------------
- // ExtendedRequest Message.
+ // transition from Simple Authentication to Controls.
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... ExtendedResponse ...
- // ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
- // We have to switch to the ExtendedResponse grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.EXTENDED_RESPONSE_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.EXTENDED_RESPONSE_GRAMMAR_SWITCH, null );
+ // bindRequest BindRequest,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ super.transitions[LdapStatesEnum.SIMPLE_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.SIMPLE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from name to SASL Authentication
+ // --------------------------------------------------------------------------------------------
+ // BindRequest ::= [APPLICATION 0] SEQUENCE {
+ // ....
+ // authentication AuthenticationChoice }
+ //
+ // AuthenticationChoice ::= CHOICE {
+ // ...
+ // sasl [3] SaslCredentials }
+ // ...
+ //
+ // We have to create an Authentication Object to store the credentials.
+ super.transitions[LdapStatesEnum.NAME_STATE][LdapConstants.BIND_REQUEST_SASL_TAG] =
+ new GrammarTransition( LdapStatesEnum.NAME_STATE, LdapStatesEnum.SASL_STATE, LdapConstants.BIND_REQUEST_SASL_TAG,
+ new GrammarAction( "Initialize Bind SASL Authentication" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+ BindRequest bindRequestMessage = ldapMessage.getBindRequest();
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ // We will check that the sasl is not null
+ if ( tlv.getLength() == 0 )
+ {
+ String msg = "The SaslCredential must not be null";
+ log.error( msg );
+
+ BindResponseImpl response = new BindResponseImpl( ldapMessage.getMessageId() );
+
+ throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALIDCREDENTIALS,
+ bindRequestMessage.getName(), null );
+ }
+
+ // Create the SaslCredentials Object
+ SaslCredentials authentication = new SaslCredentials();
+
+ authentication.setParent( bindRequestMessage );
+
+ bindRequestMessage.setAuthentication( authentication );
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "The SaslCredential has been created" );
+ }
+
+ return;
+ }
+ } );
// --------------------------------------------------------------------------------------------
- // Controls
+ // Transition from SASL Authentication to Mechanism
// --------------------------------------------------------------------------------------------
- // LdapMessage ::= ... extendedResp ExtendedResponse },
- // controls [0] Controls OPTIONAL }
- //
- // We have to switch to the Controls grammar
- super.transitions[LdapStatesEnum.PROTOCOL_OP_TAG][LdapConstants.CONTROLS_TAG] = new GrammarTransition(
- LdapStatesEnum.PROTOCOL_OP_TAG, LdapStatesEnum.LDAP_CONTROL_GRAMMAR_SWITCH, null );
- }
+ // SaslCredentials ::= SEQUENCE {
+ // mechanism LDAPSTRING,
+ // ...
+ //
+ // We have to store the mechanism.
+ super.transitions[LdapStatesEnum.SASL_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.SASL_STATE, LdapStatesEnum.MECHANISM_STATE, UniversalTag.OCTET_STRING_TAG,
+ new GrammarAction( "Store SASL mechanism" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+ BindRequest bindRequestMessage = ldapMessage.getBindRequest();
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+ // Get the SaslCredentials Object
+ SaslCredentials authentication = bindRequestMessage.getSaslAuthentication();
+
+ // We have to handle the special case of a 0 length
+ // mechanism
+ if ( tlv.getLength() == 0 )
+ {
+ authentication.setMechanism( "" );
+ }
+ else
+ {
+ authentication.setMechanism( new String( tlv.getValue().getData() ) );
+ }
+
+ // We can have an END transition
+ ldapMessageContainer.grammarEndAllowed( true );
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "The mechanism is : {}", authentication.getMechanism() );
+ }
+
+ return;
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Mechanism to Credentials
+ // --------------------------------------------------------------------------------------------
+ // SaslCredentials ::= SEQUENCE {
+ // ...
+ // credentials OCTET STRING OPTIONAL }
+ //
+ // We have to store the mechanism.
+ super.transitions[LdapStatesEnum.MECHANISM_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CREDENTIALS_STATE, UniversalTag.OCTET_STRING_TAG,
+ new GrammarAction( "Store SASL credentials" )
+ {
+ public void action( IAsn1Container container )
+ {
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+
+ BindRequest bindRequestMessage = ldapMessageContainer.getLdapMessage().getBindRequest();
+
+ // Get the Value and store it in the BindRequest
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ SaslCredentials credentials = bindRequestMessage.getSaslAuthentication();
+
+ // We have to handle the special case of a 0 length
+ // credentials
+ if ( tlv.getLength() == 0 )
+ {
+ credentials.setCredentials( StringTools.EMPTY_BYTES );
+ }
+ else
+ {
+ credentials.setCredentials( tlv.getValue().getData() );
+ }
+
+ // We can have an END transition
+ ldapMessageContainer.grammarEndAllowed( true );
+ if ( IS_DEBUG )
+ {
+ log.debug( "The credentials are : {}", credentials.getCredentials() );
+ }
+
+ return;
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // transition from from Mechanism to Controls.
+ // --------------------------------------------------------------------------------------------
+ // bindRequest BindRequest,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ super.transitions[LdapStatesEnum.MECHANISM_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // transition from credentials to Controls.
+ // --------------------------------------------------------------------------------------------
+ // bindRequest BindRequest,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ super.transitions[LdapStatesEnum.CREDENTIALS_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.CREDENTIALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from MessageId to BindResponse message
+ // --------------------------------------------------------------------------------------------
+ // LdapMessage ::= ... BindResponse ...
+ // BindResponse ::= [APPLICATION 1] SEQUENCE { ...
+ // We have to switch to the BindResponse grammar
+ super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.BIND_RESPONSE_TAG] =
+ new GrammarTransition( LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.BIND_RESPONSE_STATE, LdapConstants.BIND_RESPONSE_TAG,
+ new GrammarAction( "Init BindReponse" )
+ {
+ public void action( IAsn1Container container )
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+
+ // Now, we can allocate the BindRequest Object
+ BindResponse bindResponse = new BindResponse();
+
+ // As this is a new Constructed object, we have to init its
+ // length
+ bindResponse.setParent( ldapMessage );
+
+ // And we associate it to the ldapMessage Object
+ ldapMessage.setProtocolOP( bindResponse );
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from BindResponse message to Result Code BR
+ // --------------------------------------------------------------------------------------------
+ // BindResponse ::= [APPLICATION 1] SEQUENCE {
+ // COMPONENTS OF LDAPResult,
+ // ...
+ //
+ // LDAPResult ::= SEQUENCE {
+ // resultCode ENUMERATED {
+ // ...
+ //
+ // Stores the result code into the Bind Response object
+ super.transitions[LdapStatesEnum.BIND_RESPONSE_STATE][UniversalTag.ENUMERATED_TAG] =
+ new GrammarTransition( LdapStatesEnum.BIND_RESPONSE_STATE, LdapStatesEnum.RESULT_CODE_BR_STATE, UniversalTag.ENUMERATED_TAG,
+ new ResultCodeAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Result Code BR to Matched DN BR
+ // --------------------------------------------------------------------------------------------
+ // LDAPResult ::= SEQUENCE {
+ // ...
+ // matchedDN LDAPDN,
+ // ...
+ //
+ // Stores the matched DN
+ super.transitions[LdapStatesEnum.RESULT_CODE_BR_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.RESULT_CODE_BR_STATE, LdapStatesEnum.MATCHED_DN_BR_STATE, UniversalTag.OCTET_STRING_TAG,
+ new MatchedDNAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Matched DN BR to Error Message BR
+ // --------------------------------------------------------------------------------------------
+ // LDAPResult ::= SEQUENCE {
+ // ...
+ // errorMessage LDAPString,
+ // ...
+ //
+ // Stores the error message
+ super.transitions[LdapStatesEnum.MATCHED_DN_BR_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.MATCHED_DN_BR_STATE, LdapStatesEnum.ERROR_MESSAGE_BR_STATE, UniversalTag.OCTET_STRING_TAG,
+ new ErrorMessageAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Error Message BR to Server SASL credentials
+ // --------------------------------------------------------------------------------------------
+ // BindResponse ::= APPLICATION 1] SEQUENCE {
+ // ...
+ // serverSaslCreds [7] OCTET STRING OPTIONAL }
+ //
+ // Stores the sasl credentials
+ super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.SERVER_SASL_CREDENTIAL_TAG] =
+ new GrammarTransition( LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE, LdapConstants.SERVER_SASL_CREDENTIAL_TAG,
+ new ServerSASLCredsAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Error Message BR to Referrals BR
+ // --------------------------------------------------------------------------------------------
+ // LDAPResult ::= SEQUENCE {
+ // ...
+ // referral [3] Referral OPTIONNAL }
+ //
+ // Initialiaze the referrals list
+ super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] =
+ new GrammarTransition( LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.REFERRALS_BR_STATE, LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG,
+ new InitReferralsAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Referrals BR to Referral BR
+ // --------------------------------------------------------------------------------------------
+ // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+ // URI ::= LDAPString
+ //
+ // Add a first Referral
+ super.transitions[LdapStatesEnum.REFERRALS_BR_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.REFERRALS_BR_STATE, LdapStatesEnum.REFERRAL_BR_STATE, UniversalTag.OCTET_STRING_TAG,
+ new ReferralAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Referral BR to Referral BR
+ // --------------------------------------------------------------------------------------------
+ // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+ // URI ::= LDAPString
+ //
+ // Adda new Referral
+ super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.REFERRAL_BR_STATE, UniversalTag.OCTET_STRING_TAG,
+ new ReferralAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Referral BR to Server SASL Credentials
+ // --------------------------------------------------------------------------------------------
+ // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+ // URI ::= LDAPString
+ //
+ // Adda new Referral
+ super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][LdapConstants.SERVER_SASL_CREDENTIAL_TAG] =
+ new GrammarTransition( LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE, LdapConstants.SERVER_SASL_CREDENTIAL_TAG,
+ new ServerSASLCredsAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Referral BR to Controls
+ // --------------------------------------------------------------------------------------------
+ // bindResponse BindResponse,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ // Adda new Referral
+ super.transitions[LdapStatesEnum.REFERRAL_BR_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.REFERRAL_BR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Error Message BR to controls
+ // --------------------------------------------------------------------------------------------
+ // bindResponse BindResponse,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ //
+ super.transitions[LdapStatesEnum.ERROR_MESSAGE_BR_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.ERROR_MESSAGE_BR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Server SASL credentials to Controls
+ // --------------------------------------------------------------------------------------------
+ // bindResponse BindResponse,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ super.transitions[LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.SERVER_SASL_CREDENTIALS_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Result Code to Matched DN
+ // --------------------------------------------------------------------------------------------
+ // LDAPResult ::= SEQUENCE {
+ // ...
+ // matchedDN LDAPDN,
+ // ...
+ //
+ // Stores the matched DN
+ super.transitions[LdapStatesEnum.RESULT_CODE_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.RESULT_CODE_STATE, LdapStatesEnum.MATCHED_DN_STATE, UniversalTag.OCTET_STRING_TAG,
+ new MatchedDNAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Matched DN to Error Message
+ // --------------------------------------------------------------------------------------------
+ // LDAPResult ::= SEQUENCE {
+ // ...
+ // errorMessage LDAPString,
+ // ...
+ //
+ // Stores the error message
+ super.transitions[LdapStatesEnum.MATCHED_DN_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.MATCHED_DN_STATE, LdapStatesEnum.ERROR_MESSAGE_STATE, UniversalTag.OCTET_STRING_TAG,
+ new ErrorMessageAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Error Message to Referrals
+ // --------------------------------------------------------------------------------------------
+ // LDAPResult ::= SEQUENCE {
+ // ...
+ // referral [3] Referral OPTIONNAL }
+ //
+ // Initialiaze the referrals list
+ super.transitions[LdapStatesEnum.ERROR_MESSAGE_STATE][LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG] =
+ new GrammarTransition( LdapStatesEnum.ERROR_MESSAGE_STATE, LdapStatesEnum.REFERRALS_STATE, LdapConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG,
+ new GrammarAction(
+ "Init referrals list" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+ LdapResponse response = ldapMessage.getLdapResponse();
+ LdapResult ldapResult = response.getLdapResult();
+
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ // If we hae a Referrals sequence, then it should not be empty
+ // sasl credentials
+ if ( tlv.getLength() == 0 )
+ {
+ String msg = "The Referrals must not be null";
+ log.error( msg );
+
+ // This will generate a PROTOCOL_ERROR
+ throw new DecoderException( msg );
+ }
+
+ ldapResult.initReferrals();
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Referrals to Referral
+ // --------------------------------------------------------------------------------------------
+ // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+ // URI ::= LDAPString
+ //
+ // Add a first Referral
+ super.transitions[LdapStatesEnum.REFERRALS_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.REFERRALS_STATE, LdapStatesEnum.REFERRAL_STATE, UniversalTag.OCTET_STRING_TAG,
+ new ReferralAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Referral to Referral
+ // --------------------------------------------------------------------------------------------
+ // Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
+ // URI ::= LDAPString
+ //
+ // Adda new Referral
+ super.transitions[LdapStatesEnum.REFERRAL_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.REFERRAL_STATE, LdapStatesEnum.REFERRAL_STATE, UniversalTag.OCTET_STRING_TAG,
+ new ReferralAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Referral to Controls
+ // --------------------------------------------------------------------------------------------
+ // xxxResponse xxxResponse,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ // Adda new Referral
+ super.transitions[LdapStatesEnum.REFERRAL_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.REFERRAL_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Error Message to controls
+ // --------------------------------------------------------------------------------------------
+ // xxxResponse xxxResponse,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ //
+ super.transitions[LdapStatesEnum.ERROR_MESSAGE_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.ERROR_MESSAGE_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from MessageId to SearchResultEntry Message.
+ // --------------------------------------------------------------------------------------------
+ // LdapMessage ::= ... SearchResultEntry ...
+ // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+ //
+ // Initialize the searchResultEntry object
+ super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_RESULT_ENTRY_TAG] =
+ new GrammarTransition( LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE, LdapConstants.SEARCH_RESULT_ENTRY_TAG,
+ new GrammarAction( "Init SearchResultEntry" )
+ {
+ public void action( IAsn1Container container )
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+
+ // Now, we can allocate the SearchResultEntry Object
+ // And we associate it to the ldapMessage Object
+ ldapMessage.setProtocolOP( new SearchResultEntry() );
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from SearchResultEntry Message to ObjectName
+ // --------------------------------------------------------------------------------------------
+ // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+ // objectName LDAPDN,
+ // ...
+ //
+ // Store the object name.
+ super.transitions[LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.SEARCH_RESULT_ENTRY_STATE, LdapStatesEnum.OBJECT_NAME_STATE, UniversalTag.OCTET_STRING_TAG,
+ new GrammarAction( "Store search result entry object name Value" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+ SearchResultEntry searchResultEntry = ldapMessage.getSearchResultEntry();
+
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ LdapDN objectName = LdapDN.EMPTY_LDAPDN;
+
+ // Store the value.
+ if ( tlv.getLength() == 0 )
+ {
+ searchResultEntry.setObjectName( objectName );
+ }
+ else
+ {
+ byte[] dnBytes = tlv.getValue().getData();
+
+ try
+ {
+ objectName = new LdapDN( dnBytes );
+ }
+ catch ( InvalidNameException ine )
+ {
+ // This is for the client side. We will never decode LdapResult on the server
+ String msg = "The DN " + StringTools.dumpBytes( dnBytes )
+ + "is invalid : " + ine.getMessage();
+ log.error( "{} : {}", msg, ine.getMessage() );
+ throw new DecoderException( msg, ine );
+ }
+
+ searchResultEntry.setObjectName( objectName );
+ }
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "Search Result Entry DN found : {}", searchResultEntry.getObjectName() );
+ }
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from ObjectName to AttributesSR
+ // --------------------------------------------------------------------------------------------
+ // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+ // ...
+ // attributes PartialAttributeList }
+ //
+ // PartialAttributeList ::= *SEQUENCE* OF SEQUENCE {
+ // ...
+ //
+ // We may have no attributes. Just allows the grammar to end
+ super.transitions[LdapStatesEnum.OBJECT_NAME_STATE][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( LdapStatesEnum.OBJECT_NAME_STATE, LdapStatesEnum.ATTRIBUTES_SR_STATE, UniversalTag.SEQUENCE_TAG,
+ new GrammarAction( "Pop and end allowed" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ container.grammarEndAllowed( true );
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from AttributesSR to PartialAttributesList
+ // --------------------------------------------------------------------------------------------
+ // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+ // ...
+ // attributes PartialAttributeList }
+ //
+ // PartialAttributeList ::= SEQUENCE OF *SEQUENCE* {
+ // ...
+ //
+ // nothing to do
+ super.transitions[LdapStatesEnum.ATTRIBUTES_SR_STATE][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( LdapStatesEnum.ATTRIBUTES_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, UniversalTag.SEQUENCE_TAG, null );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from AttributesSR to Controls
+ // --------------------------------------------------------------------------------------------
+ // searchResultEntry SearchResultEntry,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ // Initialize the controls
+ super.transitions[LdapStatesEnum.ATTRIBUTES_SR_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.ATTRIBUTES_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from PartialAttributesList to typeSR
+ // --------------------------------------------------------------------------------------------
+ // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+ // ...
+ // attributes PartialAttributeList }
+ //
+ // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+ // type AttributeDescription,
+ // ...
+ //
+ // Store the attribute's name.
+ super.transitions[LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, LdapStatesEnum.TYPE_SR_STATE, UniversalTag.OCTET_STRING_TAG,
+ new GrammarAction( "Store search result entry object name Value" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+ SearchResultEntry searchResultEntry = ldapMessage.getSearchResultEntry();
+
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ String type = "";
+
+ // Store the name
+ if ( tlv.getLength() == 0 )
+ {
+ searchResultEntry.addAttributeValues( type );
+ }
+ else
+ {
+ type = new String( tlv.getValue().getData() );
+ searchResultEntry.addAttributeValues( type );
+ }
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "Attribute type : {}", type );
+ }
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from typeSR to ValsSR
+ // --------------------------------------------------------------------------------------------
+ // SearchResultEntry ::= [APPLICATION 4] SEQUENCE { ...
+ // ...
+ // attributes PartialAttributeList }
+ //
+ // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+ // ...
+ // vals SET OF AttributeValue }
+ //
+ // We may have no value. Just allows the grammar to end
+ super.transitions[LdapStatesEnum.TYPE_SR_STATE][UniversalTag.SET_TAG] =
+ new GrammarTransition( LdapStatesEnum.TYPE_SR_STATE, LdapStatesEnum.VALS_SR_STATE, UniversalTag.SET_TAG,
+ new GrammarAction( "Grammar end allowed" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ container.grammarEndAllowed( true );
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from ValsSR to AttributeValueSR
+ // --------------------------------------------------------------------------------------------
+ // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+ // ...
+ // vals SET OF AttributeValue }
+ //
+ // AttributeValue ::= OCTET STRING
+ //
+ // Store the attribute value
+ super.transitions[LdapStatesEnum.VALS_SR_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, UniversalTag.OCTET_STRING_TAG,
+ new SearchResultAttributeValueAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from ValsSR to PartialAttributesList
+ // --------------------------------------------------------------------------------------------
+ // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+ // ...
+ // vals SET OF AttributeValue }
+ //
+ // Loop when we don't have any attribute value. Nothing to do
+ super.transitions[LdapStatesEnum.VALS_SR_STATE][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, UniversalTag.SEQUENCE_TAG, null );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from ValsSR to Controls
+ // --------------------------------------------------------------------------------------------
+ // searchResultEntry SearchResultEntry,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ // Initialize the controls
+ super.transitions[LdapStatesEnum.VALS_SR_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.VALS_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from AttributeValueSR to AttributeValueSR
+ // --------------------------------------------------------------------------------------------
+ // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+ // ...
+ // vals SET OF AttributeValue }
+ //
+ // AttributeValue ::= OCTET STRING
+ //
+ // Store the attribute value
+ super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, UniversalTag.OCTET_STRING_TAG,
+ new SearchResultAttributeValueAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from AttributeValueSR to PartialAttributesList
+ // --------------------------------------------------------------------------------------------
+ // PartialAttributeList ::= SEQUENCE OF SEQUENCE {
+ // ...
+ // vals SET OF AttributeValue }
+ //
+ // Loop when we don't have any attribute value. Nothing to do
+ super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.PARTIAL_ATTRIBUTES_LIST_STATE, UniversalTag.SEQUENCE_TAG, null );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from AttributeValueSR to Controls
+ // --------------------------------------------------------------------------------------------
+ // searchResultEntry SearchResultEntry,
+ // ... },
+ // controls [0] Controls OPTIONAL }
+ //
+ // Initialize the controls
+ super.transitions[LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE][LdapConstants.CONTROLS_TAG] =
+ new GrammarTransition( LdapStatesEnum.ATTRIBUTE_VALUE_SR_STATE, LdapStatesEnum.CONTROLS_STATE, LdapConstants.CONTROLS_TAG,
+ new ControlsInitAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // SearchResultDone Message.
+ // --------------------------------------------------------------------------------------------
+ // LdapMessage ::= ... SearchResultDone ...
+ // SearchResultDone ::= [APPLICATION 5] SEQUENCE { ...
+ //
+ super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.SEARCH_RESULT_DONE_TAG] =
+ new GrammarTransition( LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.SEARCH_RESULT_DONE_STATE, LdapConstants.SEARCH_RESULT_DONE_TAG,
+ new GrammarAction( "Init search Result Done" )
+ {
+ public void action( IAsn1Container container )
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+
+ // Now, we can allocate the SearchResultDone Object
+ ldapMessage.setProtocolOP( new SearchResultDone() );
+
+ log.debug( "Search Result Done found" );
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // SearchResultDone Message.
+ // --------------------------------------------------------------------------------------------
+ // LdapMessage ::= ... SearchResultDone ...
+ // SearchResultDone ::= [APPLICATION 5] LDAPResult
+ //
+ // LDAPResult ::= SEQUENCE {
+ // resultCode ENUMERATED {
+ // ...
+ //
+ // Stores the result code
+ super.transitions[LdapStatesEnum.SEARCH_RESULT_DONE_STATE][UniversalTag.ENUMERATED_TAG] =
+ new GrammarTransition( LdapStatesEnum.SEARCH_RESULT_DONE_STATE, LdapStatesEnum.RESULT_CODE_STATE, UniversalTag.ENUMERATED_TAG,
+ new ResultCodeAction() );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Message ID to ModifyRequest Message
+ // --------------------------------------------------------------------------------------------
+ // LdapMessage ::= ... ModifyRequest ...
+ // ModifyRequest ::= [APPLICATION 6] SEQUENCE { ...
+ //
+ // Creates the Modify Request object
+ super.transitions[LdapStatesEnum.MESSAGE_ID_STATE][LdapConstants.MODIFY_REQUEST_TAG] =
+ new GrammarTransition( LdapStatesEnum.MESSAGE_ID_STATE, LdapStatesEnum.MODIFY_REQUEST_STATE, LdapConstants.MODIFY_REQUEST_TAG,
+ new GrammarAction( "Init ModifyRequest" )
+ {
+ public void action( IAsn1Container container )
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+
+ // Now, we can allocate the ModifyRequest Object
+ // And we associate it to the ldapMessage Object
+ ldapMessage.setProtocolOP( new ModifyRequest() );
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from ModifyRequest Message to Object
+ // --------------------------------------------------------------------------------------------
+ // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+ // object LDAPDN,
+ // ...
+ //
+ // Stores the object DN
+ super.transitions[LdapStatesEnum.MODIFY_REQUEST_STATE][UniversalTag.OCTET_STRING_TAG] =
+ new GrammarTransition( LdapStatesEnum.MODIFY_REQUEST_STATE, LdapStatesEnum.OBJECT_STATE, UniversalTag.OCTET_STRING_TAG,
+ new GrammarAction( "Store Modify request object Value" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+ ModifyRequest modifyRequest = ldapMessage.getModifyRequest();
+
+ TLV tlv = ldapMessageContainer.getCurrentTLV();
+
+ LdapDN object = LdapDN.EMPTY_LDAPDN;
+
+ // Store the value.
+ if ( tlv.getLength() == 0 )
+ {
+ modifyRequest.setObject( object );
+ }
+ else
+ {
+ byte[] dnBytes = tlv.getValue().getData();
+
+ try
+ {
+ object = new LdapDN( dnBytes );
+ }
+ catch ( InvalidNameException ine )
+ {
+ String msg = "Invalid DN given : " + StringTools.utf8ToString( dnBytes ) +
+ " (" + StringTools.dumpBytes( dnBytes ) +
+ ") is invalid";
+ log.error( "{} : {}", msg, ine.getMessage() );
+
+ ModifyResponseImpl response = new ModifyResponseImpl( ldapMessage.getMessageId() );
+ throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALIDDNSYNTAX, LdapDN.EMPTY_LDAPDN, ine );
+ }
+
+ modifyRequest.setObject( object );
+ }
+
+ if ( IS_DEBUG )
+ {
+ log.debug( "Modification of DN {}", modifyRequest.getObject() );
+ }
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from Object to modifications
+ // --------------------------------------------------------------------------------------------
+ // ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+ // ...
+ // modification *SEQUENCE OF* SEQUENCE {
+ // ...
+ //
+ // Initialize the modifications list
+ super.transitions[LdapStatesEnum.OBJECT_STATE][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( LdapStatesEnum.OBJECT_STATE, LdapStatesEnum.MODIFICATIONS_STATE, UniversalTag.SEQUENCE_TAG,
+ new GrammarAction( "Init modifications array list" )
+ {
+ public void action( IAsn1Container container )
+ {
+
+ LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer ) container;
+ LdapMessage ldapMessage = ldapMessageContainer.getLdapMessage();
+ ModifyRequest modifyRequest = ldapMessage.getModifyRequest();
+
+ modifyRequest.initModifications();
+ }
+ } );
+
+ // --------------------------------------------------------------------------------------------
+ // Transition from modifications to modification sequence
[... 4973 lines stripped ...]