// Let's read the RFC2554 "initial-response" parameter
// The line could be in the form of "AUTH PLAIN <base64Secret>"
if (!stk.nextToken().trim().equalsIgnoreCase("PLAIN"))
{
// Mechanism mismatch
throw new RejectException(504, "AUTH mechanism mismatch");
}
if (stk.hasMoreTokens())
{
// the client submitted an initial response
secret = stk.nextToken();
}
else
{
// the client did not submit an initial response, we'll get it in the next pass
return "334 Ok";
}
}
byte[] decodedSecret = Base64.decode(secret);
if (decodedSecret == null)
throw new RejectException();
/*
* RFC4616: The client presents the authorization identity (identity
* to act as), followed by a NUL (U+0000) character, followed by the
* authentication identity (identity whose password will be used),
* followed by a NUL (U+0000) character, followed by the clear-text
* password.
*/
int i, j;
for (i = 0; i < decodedSecret.length && decodedSecret[i] != 0; i++)
;
if (i >= decodedSecret.length)
{
throw new RejectException();
}
for (j = i + 1; j < decodedSecret.length && decodedSecret[j] != 0; j++)
;
if (j >= decodedSecret.length)
{
throw new RejectException();
}
@SuppressWarnings("unused")
String authorizationId = new String(decodedSecret, 0, i);
String authenticationId = new String(decodedSecret, i + 1, j - i - 1);
String passwd = new String(decodedSecret, j + 1, decodedSecret.length - j - 1);
// might be nice to do something with authorizationId, but for
// purposes of the UsernamePasswordValidator, we just want to use
// authenticationId
this.username = authenticationId;
this.password = passwd;
try
{
PlainAuthenticationHandlerFactory.this.helper.login(this.username.toString(), this.password);
}
catch (LoginFailedException lfe)
{
throw new RejectException();
}
return null;
}