mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-23 23:02:05 +01:00
[sasl] Avoid mechanisms that need a password when none is available
This commit is contained in:
parent
72e11ebf71
commit
92f4aadfdc
4 changed files with 41 additions and 12 deletions
|
@ -42,6 +42,7 @@ import org.jivesoftware.smack.sasl.core.ScramSha1PlusMechanism;
|
||||||
import org.jivesoftware.smack.sasl.packet.SaslNonza;
|
import org.jivesoftware.smack.sasl.packet.SaslNonza;
|
||||||
import org.jivesoftware.smack.sasl.packet.SaslNonza.SASLFailure;
|
import org.jivesoftware.smack.sasl.packet.SaslNonza.SASLFailure;
|
||||||
import org.jivesoftware.smack.sasl.packet.SaslNonza.Success;
|
import org.jivesoftware.smack.sasl.packet.SaslNonza.Success;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
|
||||||
import org.jxmpp.jid.DomainBareJid;
|
import org.jxmpp.jid.DomainBareJid;
|
||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
|
@ -184,7 +185,7 @@ public final class SASLAuthentication {
|
||||||
SASLMechanism authenticate(String username, String password, EntityBareJid authzid, SSLSession sslSession)
|
SASLMechanism authenticate(String username, String password, EntityBareJid authzid, SSLSession sslSession)
|
||||||
throws XMPPErrorException, SASLErrorException, IOException,
|
throws XMPPErrorException, SASLErrorException, IOException,
|
||||||
InterruptedException, SmackSaslException, NotConnectedException, NoResponseException {
|
InterruptedException, SmackSaslException, NotConnectedException, NoResponseException {
|
||||||
final SASLMechanism mechanism = selectMechanism(authzid);
|
final SASLMechanism mechanism = selectMechanism(authzid, password);
|
||||||
final CallbackHandler callbackHandler = configuration.getCallbackHandler();
|
final CallbackHandler callbackHandler = configuration.getCallbackHandler();
|
||||||
final String host = connection.getHost();
|
final String host = connection.getHost();
|
||||||
final DomainBareJid xmppServiceDomain = connection.getXMPPServiceDomain();
|
final DomainBareJid xmppServiceDomain = connection.getXMPPServiceDomain();
|
||||||
|
@ -312,35 +313,49 @@ public final class SASLAuthentication {
|
||||||
return lastUsedMech.getName();
|
return lastUsedMech.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SASLMechanism selectMechanism(EntityBareJid authzid) throws SmackException.SmackSaslException {
|
private SASLMechanism selectMechanism(EntityBareJid authzid, String password) throws SmackException.SmackSaslException {
|
||||||
|
final boolean passwordAvailable = StringUtils.isNotEmpty(password);
|
||||||
|
|
||||||
Iterator<SASLMechanism> it = REGISTERED_MECHANISMS.iterator();
|
Iterator<SASLMechanism> it = REGISTERED_MECHANISMS.iterator();
|
||||||
final List<String> serverMechanisms = getServerMechanisms();
|
final List<String> serverMechanisms = getServerMechanisms();
|
||||||
if (serverMechanisms.isEmpty()) {
|
if (serverMechanisms.isEmpty()) {
|
||||||
LOGGER.warning("Server did not report any SASL mechanisms");
|
LOGGER.warning("Server did not report any SASL mechanisms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> skipReasons = new ArrayList<>();
|
||||||
|
|
||||||
// Iterate in SASL Priority order over registered mechanisms
|
// Iterate in SASL Priority order over registered mechanisms
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
SASLMechanism mechanism = it.next();
|
SASLMechanism mechanism = it.next();
|
||||||
String mechanismName = mechanism.getName();
|
String mechanismName = mechanism.getName();
|
||||||
|
|
||||||
|
if (!serverMechanisms.contains(mechanismName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (BLACKLISTED_MECHANISMS) {
|
synchronized (BLACKLISTED_MECHANISMS) {
|
||||||
if (BLACKLISTED_MECHANISMS.contains(mechanismName)) {
|
if (BLACKLISTED_MECHANISMS.contains(mechanismName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!configuration.isEnabledSaslMechanism(mechanismName)) {
|
if (!configuration.isEnabledSaslMechanism(mechanismName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (authzid != null) {
|
|
||||||
if (!mechanism.authzidSupported()) {
|
if (authzid != null && !mechanism.authzidSupported()) {
|
||||||
LOGGER.fine("Skipping " + mechanism + " because authzid is required by not supported by this SASL mechanism");
|
skipReasons.add("Skipping " + mechanism + " because authzid is required by not supported by this SASL mechanism");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mechanism.requiresPassword() && !passwordAvailable) {
|
||||||
|
skipReasons.add("Skipping " + mechanism + " because a password is required for it, but none was provided to the connection configuration");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (serverMechanisms.contains(mechanismName)) {
|
|
||||||
// Create a new instance of the SASLMechanism for every authentication attempt.
|
// Create a new instance of the SASLMechanism for every authentication attempt.
|
||||||
return mechanism.instanceForAuthentication(connection, configuration);
|
return mechanism.instanceForAuthentication(connection, configuration);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (BLACKLISTED_MECHANISMS) {
|
synchronized (BLACKLISTED_MECHANISMS) {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
@ -349,7 +364,8 @@ public final class SASLAuthentication {
|
||||||
"Server announced mechanisms: " + serverMechanisms + ". " +
|
"Server announced mechanisms: " + serverMechanisms + ". " +
|
||||||
"Registered SASL mechanisms with Smack: " + REGISTERED_MECHANISMS + ". " +
|
"Registered SASL mechanisms with Smack: " + REGISTERED_MECHANISMS + ". " +
|
||||||
"Enabled SASL mechanisms for this connection: " + configuration.getEnabledSaslMechanisms() + ". " +
|
"Enabled SASL mechanisms for this connection: " + configuration.getEnabledSaslMechanisms() + ". " +
|
||||||
"Blacklisted SASL mechanisms: " + BLACKLISTED_MECHANISMS + '.'
|
"Blacklisted SASL mechanisms: " + BLACKLISTED_MECHANISMS + ". " +
|
||||||
|
"Skip reasons: " + skipReasons
|
||||||
);
|
);
|
||||||
// @formatter;on
|
// @formatter;on
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2003-2007 Jive Software, 2014-2019 Florian Schmaus
|
* Copyright 2003-2007 Jive Software, 2014-2021 Florian Schmaus
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -311,6 +311,10 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean requiresPassword() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isAuthenticationSuccessful() {
|
public boolean isAuthenticationSuccessful() {
|
||||||
return authenticationSuccessful;
|
return authenticationSuccessful;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,4 +65,9 @@ public class SASLExternalMechanism extends SASLJavaXMechanism {
|
||||||
public SASLExternalMechanism newInstance() {
|
public SASLExternalMechanism newInstance() {
|
||||||
return new SASLExternalMechanism();
|
return new SASLExternalMechanism();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresPassword() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,4 +76,8 @@ public class SASLExternalMechanism extends SASLMechanism {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresPassword() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue