Commit 020eb3c5 authored by csh's avatar csh

OF-735 Openfire should return <invalid-mechanism/> SASL failure, when...

OF-735 Openfire should return <invalid-mechanism/> SASL failure, when requesting an unknown mechanism

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13958 b35dd754-fafc-0310-a699-88a17e54d16e
parent c3c245ab
...@@ -121,6 +121,32 @@ public class SASLAuthentication { ...@@ -121,6 +121,32 @@ public class SASLAuthentication {
} }
} }
private enum Failure {
ABORTED("aborted"),
ACCOUNT_DISABLED("account-disabled"),
CREDENTIALS_EXPIRED("credentials-expired"),
ENCRYPTION_REQUIRED("encryption-required"),
INCORRECT_ENCODING("incorrect-encoding"),
INVALID_AUTHZID("invalid-authzid"),
INVALID_MECHANISM("invalid-mechanism"),
MALFORMED_REQUEST("malformed-request"),
MECHANISM_TOO_WEAK("mechanism-too-weak"),
NOT_AUTHORIZED("not-authorized"),
TEMPORARY_AUTH_FAILURE("temporary-auth-failure");
private String name = null;
private Failure(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public enum Status { public enum Status {
/** /**
* Entity needs to respond last challenge. Session is still negotiating * Entity needs to respond last challenge. Session is still negotiating
...@@ -234,6 +260,13 @@ public class SASLAuthentication { ...@@ -234,6 +260,13 @@ public class SASLAuthentication {
switch (type) { switch (type) {
case AUTH: case AUTH:
mechanism = doc.attributeValue("mechanism"); mechanism = doc.attributeValue("mechanism");
// http://xmpp.org/rfcs/rfc6120.html#sasl-errors-invalid-mechanism
// The initiating entity did not specify a mechanism
if (mechanism == null) {
authenticationFailed(session, Failure.INVALID_MECHANISM);
status = Status.failed;
break;
}
// Store the requested SASL mechanism by the client // Store the requested SASL mechanism by the client
session.setSessionData("SaslMechanism", mechanism); session.setSessionData("SaslMechanism", mechanism);
//Log.debug("SASLAuthentication.doHandshake() AUTH entered: "+mechanism); //Log.debug("SASLAuthentication.doHandshake() AUTH entered: "+mechanism);
...@@ -286,14 +319,14 @@ public class SASLAuthentication { ...@@ -286,14 +319,14 @@ public class SASLAuthentication {
} }
catch (SaslException e) { catch (SaslException e) {
Log.info("User Login Failed. " + e.getMessage()); Log.info("User Login Failed. " + e.getMessage());
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
status = Status.failed; status = Status.failed;
} }
} }
else { else {
Log.warn("Client wants to do a MECH we don't support: '" + Log.warn("Client wants to do a MECH we don't support: '" +
mechanism + "'"); mechanism + "'");
authenticationFailed(session); authenticationFailed(session, Failure.INVALID_MECHANISM);
status = Status.failed; status = Status.failed;
} }
break; break;
...@@ -337,25 +370,25 @@ public class SASLAuthentication { ...@@ -337,25 +370,25 @@ public class SASLAuthentication {
} }
catch (SaslException e) { catch (SaslException e) {
Log.debug("SASLAuthentication: SaslException", e); Log.debug("SASLAuthentication: SaslException", e);
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
status = Status.failed; status = Status.failed;
} }
} }
else { else {
Log.error("SaslServer is null, should be valid object instead."); Log.error("SaslServer is null, should be valid object instead.");
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
status = Status.failed; status = Status.failed;
} }
} }
else { else {
Log.warn( Log.warn(
"Client responded to a MECH we don't support: '" + mechanism + "'"); "Client responded to a MECH we don't support: '" + mechanism + "'");
authenticationFailed(session); authenticationFailed(session, Failure.INVALID_MECHANISM);
status = Status.failed; status = Status.failed;
} }
break; break;
default: default:
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
status = Status.failed; status = Status.failed;
// Ignore // Ignore
break; break;
...@@ -363,7 +396,7 @@ public class SASLAuthentication { ...@@ -363,7 +396,7 @@ public class SASLAuthentication {
} }
else { else {
Log.debug("SASLAuthentication: Unknown namespace sent in auth element: " + doc.asXML()); Log.debug("SASLAuthentication: Unknown namespace sent in auth element: " + doc.asXML());
authenticationFailed(session); authenticationFailed(session, Failure.MALFORMED_REQUEST);
status = Status.failed; status = Status.failed;
} }
// Check if SASL authentication has finished so we can clean up temp information // Check if SASL authentication has finished so we can clean up temp information
...@@ -461,7 +494,7 @@ public class SASLAuthentication { ...@@ -461,7 +494,7 @@ public class SASLAuthentication {
forbidAccess = true; forbidAccess = true;
} }
if (forbidAccess) { if (forbidAccess) {
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
return Status.failed; return Status.failed;
} }
// Just accept the authentication :) // Just accept the authentication :)
...@@ -470,7 +503,7 @@ public class SASLAuthentication { ...@@ -470,7 +503,7 @@ public class SASLAuthentication {
} }
else { else {
// anonymous login is disabled so close the connection // anonymous login is disabled so close the connection
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
return Status.failed; return Status.failed;
} }
} }
...@@ -521,13 +554,13 @@ public class SASLAuthentication { ...@@ -521,13 +554,13 @@ public class SASLAuthentication {
Log.debug("SASLAuthentication: EXTERNAL authentication via SSL certs for c2s connection"); Log.debug("SASLAuthentication: EXTERNAL authentication via SSL certs for c2s connection");
// This may be null, we will deal with that later // This may be null, we will deal with that later
String username = new String(StringUtils.decodeBase64(doc.getTextTrim()), CHARSET); String username = new String(StringUtils.decodeBase64(doc.getTextTrim()), CHARSET);
String principal = ""; String principal = "";
ArrayList<String> principals = new ArrayList<String>(); ArrayList<String> principals = new ArrayList<String>();
Connection connection = session.getConnection(); Connection connection = session.getConnection();
if (connection.getPeerCertificates().length < 1) { if (connection.getPeerCertificates().length < 1) {
Log.debug("SASLAuthentication: EXTERNAL authentication requested, but no certificates found."); Log.debug("SASLAuthentication: EXTERNAL authentication requested, but no certificates found.");
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
return Status.failed; return Status.failed;
} }
...@@ -578,7 +611,7 @@ public class SASLAuthentication { ...@@ -578,7 +611,7 @@ public class SASLAuthentication {
} else { } else {
Log.debug("SASLAuthentication: unknown session type. Cannot perform EXTERNAL authentication"); Log.debug("SASLAuthentication: unknown session type. Cannot perform EXTERNAL authentication");
} }
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
return Status.failed; return Status.failed;
} }
...@@ -603,7 +636,7 @@ public class SASLAuthentication { ...@@ -603,7 +636,7 @@ public class SASLAuthentication {
return Status.authenticated; return Status.authenticated;
} }
// Otherwise, authentication failed. // Otherwise, authentication failed.
authenticationFailed(session); authenticationFailed(session, Failure.NOT_AUTHORIZED);
return Status.failed; return Status.failed;
} }
...@@ -628,7 +661,7 @@ public class SASLAuthentication { ...@@ -628,7 +661,7 @@ public class SASLAuthentication {
if (username != null && LockOutManager.getInstance().isAccountDisabled(username)) { if (username != null && LockOutManager.getInstance().isAccountDisabled(username)) {
// Interception! This person is locked out, fail instead! // Interception! This person is locked out, fail instead!
LockOutManager.getInstance().recordFailedLogin(username); LockOutManager.getInstance().recordFailedLogin(username);
authenticationFailed(session); authenticationFailed(session, Failure.ACCOUNT_DISABLED);
return; return;
} }
StringBuilder reply = new StringBuilder(80); StringBuilder reply = new StringBuilder(80);
...@@ -653,10 +686,11 @@ public class SASLAuthentication { ...@@ -653,10 +686,11 @@ public class SASLAuthentication {
} }
} }
private static void authenticationFailed(LocalSession session) { private static void authenticationFailed(LocalSession session, Failure failure) {
StringBuilder reply = new StringBuilder(80); StringBuilder reply = new StringBuilder(80);
reply.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); reply.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"><");
reply.append("<not-authorized/></failure>"); reply.append(failure.toString());
reply.append("/></failure>");
session.deliverRawText(reply.toString()); session.deliverRawText(reply.toString());
// Give a number of retries before closing the connection // Give a number of retries before closing the connection
Integer retries = (Integer) session.getSessionData("authRetries"); Integer retries = (Integer) session.getSessionData("authRetries");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment