// immediately.
if (username == null || password == null) {
return false;
}
ClientAuthenticator authenticator = null;
// now go through the progression of mechanisms we support, from the
// most secure to the
// least secure.
if (supportsAuthentication(AUTHENTICATION_DIGESTMD5)) {
authenticator = new DigestMD5Authenticator(host, username, password, getSASLRealm());
} else if (supportsAuthentication(AUTHENTICATION_CRAMMD5)) {
authenticator = new CramMD5Authenticator(username, password);
} else if (supportsAuthentication(AUTHENTICATION_LOGIN)) {
authenticator = new LoginAuthenticator(username, password);
} else if (supportsAuthentication(AUTHENTICATION_PLAIN)) {
authenticator = new PlainAuthenticator(username, password);
} else {
// can't find a mechanism we support in common
return false;
}
if (debug) {
debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
}
// if the authenticator has some initial data, we compose a command
// containing the initial data.
if (authenticator.hasInitialResponse()) {
StringBuffer command = new StringBuffer();
// the auth command initiates the handshaking.
command.append("AUTH ");
// and tell the server which mechanism we're using.
command.append(authenticator.getMechanismName());
command.append(" ");
// and append the response data
command.append(new String(Base64.encode(authenticator.evaluateChallenge(null))));
// send the command now
sendLine(command.toString());
}
// we just send an auth command with the command type.
else {
StringBuffer command = new StringBuffer();
// the auth command initiates the handshaking.
command.append("AUTH ");
// and tell the server which mechanism we're using.
command.append(authenticator.getMechanismName());
// send the command now
sendLine(command.toString());
}
// now process the challenge sequence. We get a 235 response back when
// the server accepts the
// authentication, and a 334 indicates we have an additional challenge.
while (true) {
// get the next line, and if it is an error response, return now.
SMTPReply line;
try {
line = new SMTPReply(receiveLine());
} catch (MalformedSMTPReplyException e) {
throw new MessagingException(e.toString());
} catch (MessagingException e) {
throw e;
}
// if we get a completion return, we've passed muster, so give an
// authentication response.
if (line.getCode() == AUTHENTICATION_COMPLETE) {
if (debug) {
debugOut("Successful SMTP authentication");
}
return true;
}
// we have an additional challenge to process.
else if (line.getCode() == AUTHENTICATION_CHALLENGE) {
// Does the authenticator think it is finished? We can't answer
// an additional challenge,
// so fail this.
if (authenticator.isComplete()) {
return false;
}
// we're passed back a challenge value, Base64 encoded.
byte[] challenge = Base64.decode(line.getMessage().getBytes());
// have the authenticator evaluate and send back the encoded
// response.
sendLine(new String(Base64.encode(authenticator.evaluateChallenge(challenge))));
}
// completion or challenge are the only responses we know how to
// handle. Anything else must
// be a failure.
else {