SaslStreamElements.java
/**
*
* Copyright 2014-2018 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.packet;
import java.util.Map;
import org.jivesoftware.smack.packet.AbstractError;
import org.jivesoftware.smack.packet.Nonza;
import org.jivesoftware.smack.sasl.SASLError;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
public class SaslStreamElements {
public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-sasl";
/**
* Initiating SASL authentication by select a mechanism.
*/
public static class AuthMechanism implements Nonza {
public static final String ELEMENT = "auth";
private final String mechanism;
private final String authenticationText;
public AuthMechanism(String mechanism, String authenticationText) {
this.mechanism = Objects.requireNonNull(mechanism, "SASL mechanism shouldn't be null.");
this.authenticationText = StringUtils.requireNotNullOrEmpty(authenticationText,
"SASL authenticationText must not be null or empty (RFC6120 6.4.2)");
}
@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).attribute("mechanism", mechanism).rightAngleBracket();
xml.optAppend(authenticationText);
xml.closeElement(ELEMENT);
return xml;
}
public String getMechanism() {
return mechanism;
}
public String getAuthenticationText() {
return authenticationText;
}
@Override
public String getNamespace() {
return NAMESPACE;
}
@Override
public String getElementName() {
return ELEMENT;
}
}
/**
* A SASL challenge stream element.
*/
public static class Challenge implements Nonza {
public static final String ELEMENT = "challenge";
private final String data;
public Challenge(String data) {
this.data = StringUtils.returnIfNotEmptyTrimmed(data);
}
@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder().halfOpenElement(ELEMENT).xmlnsAttribute(
NAMESPACE).rightAngleBracket();
xml.optAppend(data);
xml.closeElement(ELEMENT);
return xml;
}
@Override
public String getNamespace() {
return NAMESPACE;
}
@Override
public String getElementName() {
return ELEMENT;
}
}
/**
* A SASL response stream element.
*/
public static class Response implements Nonza {
public static final String ELEMENT = "response";
private final String authenticationText;
public Response() {
authenticationText = null;
}
public Response(String authenticationText) {
this.authenticationText = StringUtils.returnIfNotEmptyTrimmed(authenticationText);
}
@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket();
xml.optAppend(authenticationText);
xml.closeElement(ELEMENT);
return xml;
}
public String getAuthenticationText() {
return authenticationText;
}
@Override
public String getNamespace() {
return NAMESPACE;
}
@Override
public String getElementName() {
return ELEMENT;
}
}
/**
* A SASL success stream element.
*/
public static class Success implements Nonza {
public static final String ELEMENT = "success";
private final String data;
/**
* Construct a new SASL success stream element with optional additional data for the SASL layer.
* (RFC6120 6.3.10)
*
* @param data additional data for the SASL layer or <code>null</code>
*/
public Success(String data) {
this.data = StringUtils.returnIfNotEmptyTrimmed(data);
}
/**
* Returns additional data for the SASL layer or <code>null</code>.
*
* @return additional data or <code>null</code>
*/
public String getData() {
return data;
}
@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket();
xml.optAppend(data);
xml.closeElement(ELEMENT);
return xml;
}
@Override
public String getNamespace() {
return NAMESPACE;
}
@Override
public String getElementName() {
return ELEMENT;
}
}
/**
* A SASL failure stream element, also called "SASL Error".
* @see <a href="http://xmpp.org/rfcs/rfc6120.html#sasl-errors">RFC 6120 6.5 SASL Errors</a>
*/
public static class SASLFailure extends AbstractError implements Nonza {
public static final String ELEMENT = "failure";
private final SASLError saslError;
private final String saslErrorString;
public SASLFailure(String saslError) {
this(saslError, null);
}
public SASLFailure(String saslError, Map<String, String> descriptiveTexts) {
super(descriptiveTexts);
SASLError error = SASLError.fromString(saslError);
if (error == null) {
// RFC6120 6.5 states that unknown condition must be treat as generic authentication
// failure.
this.saslError = SASLError.not_authorized;
}
else {
this.saslError = error;
}
this.saslErrorString = saslError;
}
/**
* Get the SASL related error condition.
*
* @return the SASL related error condition.
*/
public SASLError getSASLError() {
return saslError;
}
/**
* Get the SASL error as String.
* @return the SASL error as String
*/
public String getSASLErrorString() {
return saslErrorString;
}
@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket();
xml.emptyElement(saslErrorString);
addDescriptiveTextsAndExtensions(xml);
xml.closeElement(ELEMENT);
return xml;
}
@Override
public String toString() {
return toXML(null).toString();
}
@Override
public String getNamespace() {
return NAMESPACE;
}
@Override
public String getElementName() {
return ELEMENT;
}
}
}