From 92f4aadfdc45c144763c2e2a1921c2fa9a6db90b Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 25 Mar 2021 15:01:15 +0100 Subject: [PATCH] [sasl] Avoid mechanisms that need a password when none is available --- .../smack/SASLAuthentication.java | 38 +++++++++++++------ .../smack/sasl/SASLMechanism.java | 6 ++- .../sasl/javax/SASLExternalMechanism.java | 5 +++ .../sasl/provided/SASLExternalMechanism.java | 4 ++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java index 2e02b5080..6919844f8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -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.SASLFailure; import org.jivesoftware.smack.sasl.packet.SaslNonza.Success; +import org.jivesoftware.smack.util.StringUtils; import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.EntityBareJid; @@ -184,7 +185,7 @@ public final class SASLAuthentication { SASLMechanism authenticate(String username, String password, EntityBareJid authzid, SSLSession sslSession) throws XMPPErrorException, SASLErrorException, IOException, InterruptedException, SmackSaslException, NotConnectedException, NoResponseException { - final SASLMechanism mechanism = selectMechanism(authzid); + final SASLMechanism mechanism = selectMechanism(authzid, password); final CallbackHandler callbackHandler = configuration.getCallbackHandler(); final String host = connection.getHost(); final DomainBareJid xmppServiceDomain = connection.getXMPPServiceDomain(); @@ -312,34 +313,48 @@ public final class SASLAuthentication { 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 it = REGISTERED_MECHANISMS.iterator(); final List serverMechanisms = getServerMechanisms(); if (serverMechanisms.isEmpty()) { LOGGER.warning("Server did not report any SASL mechanisms"); } + + List skipReasons = new ArrayList<>(); + // Iterate in SASL Priority order over registered mechanisms while (it.hasNext()) { SASLMechanism mechanism = it.next(); String mechanismName = mechanism.getName(); + + if (!serverMechanisms.contains(mechanismName)) { + continue; + } + synchronized (BLACKLISTED_MECHANISMS) { if (BLACKLISTED_MECHANISMS.contains(mechanismName)) { continue; } } + if (!configuration.isEnabledSaslMechanism(mechanismName)) { continue; } - if (authzid != null) { - if (!mechanism.authzidSupported()) { - LOGGER.fine("Skipping " + mechanism + " because authzid is required by not supported by this SASL mechanism"); - continue; - } + + if (authzid != null && !mechanism.authzidSupported()) { + skipReasons.add("Skipping " + mechanism + " because authzid is required by not supported by this SASL mechanism"); + continue; } - if (serverMechanisms.contains(mechanismName)) { - // Create a new instance of the SASLMechanism for every authentication attempt. - return mechanism.instanceForAuthentication(connection, configuration); + + if (mechanism.requiresPassword() && !passwordAvailable) { + skipReasons.add("Skipping " + mechanism + " because a password is required for it, but none was provided to the connection configuration"); + continue; } + + // Create a new instance of the SASLMechanism for every authentication attempt. + return mechanism.instanceForAuthentication(connection, configuration); } synchronized (BLACKLISTED_MECHANISMS) { @@ -349,7 +364,8 @@ public final class SASLAuthentication { "Server announced mechanisms: " + serverMechanisms + ". " + "Registered SASL mechanisms with Smack: " + REGISTERED_MECHANISMS + ". " + "Enabled SASL mechanisms for this connection: " + configuration.getEnabledSaslMechanisms() + ". " + - "Blacklisted SASL mechanisms: " + BLACKLISTED_MECHANISMS + '.' + "Blacklisted SASL mechanisms: " + BLACKLISTED_MECHANISMS + ". " + + "Skip reasons: " + skipReasons ); // @formatter;on } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java index e821e8e91..f1c00ef19 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java @@ -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"); * you may not use this file except in compliance with the License. @@ -311,6 +311,10 @@ public abstract class SASLMechanism implements Comparable { return false; } + public boolean requiresPassword() { + return true; + } + public boolean isAuthenticationSuccessful() { return authenticationSuccessful; } diff --git a/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLExternalMechanism.java b/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLExternalMechanism.java index 83500d5c1..d0f24e537 100644 --- a/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLExternalMechanism.java +++ b/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLExternalMechanism.java @@ -65,4 +65,9 @@ public class SASLExternalMechanism extends SASLJavaXMechanism { public SASLExternalMechanism newInstance() { return new SASLExternalMechanism(); } + + @Override + public boolean requiresPassword() { + return false; + } } diff --git a/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLExternalMechanism.java b/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLExternalMechanism.java index cf5fea0af..f1cd947d4 100644 --- a/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLExternalMechanism.java +++ b/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLExternalMechanism.java @@ -76,4 +76,8 @@ public class SASLExternalMechanism extends SASLMechanism { return true; } + @Override + public boolean requiresPassword() { + return false; + } }