mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-24 23:32:05 +01:00
Add allowEmptyOrNullUsername()
to ConnectionConfiguration.Builder(). And prepare SASL EXTERNAL for empty or null usernames. Also clarify some parts regarding the user field. Fixes SMACK-627
This commit is contained in:
parent
50c7d0bc2c
commit
7e4e3699a1
4 changed files with 33 additions and 5 deletions
|
@ -158,7 +158,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
protected final Map<String, PacketExtension> streamFeatures = new HashMap<String, PacketExtension>();
|
protected final Map<String, PacketExtension> streamFeatures = new HashMap<String, PacketExtension>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The full JID of the authenticated user.
|
* The full JID of the authenticated user, as returned by the resource binding response of the server.
|
||||||
|
* <p>
|
||||||
|
* It is important that we don't infer the user from the login() arguments and the configurations service name, as,
|
||||||
|
* for example, when SASL External is used, the username is not given to login but taken from the 'external'
|
||||||
|
* certificate.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
protected String user;
|
protected String user;
|
||||||
|
|
||||||
|
@ -431,7 +436,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
*/
|
*/
|
||||||
public void login(String username, String password, String resource) throws XMPPException,
|
public void login(String username, String password, String resource) throws XMPPException,
|
||||||
SmackException, IOException {
|
SmackException, IOException {
|
||||||
if (StringUtils.isNullOrEmpty(username)) {
|
if (!config.allowNullOrEmptyUsername && StringUtils.isNullOrEmpty(username)) {
|
||||||
throw new IllegalArgumentException("Username must not be null or empty");
|
throw new IllegalArgumentException("Username must not be null or empty");
|
||||||
}
|
}
|
||||||
usedUsername = username;
|
usedUsername = username;
|
||||||
|
@ -482,6 +487,9 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
Bind bindResource = Bind.newSet(resource);
|
Bind bindResource = Bind.newSet(resource);
|
||||||
PacketCollector packetCollector = createPacketCollectorAndSend(new PacketIDFilter(bindResource), bindResource);
|
PacketCollector packetCollector = createPacketCollectorAndSend(new PacketIDFilter(bindResource), bindResource);
|
||||||
Bind response = packetCollector.nextResultOrThrow();
|
Bind response = packetCollector.nextResultOrThrow();
|
||||||
|
// Set the connections user to the result of resource binding. It is important that we don't infer the user
|
||||||
|
// from the login() arguments and the configurations service name, as, for example, when SASL External is used,
|
||||||
|
// the username is not given to login but taken from the 'external' certificate.
|
||||||
user = response.getJid();
|
user = response.getJid();
|
||||||
serviceName = XmppStringUtils.parseDomain(user);
|
serviceName = XmppStringUtils.parseDomain(user);
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,8 @@ public abstract class ConnectionConfiguration {
|
||||||
// Holds the proxy information (such as proxyhost, proxyport, username, password etc)
|
// Holds the proxy information (such as proxyhost, proxyport, username, password etc)
|
||||||
protected final ProxyInfo proxy;
|
protected final ProxyInfo proxy;
|
||||||
|
|
||||||
|
protected final boolean allowNullOrEmptyUsername;
|
||||||
|
|
||||||
protected ConnectionConfiguration(Builder<?,?> builder) {
|
protected ConnectionConfiguration(Builder<?,?> builder) {
|
||||||
if (builder.username != null) {
|
if (builder.username != null) {
|
||||||
// Do partial version of nameprep on the username.
|
// Do partial version of nameprep on the username.
|
||||||
|
@ -136,6 +138,7 @@ public abstract class ConnectionConfiguration {
|
||||||
legacySessionDisabled = builder.legacySessionDisabled;
|
legacySessionDisabled = builder.legacySessionDisabled;
|
||||||
rosterStore = builder.rosterStore;
|
rosterStore = builder.rosterStore;
|
||||||
debuggerEnabled = builder.debuggerEnabled;
|
debuggerEnabled = builder.debuggerEnabled;
|
||||||
|
allowNullOrEmptyUsername = builder.allowEmptyOrNullUsername;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -405,6 +408,7 @@ public abstract class ConnectionConfiguration {
|
||||||
private String serviceName;
|
private String serviceName;
|
||||||
private String host;
|
private String host;
|
||||||
private int port = 5222;
|
private int port = 5222;
|
||||||
|
private boolean allowEmptyOrNullUsername = false;
|
||||||
|
|
||||||
protected Builder() {
|
protected Builder() {
|
||||||
}
|
}
|
||||||
|
@ -647,6 +651,19 @@ public abstract class ConnectionConfiguration {
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow <code>null</code> or the empty String as username.
|
||||||
|
*
|
||||||
|
* Some SASL mechanisms (e.g. SASL External) may also signal the username (as "authorization identity"), in
|
||||||
|
* which case Smack should not throw an IllegalArgumentException when the username is not set.
|
||||||
|
*
|
||||||
|
* @return a reference to this builder.
|
||||||
|
*/
|
||||||
|
public B allowEmptyOrNullUsernames() {
|
||||||
|
allowEmptyOrNullUsername = true;
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
public abstract C build();
|
public abstract C build();
|
||||||
|
|
||||||
protected abstract B getThis();
|
protected abstract B getThis();
|
||||||
|
|
|
@ -91,7 +91,10 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
|
||||||
protected XMPPConnection connection;
|
protected XMPPConnection connection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* authcid
|
* authcid, i.e. the username (localpart) of the XMPP connection trying to authenticated.
|
||||||
|
* <p>
|
||||||
|
* Not to be confused with the authzid.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
protected String authenticationId;
|
protected String authenticationId;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import javax.security.auth.callback.CallbackHandler;
|
||||||
|
|
||||||
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;
|
||||||
import org.jxmpp.util.XmppStringUtils;
|
import org.jxmpp.util.XmppStringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +39,7 @@ public class SASLExternalMechanism extends SASLMechanism {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected byte[] getAuthenticationText() throws SmackException {
|
protected byte[] getAuthenticationText() throws SmackException {
|
||||||
if (authenticationId == null) {
|
if (StringUtils.isNullOrEmpty(authenticationId)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue