Make SASLMechanism.getAuthenticationText() return byte[]

every SASL Mechanism is designed as a byte array based protocol. XMPP
adds the constraint that the challenges and responses are send base64
encoded. It's therefore better API design to let getAuthenticationText()
return byte[] instead of String.
This commit is contained in:
Florian Schmaus 2014-08-11 21:39:09 +02:00
parent c5b7f14527
commit f37682d980
5 changed files with 32 additions and 14 deletions

View File

@ -27,8 +27,10 @@ import javax.security.auth.callback.CallbackHandler;
*/ */
public class SASLAnonymous extends SASLMechanism { public class SASLAnonymous extends SASLMechanism {
public static final String NAME = "ANONYMOUS";
public String getName() { public String getName() {
return "ANONYMOUS"; return NAME;
} }
@Override @Override
@ -43,8 +45,8 @@ public class SASLAnonymous extends SASLMechanism {
} }
@Override @Override
protected String getAuthenticationText() throws SmackException { protected byte[] getAuthenticationText() throws SmackException {
// TODO Auto-generated method stub // ANONYMOUS has no initial response, return null
return null; return null;
} }

View File

@ -169,12 +169,28 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
protected abstract void authenticateInternal(CallbackHandler cbh) throws SmackException; protected abstract void authenticateInternal(CallbackHandler cbh) throws SmackException;
private final void authenticate() throws SmackException, NotConnectedException { private final void authenticate() throws SmackException, NotConnectedException {
String authenticationText = getAuthenticationText(); byte[] authenticationBytes = getAuthenticationText();
String authenticationText;
if (authenticationBytes != null) {
authenticationText = StringUtils.encodeBase64(authenticationBytes);
} else {
// RFC6120 6.4.2 "If the initiating entity needs to send a zero-length initial response,
// it MUST transmit the response as a single equals sign character ("="), which
// indicates that the response is present but contains no data."
authenticationText = "=";
}
// Send the authentication to the server // Send the authentication to the server
connection.sendPacket(new AuthMechanism(getName(), authenticationText)); connection.sendPacket(new AuthMechanism(getName(), authenticationText));
} }
protected abstract String getAuthenticationText() throws SmackException; /**
* Should return the initial response of the SASL mechanism. The returned byte array will be
* send base64 encoded to the server. SASL mechanism are free to return <code>null</code> here.
*
* @return the initial response or null
* @throws SmackException
*/
protected abstract byte[] getAuthenticationText() throws SmackException;
/** /**
* The server is challenging the SASL mechanism for the stanza he just sent. Send a * The server is challenging the SASL mechanism for the stanza he just sent. Send a

View File

@ -37,8 +37,11 @@ public class SaslStanzas {
if (mechanism == null) { if (mechanism == null) {
throw new NullPointerException("SASL mechanism shouldn't be null."); throw new NullPointerException("SASL mechanism shouldn't be null.");
} }
if (StringUtils.isNullOrEmpty(authenticationText)) {
throw new IllegalArgumentException("SASL authenticationText must not be null or empty (RFC6120 6.4.2)");
}
this.mechanism = mechanism; this.mechanism = mechanism;
this.authenticationText = StringUtils.returnIfNotEmptyTrimmed(authenticationText); this.authenticationText = authenticationText;
} }
@Override @Override

View File

@ -33,7 +33,6 @@ import javax.security.sasl.SaslException;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.sasl.SASLMechanism; import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.util.StringUtils;
public abstract class SASLJavaXMechanism extends SASLMechanism { public abstract class SASLJavaXMechanism extends SASLMechanism {
@ -107,19 +106,17 @@ public abstract class SASLJavaXMechanism extends SASLMechanism {
} }
} }
protected String getAuthenticationText() throws SmackException { @Override
String authenticationText = null; protected byte[] getAuthenticationText() throws SmackException {
if (sc.hasInitialResponse()) { if (sc.hasInitialResponse()) {
byte[] response;
try { try {
response = sc.evaluateChallenge(new byte[0]); return sc.evaluateChallenge(new byte[0]);
} }
catch (SaslException e) { catch (SaslException e) {
throw new SmackException(e); throw new SmackException(e);
} }
authenticationText = StringUtils.encodeBase64(response, false);
} }
return authenticationText; return null;
} }
@Override @Override

View File

@ -62,7 +62,7 @@ public class SASLDigestMD5Mechanism extends SASLMechanism {
} }
@Override @Override
protected String getAuthenticationText() throws SmackException { protected byte[] getAuthenticationText() throws SmackException {
// DIGEST-MD5 has no initial response, return null // DIGEST-MD5 has no initial response, return null
return null; return null;
} }