BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(gssapiBindDN.toByteString(),
SASL_MECHANISM_GSSAPI, saslCredentials);
// FIXME -- Add controls here?
LDAPMessage requestMessage =
new LDAPMessage(nextMessageID.getAndIncrement(), bindRequest);
try
{
writer.writeMessage(requestMessage);
}
catch (IOException ioe)
{
Message message = ERR_LDAPAUTH_CANNOT_SEND_SASL_BIND.get(
SASL_MECHANISM_GSSAPI, getExceptionMessage(ioe));
throw new ClientException(
LDAPResultCode.CLIENT_SIDE_SERVER_DOWN, message, ioe);
}
catch (Exception e)
{
Message message = ERR_LDAPAUTH_CANNOT_SEND_SASL_BIND.get(
SASL_MECHANISM_GSSAPI, getExceptionMessage(e));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_ENCODING_ERROR,
message, e);
}
// Read the response from the server.
LDAPMessage responseMessage;
try
{
responseMessage = reader.readMessage();
if (responseMessage == null)
{
Message message =
ERR_LDAPAUTH_CONNECTION_CLOSED_WITHOUT_BIND_RESPONSE.get();
throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN,
message);
}
}
catch (IOException ioe)
{
Message message = ERR_LDAPAUTH_CANNOT_READ_BIND_RESPONSE.get(
getExceptionMessage(ioe));
throw new ClientException(
LDAPResultCode.CLIENT_SIDE_SERVER_DOWN, message, ioe);
}
catch (ASN1Exception ae)
{
Message message =
ERR_LDAPAUTH_CANNOT_READ_BIND_RESPONSE.get(getExceptionMessage(ae));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_DECODING_ERROR,
message, ae);
}
catch (LDAPException le)
{
Message message =
ERR_LDAPAUTH_CANNOT_READ_BIND_RESPONSE.get(getExceptionMessage(le));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_DECODING_ERROR,
message, le);
}
catch (Exception e)
{
Message message =
ERR_LDAPAUTH_CANNOT_READ_BIND_RESPONSE.get(getExceptionMessage(e));
throw new ClientException(
LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR, message, e);
}
// FIXME -- Handle response controls.
// Look at the protocol op from the response. If it's a bind response,
// then continue. If it's an extended response, then it could be a notice
// of disconnection so check for that. Otherwise, generate an error.
switch (responseMessage.getProtocolOpType())
{
case OP_TYPE_BIND_RESPONSE:
// We'll deal with this later.
break;
case OP_TYPE_EXTENDED_RESPONSE:
ExtendedResponseProtocolOp extendedResponse =
responseMessage.getExtendedResponseProtocolOp();
String responseOID = extendedResponse.getOID();
if ((responseOID != null) &&
responseOID.equals(OID_NOTICE_OF_DISCONNECTION))
{
Message message = ERR_LDAPAUTH_SERVER_DISCONNECT.
get(extendedResponse.getResultCode(),
extendedResponse.getErrorMessage());
throw new LDAPException(extendedResponse.getResultCode(), message);
}
else
{
Message message = ERR_LDAPAUTH_UNEXPECTED_EXTENDED_RESPONSE.get(
String.valueOf(extendedResponse));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR,
message);
}
default:
Message message = ERR_LDAPAUTH_UNEXPECTED_RESPONSE.get(
String.valueOf(responseMessage.getProtocolOp()));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR,
message);
}
while (true)
{
BindResponseProtocolOp bindResponse =
responseMessage.getBindResponseProtocolOp();
int resultCode = bindResponse.getResultCode();
if (resultCode == LDAPResultCode.SUCCESS)
{
// We should be done after this, but we still need to look for and
// handle the server SASL credentials.
ByteString serverSASLCredentials =
bindResponse.getServerSASLCredentials();
if (serverSASLCredentials != null)
{
try
{
saslClient.evaluateChallenge(serverSASLCredentials.toByteArray());
}
catch (Exception e)
{
Message message =
ERR_LDAPAUTH_GSSAPI_CANNOT_VALIDATE_SERVER_CREDS.
get(getExceptionMessage(e));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR,
message, e);
}
}
// Just to be sure, check that the login really is complete.
if (! saslClient.isComplete())
{
Message message =
ERR_LDAPAUTH_GSSAPI_UNEXPECTED_SUCCESS_RESPONSE.get();
throw new ClientException(LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR,
message);
}
break;
}
else if (resultCode == LDAPResultCode.SASL_BIND_IN_PROGRESS)
{
// Read the response and process the server SASL credentials.
ByteString serverSASLCredentials =
bindResponse.getServerSASLCredentials();
byte[] credBytes;
try
{
if (serverSASLCredentials == null)
{
credBytes = saslClient.evaluateChallenge(new byte[0]);
}
else
{
credBytes = saslClient.evaluateChallenge(
serverSASLCredentials.toByteArray());
}
}
catch (Exception e)
{
Message message = ERR_LDAPAUTH_GSSAPI_CANNOT_VALIDATE_SERVER_CREDS.
get(getExceptionMessage(e));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR,
message, e);
}
// Send the next bind in the sequence to the server.
bindRequest =
new BindRequestProtocolOp(gssapiBindDN.toByteString(),
SASL_MECHANISM_GSSAPI, ByteString.wrap(credBytes));
// FIXME -- Add controls here?
requestMessage =
new LDAPMessage(nextMessageID.getAndIncrement(), bindRequest);
try
{
writer.writeMessage(requestMessage);
}
catch (IOException ioe)
{
Message message = ERR_LDAPAUTH_CANNOT_SEND_SASL_BIND.get(
SASL_MECHANISM_GSSAPI, getExceptionMessage(ioe));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN,
message, ioe);
}
catch (Exception e)
{
Message message = ERR_LDAPAUTH_CANNOT_SEND_SASL_BIND.get(
SASL_MECHANISM_GSSAPI, getExceptionMessage(e));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_ENCODING_ERROR,
message, e);
}
// Read the response from the server.
try
{
responseMessage = reader.readMessage();
if (responseMessage == null)
{
Message message =
ERR_LDAPAUTH_CONNECTION_CLOSED_WITHOUT_BIND_RESPONSE.get();
throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN,
message);
}
}
catch (IOException ioe)
{
Message message = ERR_LDAPAUTH_CANNOT_READ_BIND_RESPONSE.get(
getExceptionMessage(ioe));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN,
message, ioe);
}
catch (ASN1Exception ae)
{
Message message = ERR_LDAPAUTH_CANNOT_READ_BIND_RESPONSE.get(
getExceptionMessage(ae));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_DECODING_ERROR,
message, ae);
}
catch (LDAPException le)
{
Message message = ERR_LDAPAUTH_CANNOT_READ_BIND_RESPONSE.get(
getExceptionMessage(le));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_DECODING_ERROR,
message, le);
}
catch (Exception e)
{
Message message = ERR_LDAPAUTH_CANNOT_READ_BIND_RESPONSE.get(
getExceptionMessage(e));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR,
message, e);
}
// FIXME -- Handle response controls.
// Look at the protocol op from the response. If it's a bind
// response, then continue. If it's an extended response, then it
// could be a notice of disconnection so check for that. Otherwise,
// generate an error.
switch (responseMessage.getProtocolOpType())
{
case OP_TYPE_BIND_RESPONSE:
// We'll deal with this later.
break;
case OP_TYPE_EXTENDED_RESPONSE:
ExtendedResponseProtocolOp extendedResponse =
responseMessage.getExtendedResponseProtocolOp();
String responseOID = extendedResponse.getOID();
if ((responseOID != null) &&
responseOID.equals(OID_NOTICE_OF_DISCONNECTION))
{
Message message = ERR_LDAPAUTH_SERVER_DISCONNECT.
get(extendedResponse.getResultCode(),
extendedResponse.getErrorMessage());
throw new LDAPException(extendedResponse.getResultCode(),
message);
}
else
{
Message message = ERR_LDAPAUTH_UNEXPECTED_EXTENDED_RESPONSE.get(
String.valueOf(extendedResponse));
throw new ClientException(
LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR, message);
}
default:
Message message = ERR_LDAPAUTH_UNEXPECTED_RESPONSE.get(
String.valueOf(responseMessage.getProtocolOp()));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_LOCAL_ERROR,
message);
}
}
else