1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $RCSfile$ 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Revision$ 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Date$ 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2003-2007 Jive Software. 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License. 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * http://www.apache.org/licenses/LICENSE-2.0 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS, 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License. 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smack.sasl; 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.XMPPException; 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.SASLAuthentication; 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Packet; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.util.StringUtils; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.IOException; 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Map; 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.HashMap; 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.CallbackHandler; 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.UnsupportedCallbackException; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.Callback; 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.NameCallback; 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.PasswordCallback; 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.sasl.RealmCallback; 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.sasl.RealmChoiceCallback; 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport de.measite.smack.Sasl; 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.sasl.SaslClient; 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.sasl.SaslException; 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Base class for SASL mechanisms. Subclasses must implement these methods: 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <ul> 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>{@link #getName()} -- returns the common name of the SASL mechanism.</li> 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * </ul> 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Subclasses will likely want to implement their own versions of these mthods: 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>{@link #authenticate(String, String, String)} -- Initiate authentication stanza using the 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * deprecated method.</li> 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>{@link #authenticate(String, String, CallbackHandler)} -- Initiate authentication stanza 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * using the CallbackHandler method.</li> 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>{@link #challengeReceived(String)} -- Handle a challenge from the server.</li> 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * </ul> 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Jay Kline 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic abstract class SASLMechanism implements CallbackHandler { 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private SASLAuthentication saslAuthentication; 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected SaslClient sc; 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected String authenticationId; 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected String password; 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected String hostname; 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public SASLMechanism(SASLAuthentication saslAuthentication) { 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.saslAuthentication = saslAuthentication; 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * authentication is not recommended, since it is very inflexable. Use 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link #authenticate(String, String, CallbackHandler)} whenever possible. 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param username the username of the user being authenticated. 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param host the hostname where the user account resides. 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param password the password for this account. 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IOException If a network error occurs while authenticating. 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If a protocol error occurs or the user is not authenticated. 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void authenticate(String username, String host, String password) throws IOException, XMPPException { 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen //Since we were not provided with a CallbackHandler, we will use our own with the given 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen //information 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen //Set the authenticationID as the username, since they must be the same in this case. 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.authenticationId = username; 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.password = password; 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.hostname = host; 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String[] mechanisms = { getName() }; 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Map<String,String> props = new HashMap<String,String>(); 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this); 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen authenticate(); 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Builds and sends the <tt>auth</tt> stanza to the server. The callback handler will handle 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * any additional information, such as the authentication ID or realm, if it is needed. 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param username the username of the user being authenticated. 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param host the hostname where the user account resides. 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param cbh the CallbackHandler to obtain user information. 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IOException If a network error occures while authenticating. 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If a protocol error occurs or the user is not authenticated. 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException { 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String[] mechanisms = { getName() }; 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Map<String,String> props = new HashMap<String,String>(); 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh); 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen authenticate(); 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected void authenticate() throws IOException, XMPPException { 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String authenticationText = null; 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if(sc.hasInitialResponse()) { 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte[] response = sc.evaluateChallenge(new byte[0]); 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen authenticationText = StringUtils.encodeBase64(response, false); 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } catch (SaslException e) { 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("SASL authentication failed", e); 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Send the authentication to the server 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen getSASLAuthentication().send(new AuthMechanism(getName(), authenticationText)); 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The server is challenging the SASL mechanism for the stanza he just sent. Send a 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * response to the server's challenge. 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param challenge a base64 encoded string representing the challenge. 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IOException if an exception sending the response occurs. 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void challengeReceived(String challenge) throws IOException { 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte response[]; 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if(challenge != null) { 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response = sc.evaluateChallenge(StringUtils.decodeBase64(challenge)); 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response = sc.evaluateChallenge(new byte[0]); 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Packet responseStanza; 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (response == null) { 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen responseStanza = new Response(); 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen responseStanza = new Response(StringUtils.encodeBase64(response, false)); 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Send the authentication to the server 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen getSASLAuthentication().send(responseStanza); 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or GSSAPI. 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the common name of the SASL mechanism. 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected abstract String getName(); 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected SASLAuthentication getSASLAuthentication() { 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return saslAuthentication; 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = 0; i < callbacks.length; i++) { 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (callbacks[i] instanceof NameCallback) { 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen NameCallback ncb = (NameCallback)callbacks[i]; 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ncb.setName(authenticationId); 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if(callbacks[i] instanceof PasswordCallback) { 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PasswordCallback pcb = (PasswordCallback)callbacks[i]; 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen pcb.setPassword(password.toCharArray()); 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if(callbacks[i] instanceof RealmCallback) { 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RealmCallback rcb = (RealmCallback)callbacks[i]; 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen rcb.setText(hostname); 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if(callbacks[i] instanceof RealmChoiceCallback){ 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen //unused 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen //RealmChoiceCallback rccb = (RealmChoiceCallback)callbacks[i]; 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new UnsupportedCallbackException(callbacks[i]); 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Initiating SASL authentication by select a mechanism. 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public class AuthMechanism extends Packet { 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen final private String name; 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen final private String authenticationText; 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public AuthMechanism(String name, String authenticationText) { 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (name == null) { 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("SASL mechanism name shouldn't be null."); 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.name = name; 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.authenticationText = authenticationText; 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String toXML() { 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuilder stanza = new StringBuilder(); 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("<auth mechanism=\"").append(name); 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (authenticationText != null && 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen authenticationText.trim().length() > 0) { 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append(authenticationText); 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("</auth>"); 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return stanza.toString(); 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A SASL challenge stanza. 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static class Challenge extends Packet { 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen final private String data; 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Challenge(String data) { 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.data = data; 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String toXML() { 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuilder stanza = new StringBuilder(); 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (data != null && 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data.trim().length() > 0) { 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append(data); 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("</challenge>"); 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return stanza.toString(); 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A SASL response stanza. 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public class Response extends Packet { 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen final private String authenticationText; 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Response() { 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen authenticationText = null; 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Response(String authenticationText) { 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (authenticationText == null || authenticationText.trim().length() == 0) { 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.authenticationText = null; 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.authenticationText = authenticationText; 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String toXML() { 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuilder stanza = new StringBuilder(); 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (authenticationText != null) { 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append(authenticationText); 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("</response>"); 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return stanza.toString(); 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A SASL success stanza. 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static class Success extends Packet { 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen final private String data; 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Success(String data) { 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.data = data; 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String toXML() { 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuilder stanza = new StringBuilder(); 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (data != null && 285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data.trim().length() > 0) { 286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append(data); 287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("</success>"); 289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return stanza.toString(); 290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A SASL failure stanza. 295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static class Failure extends Packet { 297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen final private String condition; 298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Failure(String condition) { 300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.condition = condition; 301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Get the SASL related error condition. 305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the SASL related error condition. 307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getCondition() { 309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return condition; 310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String toXML() { 313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuilder stanza = new StringBuilder(); 314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (condition != null && 316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen condition.trim().length() > 0) { 317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("<").append(condition).append("/>"); 318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen stanza.append("</failure>"); 320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return stanza.toString(); 321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 324