LdapStatesEnum.BIND_REQUEST_STATE, LdapStatesEnum.VERSION_STATE, UniversalTag.INTEGER.getValue(),
new GrammarAction<LdapMessageContainer<BindRequestDecorator>>( "Store version" )
{
public void action( LdapMessageContainer<BindRequestDecorator> container ) throws DecoderException
{
BindRequest bindRequestMessage = container.getMessage();
// The current TLV should be a integer between 1 and 127
// We get it and store it in Version
TLV tlv = container.getCurrentTLV();
Value value = tlv.getValue();
try
{
int version = IntegerDecoder.parse( value, 1, 127 );
if ( IS_DEBUG )
{
LOG.debug( "Ldap version ", Integer.valueOf( version ) );
}
bindRequestMessage.setVersion3( version == 3 );
}
catch ( IntegerDecoderException ide )
{
LOG.error( I18n
.err( I18n.ERR_04078, Strings.dumpBytes(value.getData()), ide.getMessage() ) );
// This will generate a PROTOCOL_ERROR
throw new DecoderException( ide.getMessage() );
}
}
} );
// --------------------------------------------------------------------------------------------
// Transition from version to name
// --------------------------------------------------------------------------------------------
// BindRequest ::= [APPLICATION 0] SEQUENCE {
// ....
// name LDAPDN,
// ....
//
// The Ldap version is parsed and stored into the BindRequest object
super.transitions[LdapStatesEnum.VERSION_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
LdapStatesEnum.VERSION_STATE, LdapStatesEnum.NAME_STATE, UniversalTag.OCTET_STRING.getValue(),
new GrammarAction<LdapMessageContainer<BindRequestDecorator>>( "Store Bind Name value" )
{
public void action( LdapMessageContainer<BindRequestDecorator> container ) throws DecoderException
{
BindRequest bindRequestMessage = container.getMessage();
// Get the Value and store it in the BindRequest
TLV tlv = container.getCurrentTLV();
// We have to handle the special case of a 0 length name
if ( tlv.getLength() == 0 )
{
bindRequestMessage.setName( Dn.EMPTY_DN );
}
else
{
byte[] dnBytes = tlv.getValue().getData();
String dnStr = Strings.utf8ToString(dnBytes);
try
{
Dn dn = new Dn( dnStr );
bindRequestMessage.setName( dn );
}
catch ( LdapInvalidDnException ine )
{
String msg = "Incorrect Dn given : " + dnStr + " (" + Strings.dumpBytes(dnBytes)
+ ") is invalid";
LOG.error( "{} : {}", msg, ine.getMessage() );
BindResponseImpl response = new BindResponseImpl( bindRequestMessage.getMessageId() );
throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_DN_SYNTAX,
Dn.EMPTY_DN, ine );
}
}
if ( IS_DEBUG )
{
LOG.debug( " The Bind name is {}", bindRequestMessage.getName() );
}
}
} );
// --------------------------------------------------------------------------------------------
// Transition from name to Simple Authentication
// --------------------------------------------------------------------------------------------
// 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.ordinal()][LdapConstants.BIND_REQUEST_SIMPLE_TAG] = new GrammarTransition(
LdapStatesEnum.NAME_STATE, LdapStatesEnum.SIMPLE_STATE, LdapConstants.BIND_REQUEST_SIMPLE_TAG,
new GrammarAction<LdapMessageContainer<BindRequestDecorator>>( "Store Bind Simple Authentication value" )
{
public void action( LdapMessageContainer<BindRequestDecorator> container ) throws DecoderException
{
BindRequest bindRequestMessage = container.getMessage();
TLV tlv = container.getCurrentTLV();
// Allocate the Authentication Object
bindRequestMessage.setSimple( true );
// We have to handle the special case of a 0 length simple
if ( tlv.getLength() == 0 )
{
bindRequestMessage.setCredentials( StringConstants.EMPTY_BYTES );
}
else
{
bindRequestMessage.setCredentials( tlv.getValue().getData() );
}
// We can have an END transition
container.setGrammarEndAllowed( true );
if ( IS_DEBUG )
{
LOG.debug( "The simple authentication is : {}", Strings.dumpBytes(bindRequestMessage
.getCredentials()) );
}
}
} );
// --------------------------------------------------------------------------------------------
// transition from Simple Authentication to Controls.
// --------------------------------------------------------------------------------------------
// bindRequest BindRequest,
// ... },
// controls [0] Controls OPTIONAL }
//
super.transitions[LdapStatesEnum.SIMPLE_STATE.ordinal()][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.ordinal()][LdapConstants.BIND_REQUEST_SASL_TAG] = new GrammarTransition(
LdapStatesEnum.NAME_STATE, LdapStatesEnum.SASL_STATE, LdapConstants.BIND_REQUEST_SASL_TAG,
new GrammarAction<LdapMessageContainer<BindRequestDecorator>>( "Initialize Bind SASL Authentication" )
{
public void action( LdapMessageContainer<BindRequestDecorator> container ) throws DecoderException
{
BindRequest bindRequestMessage = container.getMessage();
TLV tlv = container.getCurrentTLV();
// We will check that the sasl is not null
if ( tlv.getLength() == 0 )
{
String msg = I18n.err( I18n.ERR_04079 );
LOG.error( msg );
BindResponseImpl response = new BindResponseImpl( bindRequestMessage.getMessageId() );
throw new ResponseCarryingException( msg, response, ResultCodeEnum.INVALID_CREDENTIALS,
bindRequestMessage.getName(), null );
}
bindRequestMessage.setSimple( false );
if ( IS_DEBUG )
{
LOG.debug( "The SaslCredential has been created" );
}
}
} );
// --------------------------------------------------------------------------------------------
// Transition from SASL Authentication to Mechanism
// --------------------------------------------------------------------------------------------
// SaslCredentials ::= SEQUENCE {
// mechanism LDAPSTRING,
// ...
//
// We have to store the mechanism.
super.transitions[LdapStatesEnum.SASL_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
LdapStatesEnum.SASL_STATE, LdapStatesEnum.MECHANISM_STATE, UniversalTag.OCTET_STRING.getValue(),
new GrammarAction<LdapMessageContainer<BindRequestDecorator>>( "Store SASL mechanism" )
{
public void action( LdapMessageContainer<BindRequestDecorator> container ) throws DecoderException
{
BindRequest bindRequestMessage = container.getMessage();
TLV tlv = container.getCurrentTLV();
// We have to handle the special case of a 0 length
// mechanism
if ( tlv.getLength() == 0 )
{
bindRequestMessage.setSaslMechanism( "" );
}
else
{
bindRequestMessage.setSaslMechanism( Strings.utf8ToString(tlv.getValue().getData()) );
}
// We can have an END transition
container.setGrammarEndAllowed( true );
if ( IS_DEBUG )
{
LOG.debug( "The mechanism is : {}", bindRequestMessage.getSaslMechanism() );
}
}
} );
// --------------------------------------------------------------------------------------------
// Transition from Mechanism to Credentials
// --------------------------------------------------------------------------------------------
// SaslCredentials ::= SEQUENCE {
// ...
// credentials OCTET STRING OPTIONAL }
//
// We have to store the mechanism.
super.transitions[LdapStatesEnum.MECHANISM_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition(
LdapStatesEnum.MECHANISM_STATE, LdapStatesEnum.CREDENTIALS_STATE, UniversalTag.OCTET_STRING.getValue(),
new GrammarAction<LdapMessageContainer<BindRequestDecorator>>( "Store SASL credentials" )
{
public void action( LdapMessageContainer<BindRequestDecorator> container )
{
BindRequest bindRequestMessage = container.getMessage();
// Get the Value and store it in the BindRequest
TLV tlv = container.getCurrentTLV();
// We have to handle the special case of a 0 length
// credentials
if ( tlv.getLength() == 0 )
{
bindRequestMessage.setCredentials( StringConstants.EMPTY_BYTES );
}
else
{
bindRequestMessage.setCredentials( tlv.getValue().getData() );
}
// We can have an END transition
container.setGrammarEndAllowed( true );
if ( IS_DEBUG )
{
LOG.debug( "The credentials are : {}", Strings.dumpBytes(bindRequestMessage
.getCredentials()) );
}
}
} );