1 20 21 package org.jivesoftware.smack; 22 23 import org.jivesoftware.smack.filter.PacketIDFilter; 24 import org.jivesoftware.smack.packet.Bind; 25 import org.jivesoftware.smack.packet.IQ; 26 import org.jivesoftware.smack.packet.Session; 27 import org.jivesoftware.smack.sasl.SASLMechanism; 28 import org.jivesoftware.smack.sasl.SASLPlainMechanism; 29 30 import java.io.IOException ; 31 import java.lang.reflect.Constructor ; 32 import java.util.*; 33 34 59 public class SASLAuthentication implements UserAuthentication { 60 61 private static Map implementedMechanisms = new HashMap(); 62 private static List mechanismsPreferences = new ArrayList(); 63 64 private XMPPConnection connection; 65 private Collection serverMechanisms = new ArrayList(); 66 private SASLMechanism currentMechanism = null; 67 70 private boolean saslNegotiated = false; 71 private boolean sessionSupported = false; 72 73 static { 74 registerSASLMechanism(0, "PLAIN", SASLPlainMechanism.class); 76 } 77 78 90 public static void registerSASLMechanism(int index, String name, Class mClass) { 91 implementedMechanisms.put(name, mClass); 92 mechanismsPreferences.add(index, name); 93 } 94 95 101 public static void unregisterSASLMechanism(String name) { 102 implementedMechanisms.remove(name); 103 mechanismsPreferences.remove(name); 104 } 105 106 111 public static List getRegisterSASLMechanisms() { 112 List answer = new ArrayList(); 113 for (Iterator it = mechanismsPreferences.iterator(); it.hasNext();) { 114 answer.add(implementedMechanisms.get(it.next())); 115 } 116 return answer; 117 } 118 119 SASLAuthentication(XMPPConnection connection) { 120 super(); 121 this.connection = connection; 122 } 123 124 public String authenticate(String username, String password, String resource) 125 throws XMPPException { 126 Class selected = null; 128 for (Iterator it = mechanismsPreferences.iterator(); it.hasNext();) { 129 String mechanism = (String ) it.next(); 130 if (implementedMechanisms.containsKey(mechanism) && 131 serverMechanisms.contains(mechanism)) { 132 selected = (Class ) implementedMechanisms.get(mechanism); 133 break; 134 } 135 } 136 if (selected != null) { 137 try { 140 Constructor constructor = selected 141 .getConstructor(new Class []{SASLAuthentication.class}); 142 currentMechanism = (SASLMechanism) constructor.newInstance(new Object []{this}); 143 currentMechanism.authenticate(username, connection.getServiceName(), password); 145 146 synchronized (this) { 148 try { 149 wait(30000); 150 } catch (InterruptedException e) { 151 } 152 } 153 154 if (saslNegotiated) { 155 connection.packetWriter.openStream(); 158 159 synchronized (this) { 161 try { 162 wait(30000); 163 } catch (InterruptedException e) { 164 } 165 } 166 167 Bind bindResource = new Bind(); 168 bindResource.setResource(resource); 169 170 PacketCollector collector = connection 171 .createPacketCollector(new PacketIDFilter(bindResource.getPacketID())); 172 connection.sendPacket(bindResource); 174 Bind response = (Bind) collector 176 .nextResult(SmackConfiguration.getPacketReplyTimeout()); 177 collector.cancel(); 178 if (response == null) { 179 throw new XMPPException("No response from the server."); 180 } 181 else if (response.getType() == IQ.Type.ERROR) { 183 throw new XMPPException(response.getError()); 184 } 185 String userJID = response.getJid(); 186 187 if (sessionSupported) { 188 Session session = new Session(); 189 collector = connection 190 .createPacketCollector(new PacketIDFilter(session.getPacketID())); 191 connection.sendPacket(session); 193 IQ ack = (IQ) collector 195 .nextResult(SmackConfiguration.getPacketReplyTimeout()); 196 collector.cancel(); 197 if (ack == null) { 198 throw new XMPPException("No response from the server."); 199 } 200 else if (ack.getType() == IQ.Type.ERROR) { 202 throw new XMPPException(ack.getError()); 203 } 204 } 205 return userJID; 206 } else { 207 return new NonSASLAuthentication(connection) 209 .authenticate(username, password, resource); 210 } 211 212 } catch (Exception e) { 213 e.printStackTrace(); 214 return new NonSASLAuthentication(connection) 216 .authenticate(username, password, resource); 217 } 218 } else { 219 return new NonSASLAuthentication(connection).authenticate(username, password, resource); 221 } 222 } 223 224 232 void setAvailableSASLMethods(Collection mechanisms) { 233 this.serverMechanisms = mechanisms; 234 } 235 236 245 void challengeReceived(String challenge) throws IOException { 246 currentMechanism.challengeReceived(challenge); 247 } 248 249 253 void authenticated() { 254 saslNegotiated = true; 255 synchronized (this) { 256 notify(); 258 } 259 } 260 261 265 void bindingRequired() { 266 synchronized (this) { 267 notify(); 269 } 270 } 271 272 public void send(String stanza) throws IOException { 273 connection.writer.write(stanza); 274 connection.writer.flush(); 275 } 276 277 282 void sessionsSupported() { 283 sessionSupported = true; 284 } 285 } 286 | Popular Tags |