From b51a6c54e85f808e86235d38c54de81147990de2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 10 Feb 2019 19:50:46 +0100 Subject: [PATCH] Introduce SmackSaslException --- .../smack/SASLAuthentication.java | 25 ++++++---- .../jivesoftware/smack/SmackException.java | 20 ++++++++ .../smack/sasl/SASLMechanism.java | 36 +++++++------- .../smack/sasl/core/SASLAnonymous.java | 8 ++- .../smack/sasl/core/SASLXOauth2Mechanism.java | 9 ++-- .../smack/sasl/core/ScramMechanism.java | 49 ++++++++++--------- .../smack/sasl/core/ScramPlusMechanism.java | 8 +-- .../smack/sasl/javax/SASLJavaXMechanism.java | 24 ++++----- .../sasl/javax/SmackJavaxSaslException.java | 40 +++++++++++++++ .../sasl/provided/SASLDigestMD5Mechanism.java | 26 +++++----- .../sasl/provided/SASLExternalMechanism.java | 7 ++- .../sasl/provided/SASLPlainMechanism.java | 9 ++-- 12 files changed, 161 insertions(+), 100 deletions(-) create mode 100644 smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SmackJavaxSaslException.java 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 3a8ebc5ae..9c59c01ea 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -32,6 +32,8 @@ import javax.net.ssl.SSLSession; import javax.security.auth.callback.CallbackHandler; import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.SmackException.NotConnectedException; +import org.jivesoftware.smack.SmackException.SmackSaslException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Mechanisms; import org.jivesoftware.smack.sasl.SASLErrorException; @@ -184,12 +186,14 @@ public final class SASLAuthentication { * @throws XMPPErrorException * @throws SASLErrorException * @throws IOException - * @throws SmackException * @throws InterruptedException + * @throws SmackSaslException + * @throws NotConnectedException + * @throws NoResponseException */ public SASLMechanism authenticate(String username, String password, EntityBareJid authzid, SSLSession sslSession) throws XMPPErrorException, SASLErrorException, IOException, - SmackException, InterruptedException { + InterruptedException, SmackSaslException, NotConnectedException, NoResponseException { currentMechanism = selectMechanism(authzid); final CallbackHandler callbackHandler = configuration.getCallbackHandler(); final String host = connection.getHost(); @@ -212,10 +216,12 @@ public final class SASLAuthentication { } if (saslException != null) { - if (saslException instanceof SmackException) { - throw (SmackException) saslException; + if (saslException instanceof SmackSaslException) { + throw (SmackSaslException) saslException; } else if (saslException instanceof SASLErrorException) { throw (SASLErrorException) saslException; + } else if (saslException instanceof NotConnectedException) { + throw (NotConnectedException) saslException; } else { throw new IllegalStateException("Unexpected exception type" , saslException); } @@ -248,13 +254,14 @@ public final class SASLAuthentication { * * @param challenge a base64 encoded string representing the challenge. * @param finalChallenge true if this is the last challenge send by the server within the success stanza - * @throws SmackException + * @throws SmackSaslException + * @throws NotConnectedException * @throws InterruptedException */ - public void challengeReceived(String challenge, boolean finalChallenge) throws SmackException, InterruptedException { + public void challengeReceived(String challenge, boolean finalChallenge) throws SmackSaslException, NotConnectedException, InterruptedException { try { currentMechanism.challengeReceived(challenge, finalChallenge); - } catch (InterruptedException | SmackException e) { + } catch (InterruptedException | SmackSaslException | NotConnectedException e) { authenticationFailed(e); throw e; } @@ -325,7 +332,7 @@ public final class SASLAuthentication { return lastUsedMech.getName(); } - private SASLMechanism selectMechanism(EntityBareJid authzid) throws SmackException { + private SASLMechanism selectMechanism(EntityBareJid authzid) throws SmackException.SmackSaslException { Iterator it = REGISTERED_MECHANISMS.iterator(); final List serverMechanisms = getServerMechanisms(); if (serverMechanisms.isEmpty()) { @@ -357,7 +364,7 @@ public final class SASLAuthentication { synchronized (BLACKLISTED_MECHANISMS) { // @formatter:off - throw new SmackException( + throw new SmackException.SmackSaslException( "No supported and enabled SASL Mechanism provided by server. " + "Server announced mechanisms: " + serverMechanisms + ". " + "Registered SASL mechanisms with Smack: " + REGISTERED_MECHANISMS + ". " + diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java index 743a3f844..64ff19869 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java @@ -368,4 +368,24 @@ public class SmackException extends Exception { super(exception); } } + + public static class SmackSaslException extends SmackException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public SmackSaslException(Exception exception) { + super(exception); + } + + public SmackSaslException(String message) { + super(message); + } + + public SmackSaslException(String message, Exception exception) { + super(message, exception); + } + } } 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 8f3e8c594..d130061d3 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-2018 Florian Schmaus + * Copyright 2003-2007 Jive Software, 2014-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,8 +23,8 @@ import javax.net.ssl.SSLSession; import javax.security.auth.callback.CallbackHandler; import org.jivesoftware.smack.ConnectionConfiguration; -import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException.NotConnectedException; +import org.jivesoftware.smack.SmackException.SmackSaslException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.sasl.packet.SaslStreamElements.AuthMechanism; import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Response; @@ -139,13 +139,13 @@ public abstract class SASLMechanism implements Comparable { * @param password the password for this account. * @param authzid the optional authorization identity. * @param sslSession the optional SSL/TLS session (if one was established) - * @throws SmackException If a network error occurs while authenticating. + * @throws SmackSaslException if a SASL related error occurs. * @throws NotConnectedException * @throws InterruptedException */ public final void authenticate(String username, String host, DomainBareJid serviceName, String password, EntityBareJid authzid, SSLSession sslSession) - throws SmackException, NotConnectedException, InterruptedException { + throws SmackSaslException, NotConnectedException, InterruptedException { this.authenticationId = username; this.host = host; this.serviceName = serviceName; @@ -157,10 +157,7 @@ public abstract class SASLMechanism implements Comparable { authenticate(); } - /** - * @throws SmackException - */ - protected void authenticateInternal() throws SmackException { + protected void authenticateInternal() throws SmackSaslException { } /** @@ -172,12 +169,12 @@ public abstract class SASLMechanism implements Comparable { * @param cbh the CallbackHandler to obtain user information. * @param authzid the optional authorization identity. * @param sslSession the optional SSL/TLS session (if one was established) - * @throws SmackException + * @throws SmackSaslException if a SASL related error occurs. * @throws NotConnectedException * @throws InterruptedException */ public void authenticate(String host, DomainBareJid serviceName, CallbackHandler cbh, EntityBareJid authzid, SSLSession sslSession) - throws SmackException, NotConnectedException, InterruptedException { + throws SmackSaslException, NotConnectedException, InterruptedException { this.host = host; this.serviceName = serviceName; this.authorizationId = authzid; @@ -187,9 +184,9 @@ public abstract class SASLMechanism implements Comparable { authenticate(); } - protected abstract void authenticateInternal(CallbackHandler cbh) throws SmackException; + protected abstract void authenticateInternal(CallbackHandler cbh) throws SmackSaslException; - private void authenticate() throws SmackException, NotConnectedException, InterruptedException { + private void authenticate() throws SmackSaslException, NotConnectedException, InterruptedException { byte[] authenticationBytes = getAuthenticationText(); String authenticationText; // Some SASL mechanisms do return an empty array (e.g. EXTERNAL from javax), so check that @@ -213,9 +210,9 @@ public abstract class SASLMechanism implements Comparable { * empty array here. * * @return the initial response or null - * @throws SmackException + * @throws SmackSaslException */ - protected abstract byte[] getAuthenticationText() throws SmackException; + protected abstract byte[] getAuthenticationText() throws SmackSaslException; /** * The server is challenging the SASL mechanism for the stanza he just sent. Send a @@ -223,10 +220,11 @@ public abstract class SASLMechanism implements Comparable { * * @param challengeString a base64 encoded string representing the challenge. * @param finalChallenge true if this is the last challenge send by the server within the success stanza - * @throws SmackException exception + * @throws SmackSaslException if a SASL related error occurs. * @throws InterruptedException if the connection is interrupted + * @throws NotConnectedException */ - public final void challengeReceived(String challengeString, boolean finalChallenge) throws SmackException, InterruptedException { + public final void challengeReceived(String challengeString, boolean finalChallenge) throws SmackSaslException, InterruptedException, NotConnectedException { byte[] challenge = Base64.decode((challengeString != null && challengeString.equals("=")) ? "" : challengeString); byte[] response = evaluateChallenge(challenge); if (finalChallenge) { @@ -251,9 +249,9 @@ public abstract class SASLMechanism implements Comparable { * @param challenge challenge to evaluate. * * @return null. - * @throws SmackException in case of an error. + * @throws SmackSaslException If a SASL related error occurs. */ - protected byte[] evaluateChallenge(byte[] challenge) throws SmackException { + protected byte[] evaluateChallenge(byte[] challenge) throws SmackSaslException { return null; } @@ -278,7 +276,7 @@ public abstract class SASLMechanism implements Comparable { */ public abstract int getPriority(); - public abstract void checkIfSuccessfulOrThrow() throws SmackException; + public abstract void checkIfSuccessfulOrThrow() throws SmackSaslException; public SASLMechanism instanceForAuthentication(XMPPConnection connection, ConnectionConfiguration connectionConfiguration) { SASLMechanism saslMechansim = newInstance(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLAnonymous.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLAnonymous.java index 5fc222d32..fd99732fe 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLAnonymous.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLAnonymous.java @@ -18,7 +18,6 @@ package org.jivesoftware.smack.sasl.core; import javax.security.auth.callback.CallbackHandler; -import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.sasl.SASLMechanism; /** @@ -41,13 +40,12 @@ public class SASLAnonymous extends SASLMechanism { } @Override - protected void authenticateInternal(CallbackHandler cbh) - throws SmackException { + protected void authenticateInternal(CallbackHandler cbh) { // Nothing to do here } @Override - protected byte[] getAuthenticationText() throws SmackException { + protected byte[] getAuthenticationText() { // ANONYMOUS has no initial response, return null return null; } @@ -58,7 +56,7 @@ public class SASLAnonymous extends SASLMechanism { } @Override - public void checkIfSuccessfulOrThrow() throws SmackException { + public void checkIfSuccessfulOrThrow() { // SASL Anonymous is always successful :) } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLXOauth2Mechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLXOauth2Mechanism.java index 4b2577068..734dec529 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLXOauth2Mechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLXOauth2Mechanism.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014-2016 Florian Schmaus + * Copyright 2014-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.jivesoftware.smack.sasl.core; import javax.security.auth.callback.CallbackHandler; -import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.sasl.SASLMechanism; /** @@ -65,12 +64,12 @@ public class SASLXOauth2Mechanism extends SASLMechanism { public static final String NAME = "X-OAUTH2"; @Override - protected void authenticateInternal(CallbackHandler cbh) throws SmackException { + protected void authenticateInternal(CallbackHandler cbh) { throw new UnsupportedOperationException("CallbackHandler not (yet) supported"); } @Override - protected byte[] getAuthenticationText() throws SmackException { + protected byte[] getAuthenticationText() { // Note that base64 encoding is done in SASLMechanism for the bytes return by getAuthenticationText(). return toBytes('\u0000' + authenticationId + '\u0000' + password); } @@ -92,7 +91,7 @@ public class SASLXOauth2Mechanism extends SASLMechanism { } @Override - public void checkIfSuccessfulOrThrow() throws SmackException { + public void checkIfSuccessfulOrThrow() { // No check performed } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java index c45065f40..c55e7bb3b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014-2017 Florian Schmaus + * Copyright 2014-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import java.util.Random; import javax.security.auth.callback.CallbackHandler; import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.SmackSaslException; import org.jivesoftware.smack.sasl.SASLMechanism; import org.jivesoftware.smack.util.ByteUtils; import org.jivesoftware.smack.util.SHA1; @@ -79,12 +80,12 @@ public abstract class ScramMechanism extends SASLMechanism { private byte[] serverSignature; @Override - protected void authenticateInternal(CallbackHandler cbh) throws SmackException { + protected void authenticateInternal(CallbackHandler cbh) { throw new UnsupportedOperationException("CallbackHandler not (yet) supported"); } @Override - protected byte[] getAuthenticationText() throws SmackException { + protected byte[] getAuthenticationText() { clientRandomAscii = getRandomAscii(); String saslPrepedAuthcId = saslPrep(authenticationId); clientFirstMessageBare = "n=" + escape(saslPrepedAuthcId) + ",r=" + clientRandomAscii; @@ -100,9 +101,9 @@ public abstract class ScramMechanism extends SASLMechanism { } @Override - public void checkIfSuccessfulOrThrow() throws SmackException { + public void checkIfSuccessfulOrThrow() throws SmackSaslException { if (state != State.VALID_SERVER_RESPONSE) { - throw new SmackException("SCRAM-SHA1 is missing valid server response"); + throw new SmackSaslException("SCRAM-SHA1 is missing valid server response"); } } @@ -112,7 +113,7 @@ public abstract class ScramMechanism extends SASLMechanism { } @Override - protected byte[] evaluateChallenge(byte[] challenge) throws SmackException { + protected byte[] evaluateChallenge(byte[] challenge) throws SmackSaslException { String challengeString; try { // TODO: Where is it specified that this is an UTF-8 encoded string? @@ -130,33 +131,33 @@ public abstract class ScramMechanism extends SASLMechanism { // Handle server random ASCII (nonce) String rvalue = attributes.get('r'); if (rvalue == null) { - throw new SmackException("Server random ASCII is null"); + throw new SmackSaslException("Server random ASCII is null"); } if (rvalue.length() <= clientRandomAscii.length()) { - throw new SmackException("Server random ASCII is shorter then client random ASCII"); + throw new SmackSaslException("Server random ASCII is shorter then client random ASCII"); } String receivedClientRandomAscii = rvalue.substring(0, clientRandomAscii.length()); if (!receivedClientRandomAscii.equals(clientRandomAscii)) { - throw new SmackException("Received client random ASCII does not match client random ASCII"); + throw new SmackSaslException("Received client random ASCII does not match client random ASCII"); } // Handle iterations int iterations; String iterationsString = attributes.get('i'); if (iterationsString == null) { - throw new SmackException("Iterations attribute not set"); + throw new SmackSaslException("Iterations attribute not set"); } try { iterations = Integer.parseInt(iterationsString); } catch (NumberFormatException e) { - throw new SmackException("Exception parsing iterations", e); + throw new SmackSaslException("Exception parsing iterations", e); } // Handle salt String salt = attributes.get('s'); if (salt == null) { - throw new SmackException("SALT not send"); + throw new SmackSaslException("SALT not send"); } // Parsing and error checking is done, we can now begin to calculate the values @@ -216,12 +217,12 @@ public abstract class ScramMechanism extends SASLMechanism { case RESPONSE_SENT: String clientCalculatedServerFinalMessage = "v=" + Base64.encodeToString(serverSignature); if (!clientCalculatedServerFinalMessage.equals(challengeString)) { - throw new SmackException("Server final message does not match calculated one"); + throw new SmackSaslException("Server final message does not match calculated one"); } state = State.VALID_SERVER_RESPONSE; break; default: - throw new SmackException("Invalid state"); + throw new SmackSaslException("Invalid state"); } return null; } @@ -238,7 +239,7 @@ public abstract class ScramMechanism extends SASLMechanism { return cbName + ',' + authzidPortion + ","; } - private byte[] getCBindInput() throws SmackException { + private byte[] getCBindInput() throws SmackSaslException { byte[] cbindData = getChannelBindingData(); byte[] gs2Header = toBytes(getGS2Header()); @@ -264,13 +265,13 @@ public abstract class ScramMechanism extends SASLMechanism { /** * * @return the Channel Binding data. - * @throws SmackException + * @throws SmackSaslException */ - protected byte[] getChannelBindingData() throws SmackException { + protected byte[] getChannelBindingData() throws SmackSaslException { return null; } - private static Map parseAttributes(String string) throws SmackException { + private static Map parseAttributes(String string) throws SmackSaslException { if (string.length() == 0) { return Collections.emptyMap(); } @@ -279,11 +280,11 @@ public abstract class ScramMechanism extends SASLMechanism { Map res = new HashMap(keyValuePairs.length, 1); for (String keyValuePair : keyValuePairs) { if (keyValuePair.length() < 3) { - throw new SmackException("Invalid Key-Value pair: " + keyValuePair); + throw new SmackSaslException("Invalid Key-Value pair: " + keyValuePair); } char key = keyValuePair.charAt(0); if (keyValuePair.charAt(1) != '=') { - throw new SmackException("Invalid Key-Value pair: " + keyValuePair); + throw new SmackSaslException("Invalid Key-Value pair: " + keyValuePair); } String value = keyValuePair.substring(2); res.put(key, value); @@ -362,12 +363,12 @@ public abstract class ScramMechanism extends SASLMechanism { * @return the HMAC-SHA1 value of the input. * @throws SmackException */ - private byte[] hmac(byte[] key, byte[] str) throws SmackException { + private byte[] hmac(byte[] key, byte[] str) throws SmackSaslException { try { return scramHmac.hmac(key, str); } catch (InvalidKeyException e) { - throw new SmackException(getName() + " Exception", e); + throw new SmackSaslException(getName() + " Exception", e); } } @@ -382,9 +383,9 @@ public abstract class ScramMechanism extends SASLMechanism { * @param salt * @param iterations * @return the result of the Hi function. - * @throws SmackException + * @throws SmackSaslException if a SASL related error occurs. */ - private byte[] hi(String normalizedPassword, byte[] salt, int iterations) throws SmackException { + private byte[] hi(String normalizedPassword, byte[] salt, int iterations) throws SmackSaslException { byte[] key; try { // According to RFC 5802 § 2.2, the resulting string of the normalization is also in UTF-8. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramPlusMechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramPlusMechanism.java index bbd4d8217..0aa7eee3f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramPlusMechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramPlusMechanism.java @@ -1,6 +1,6 @@ /** * - * Copyright 2016 Florian Schmaus + * Copyright 2016-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import java.security.cert.CertificateEncodingException; import javax.net.ssl.SSLPeerUnverifiedException; -import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.SmackSaslException; import org.jivesoftware.smack.util.TLSUtils; /** @@ -48,13 +48,13 @@ public abstract class ScramPlusMechanism extends ScramMechanism { } @Override - protected byte[] getChannelBindingData() throws SmackException { + protected byte[] getChannelBindingData() throws SmackSaslException { byte[] cbData; try { cbData = TLSUtils.getChannelBindingTlsServerEndPoint(sslSession); } catch (SSLPeerUnverifiedException | CertificateEncodingException | NoSuchAlgorithmException e) { - throw new SmackException(e); + throw new SmackSaslException(e); } return cbData; } diff --git a/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLJavaXMechanism.java b/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLJavaXMechanism.java index e316a7b46..e39447e04 100644 --- a/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLJavaXMechanism.java +++ b/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLJavaXMechanism.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014 Florian Schmaus + * Copyright © 2014-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslException; -import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.SmackSaslException; import org.jivesoftware.smack.sasl.SASLMechanism; public abstract class SASLJavaXMechanism extends SASLMechanism { @@ -42,15 +42,15 @@ public abstract class SASLJavaXMechanism extends SASLMechanism { public abstract String getName(); @Override - public final void checkIfSuccessfulOrThrow() throws SmackException { + public final void checkIfSuccessfulOrThrow() throws SmackSaslException { if (!sc.isComplete()) { - throw new SmackException(getName() + " was not completed"); + throw new SmackSaslException(getName() + " was not completed"); } } @Override protected void authenticateInternal() - throws SmackException { + throws SmackJavaxSaslException { String[] mechanisms = { getName() }; Map props = getSaslProps(); String authzid = null; @@ -100,38 +100,38 @@ public abstract class SASLJavaXMechanism extends SASLMechanism { }); } catch (SaslException e) { - throw new SmackException(e); + throw new SmackJavaxSaslException(e); } } @Override protected void authenticateInternal(CallbackHandler cbh) - throws SmackException { + throws SmackJavaxSaslException { String[] mechanisms = { getName() }; Map props = getSaslProps(); try { sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh); } catch (SaslException e) { - throw new SmackException(e); + throw new SmackJavaxSaslException(e); } } @Override - protected byte[] getAuthenticationText() throws SmackException { + protected byte[] getAuthenticationText() throws SmackJavaxSaslException { if (sc.hasInitialResponse()) { try { return sc.evaluateChallenge(new byte[0]); } catch (SaslException e) { - throw new SmackException(e); + throw new SmackJavaxSaslException(e); } } return null; } @Override - protected byte[] evaluateChallenge(byte[] challenge) throws SmackException { + protected byte[] evaluateChallenge(byte[] challenge) throws SmackJavaxSaslException { try { if (challenge != null) { return sc.evaluateChallenge(challenge); @@ -141,7 +141,7 @@ public abstract class SASLJavaXMechanism extends SASLMechanism { } } catch (SaslException e) { - throw new SmackException(e); + throw new SmackJavaxSaslException(e); } } diff --git a/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SmackJavaxSaslException.java b/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SmackJavaxSaslException.java new file mode 100644 index 000000000..fdc00d5d6 --- /dev/null +++ b/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SmackJavaxSaslException.java @@ -0,0 +1,40 @@ +/** + * + * Copyright 2019 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.sasl.javax; + +import javax.security.sasl.SaslException; + +import org.jivesoftware.smack.SmackException.SmackSaslException; + +public class SmackJavaxSaslException extends SmackSaslException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private final SaslException saslException; + + public SmackJavaxSaslException(SaslException saslException) { + super(saslException); + this.saslException = saslException; + } + + public SaslException getSaslException() { + return saslException; + } +} diff --git a/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLDigestMD5Mechanism.java b/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLDigestMD5Mechanism.java index fb8eb89fa..97ff9c27c 100644 --- a/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLDigestMD5Mechanism.java +++ b/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLDigestMD5Mechanism.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014-2017 Florian Schmaus + * Copyright 2014-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import java.io.UnsupportedEncodingException; import javax.security.auth.callback.CallbackHandler; -import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.SmackSaslException; import org.jivesoftware.smack.sasl.SASLMechanism; import org.jivesoftware.smack.util.ByteUtils; import org.jivesoftware.smack.util.MD5; @@ -60,12 +60,12 @@ public class SASLDigestMD5Mechanism extends SASLMechanism { private String hex_hashed_a1; @Override - protected void authenticateInternal(CallbackHandler cbh) throws SmackException { + protected void authenticateInternal(CallbackHandler cbh) { throw new UnsupportedOperationException("CallbackHandler not (yet) supported"); } @Override - protected byte[] getAuthenticationText() throws SmackException { + protected byte[] getAuthenticationText() { // DIGEST-MD5 has no initial response, return null return null; } @@ -92,16 +92,16 @@ public class SASLDigestMD5Mechanism extends SASLMechanism { @Override - public void checkIfSuccessfulOrThrow() throws SmackException { + public void checkIfSuccessfulOrThrow() throws SmackSaslException { if (verifyServerResponse && state != State.VALID_SERVER_RESPONSE) { - throw new SmackException(NAME + " no valid server response"); + throw new SmackSaslException(NAME + " no valid server response"); } } @Override - protected byte[] evaluateChallenge(byte[] challenge) throws SmackException { + protected byte[] evaluateChallenge(byte[] challenge) throws SmackSaslException { if (challenge.length == 0) { - throw new SmackException("Initial challenge has zero length"); + throw new SmackSaslException("Initial challenge has zero length"); } String challengeString; try { @@ -127,14 +127,14 @@ public class SASLDigestMD5Mechanism extends SASLMechanism { String value = keyValue[1]; if ("nonce".equals(key)) { if (nonce != null) { - throw new SmackException("Nonce value present multiple times"); + throw new SmackSaslException("Nonce value present multiple times"); } nonce = value.replace("\"", ""); } else if ("qop".equals(key)) { value = value.replace("\"", ""); if (!value.equals("auth")) { - throw new SmackException("Unsupported qop operation: " + value); + throw new SmackSaslException("Unsupported qop operation: " + value); } } } @@ -142,7 +142,7 @@ public class SASLDigestMD5Mechanism extends SASLMechanism { // RFC 2831 2.1.1 about nonce "This directive is required and MUST appear exactly // once; if not present, or if multiple instances are present, the client should // abort the authentication exchange." - throw new SmackException("nonce value not present in initial challenge"); + throw new SmackSaslException("nonce value not present in initial challenge"); } // RFC 2831 2.1.2.1 defines A1, A2, KD and response-value byte[] a1FirstPart = MD5.bytes(authenticationId + ':' + serviceName + ':' @@ -188,12 +188,12 @@ public class SASLDigestMD5Mechanism extends SASLMechanism { } } if (serverResponse == null) { - throw new SmackException("No server response received while performing " + NAME + throw new SmackSaslException("No server response received while performing " + NAME + " authentication"); } String expectedServerResponse = calcResponse(DigestType.ServerResponse); if (!serverResponse.equals(expectedServerResponse)) { - throw new SmackException("Invalid server response while performing " + NAME + throw new SmackSaslException("Invalid server response while performing " + NAME + " authentication"); } } 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 c302153ed..cf5fea0af 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 @@ -18,7 +18,6 @@ package org.jivesoftware.smack.sasl.provided; import javax.security.auth.callback.CallbackHandler; -import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.sasl.SASLMechanism; import org.jivesoftware.smack.util.StringUtils; @@ -34,13 +33,13 @@ public class SASLExternalMechanism extends SASLMechanism { public static final String NAME = EXTERNAL; @Override - protected void authenticateInternal(CallbackHandler cbh) throws SmackException { + protected void authenticateInternal(CallbackHandler cbh) { // Do nothing. Auth will be done external to Smack and which will receive the localpart // after the resource binding } @Override - protected byte[] getAuthenticationText() throws SmackException { + protected byte[] getAuthenticationText() { if (authorizationId != null) { return toBytes(authorizationId.toString()); } @@ -68,7 +67,7 @@ public class SASLExternalMechanism extends SASLMechanism { } @Override - public void checkIfSuccessfulOrThrow() throws SmackException { + public void checkIfSuccessfulOrThrow() { // No check performed } diff --git a/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLPlainMechanism.java b/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLPlainMechanism.java index d4647a455..d83548d71 100644 --- a/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLPlainMechanism.java +++ b/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLPlainMechanism.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014 Florian Schmaus + * Copyright 2014-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.jivesoftware.smack.sasl.provided; import javax.security.auth.callback.CallbackHandler; -import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.sasl.SASLMechanism; import org.jivesoftware.smack.util.ByteUtils; @@ -27,12 +26,12 @@ public class SASLPlainMechanism extends SASLMechanism { public static final String NAME = PLAIN; @Override - protected void authenticateInternal(CallbackHandler cbh) throws SmackException { + protected void authenticateInternal(CallbackHandler cbh) { throw new UnsupportedOperationException("CallbackHandler not (yet) supported"); } @Override - protected byte[] getAuthenticationText() throws SmackException { + protected byte[] getAuthenticationText() { // concatenate and encode username (authcid) and password String authzid; if (authorizationId == null) { @@ -62,7 +61,7 @@ public class SASLPlainMechanism extends SASLMechanism { } @Override - public void checkIfSuccessfulOrThrow() throws SmackException { + public void checkIfSuccessfulOrThrow() { // No check performed }