Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 90425 invoked from network); 3 Oct 2006 13:51:09 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 3 Oct 2006 13:51:08 -0000 Received: (qmail 96614 invoked by uid 500); 3 Oct 2006 13:51:05 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 96528 invoked by uid 500); 3 Oct 2006 13:51:05 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 96115 invoked by uid 99); 3 Oct 2006 13:51:00 -0000 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME,UPPERCASE_25_50 X-Spam-Check-By: apache.org Received-SPF: pass (hermes.apache.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 03 Oct 2006 06:50:57 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id CF98C1A981D; Tue, 3 Oct 2006 06:49:50 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r452497 [2/9] - in /directory/trunks/shared/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/add/ main/java/org/apache/dir... Date: Tue, 03 Oct 2006 13:49:46 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061003134950.CF98C1A981D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Modified: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java?view=diff&rev=452497&r1=452496&r2=452497 ============================================================================== --- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java (original) +++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageGrammar.java Tue Oct 3 06:49:43 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 + // -------------------------------------------------------------------------------------------- [... 4972 lines stripped ...]