1 11 12 package org.jivesoftware.messenger; 13 14 import org.jivesoftware.messenger.auth.AuthToken; 15 import org.jivesoftware.messenger.auth.UnauthorizedException; 16 import org.jivesoftware.messenger.user.User; 17 import org.jivesoftware.messenger.user.UserManager; 18 import org.jivesoftware.messenger.user.UserNotFoundException; 19 import org.jivesoftware.messenger.net.SocketConnection; 20 import org.jivesoftware.util.LocaleUtils; 21 import org.jivesoftware.util.Log; 22 import org.jivesoftware.util.JiveGlobals; 23 import org.xmpp.packet.JID; 24 import org.xmpp.packet.Packet; 25 import org.xmpp.packet.Presence; 26 import org.xmpp.packet.StreamError; 27 import org.dom4j.io.XPPPacketReader; 28 import org.xmlpull.v1.XmlPullParserException; 29 import org.xmlpull.v1.XmlPullParser; 30 31 import java.io.Writer ; 32 import java.io.IOException ; 33 import java.util.Map ; 34 import java.util.HashMap ; 35 import java.util.Iterator ; 36 import java.util.StringTokenizer ; 37 38 43 public class ClientSession extends Session { 44 45 private static final String ETHERX_NAMESPACE = "http://etherx.jabber.org/streams"; 46 private static final String FLASH_NAMESPACE = "http://www.jabber.com/streams/flash"; 47 private static final String TLS_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-tls"; 48 49 52 private static final int MAJOR_VERSION = 0; 53 private static final int MINOR_VERSION = 0; 54 55 62 private static Map <String ,String > allowedIPs = new HashMap <String ,String >(); 63 64 67 protected AuthToken authToken; 68 69 72 private boolean initialized; 73 74 81 private boolean offlineFloodStopped = false; 82 83 private Presence presence = null; 84 85 private int conflictCount = 0; 86 87 static { 88 String allowed = JiveGlobals.getProperty("xmpp.client.login.allowed", ""); 90 StringTokenizer tokens = new StringTokenizer (allowed, ", "); 91 while (tokens.hasMoreTokens()) { 92 String address = tokens.nextToken().trim(); 93 allowedIPs.put(address, ""); 94 } 95 } 96 97 107 public static Session createSession(String serverName, XPPPacketReader reader, 108 SocketConnection connection) throws XmlPullParserException, UnauthorizedException, 109 IOException 110 { 111 XmlPullParser xpp = reader.getXPPParser(); 112 113 boolean isFlashClient = xpp.getPrefix().equals("flash"); 114 connection.setFlashClient(isFlashClient); 115 116 if (!xpp.getName().equals("stream") && !isFlashClient) { 119 throw new XmlPullParserException( 120 LocaleUtils.getLocalizedString("admin.error.bad-stream")); 121 } 122 123 if (!xpp.getNamespace(xpp.getPrefix()).equals(ETHERX_NAMESPACE) && 124 !(isFlashClient && xpp.getNamespace(xpp.getPrefix()).equals(FLASH_NAMESPACE))) 125 { 126 throw new XmlPullParserException(LocaleUtils.getLocalizedString( 127 "admin.error.bad-namespace")); 128 } 129 130 if (!allowedIPs.isEmpty()) { 131 if (!allowedIPs.containsKey(connection.getInetAddress().getHostAddress())) { 134 byte[] address = connection.getInetAddress().getAddress(); 135 String range1 = (address[0] & 0xff) + "." + (address[1] & 0xff) + "." + 136 (address[2] & 0xff) + 137 ".*"; 138 String range2 = (address[0] & 0xff) + "." + (address[1] & 0xff) + ".*.*"; 139 String range3 = (address[0] & 0xff) + ".*.*.*"; 140 if (!allowedIPs.containsKey(range1) && !allowedIPs.containsKey(range2) && 141 !allowedIPs.containsKey(range3)) { 142 Log.debug("Closed connection to client attempting to connect from: " + 145 connection.getInetAddress().getHostAddress()); 146 StreamError error = new StreamError(StreamError.Condition.not_authorized); 148 StringBuilder sb = new StringBuilder (); 149 sb.append(error.toXML()); 150 connection.deliverRawText(sb.toString()); 151 connection.close(); 153 return null; 154 } 155 } 156 } 157 158 String language = "en"; 160 int majorVersion = 0; 164 int minorVersion = 0; 165 for (int i = 0; i < xpp.getAttributeCount(); i++) { 166 if ("lang".equals(xpp.getAttributeName(i))) { 167 language = xpp.getAttributeValue(i); 168 } 169 if ("version".equals(xpp.getAttributeName(i))) { 170 try { 171 String [] versionString = xpp.getAttributeValue(i).split("\\."); 172 majorVersion = Integer.parseInt(versionString[0]); 173 minorVersion = Integer.parseInt(versionString[1]); 174 } 175 catch (Exception e) { 176 Log.error(e); 177 } 178 } 179 } 180 181 if (majorVersion > MAJOR_VERSION) { 184 majorVersion = MAJOR_VERSION; 185 minorVersion = MINOR_VERSION; 186 } 187 else if (majorVersion == MAJOR_VERSION) { 188 if (minorVersion > MINOR_VERSION) { 192 minorVersion = MINOR_VERSION; 193 } 194 } 195 196 connection.setLanaguage(language); 198 connection.setXMPPVersion(majorVersion, minorVersion); 199 200 Session session = SessionManager.getInstance().createClientSession(connection); 202 203 Writer writer = connection.getWriter(); 204 StringBuilder sb = new StringBuilder (); 206 sb.append("<?xml version='1.0' encoding='"); 207 sb.append(CHARSET); 208 sb.append("'?>"); 209 if (isFlashClient) { 210 sb.append("<flash:stream xmlns:flash=\"http://www.jabber.com/streams/flash\" "); 211 } 212 else { 213 sb.append("<stream:stream "); 214 } 215 sb.append("xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\" from=\""); 216 sb.append(serverName); 217 sb.append("\" id=\""); 218 sb.append(session.getStreamID().toString()); 219 sb.append("\" xml:lang=\""); 220 sb.append(language); 221 if (majorVersion != 0) { 223 sb.append("\" version=\""); 224 sb.append(majorVersion).append(".").append(minorVersion); 225 } 226 sb.append("\">"); 227 writer.write(sb.toString()); 228 229 if (majorVersion == 0) { 232 if (isFlashClient) { 234 writer.write('\0'); 235 } 236 writer.flush(); 237 238 return session; 239 } 240 242 sb = new StringBuilder (); 243 sb.append("<stream:features>"); 244 sb.append("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\">"); 245 sb.append("</starttls></stream:features>"); 247 248 writer.write(sb.toString()); 249 250 if (isFlashClient) { 251 writer.write('\0'); 252 } 253 writer.flush(); 254 255 boolean done = false; 256 while (!done) { 257 if (xpp.next() == XmlPullParser.START_TAG) { 258 done = true; 259 if (xpp.getName().equals("starttls") && 260 xpp.getNamespace(xpp.getPrefix()).equals(TLS_NAMESPACE)) 261 { 262 writer.write("<proceed xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>"); 263 if (isFlashClient) { 264 writer.write('\0'); 265 } 266 writer.flush(); 267 268 } 270 } 271 } 272 273 return session; 274 } 275 276 282 public static Map <String , String > getAllowedIPs() { 283 return allowedIPs; 284 } 285 286 292 public static void setAllowedIPs(Map <String , String > allowed) { 293 allowedIPs = allowed; 294 if (allowedIPs.isEmpty()) { 295 JiveGlobals.deleteProperty("xmpp.client.login.allowed"); 296 } 297 else { 298 StringBuilder buf = new StringBuilder (); 300 Iterator <String > iter = allowedIPs.keySet().iterator(); 301 if (iter.hasNext()) { 302 buf.append(iter.next()); 303 } 304 while (iter.hasNext()) { 305 buf.append(", ").append((String )iter.next()); 306 } 307 JiveGlobals.setProperty("xmpp.client.login.allowed", buf.toString()); 308 } 309 } 310 311 316 public ClientSession(String serverName, Connection connection, StreamID streamID) { 317 super(serverName, connection, streamID); 318 presence = new Presence(); 320 presence.setType(Presence.Type.unavailable); 321 } 322 323 331 public String getUsername() throws UserNotFoundException { 332 if (authToken == null) { 333 throw new UserNotFoundException(); 334 } 335 return getAddress().getNode(); 336 } 337 338 339 349 public void setAuthToken(AuthToken auth, UserManager userManager, String resource) 350 throws UserNotFoundException 351 { 352 User user = userManager.getUser(auth.getUsername()); 353 setAddress(new JID(user.getUsername(), getServerName(), resource)); 354 authToken = auth; 355 356 sessionManager.addSession(this); 357 setStatus(Session.STATUS_AUTHENTICATED); 358 } 359 360 366 public void setAnonymousAuth() { 367 sessionManager.addAnonymousSession(this); 368 setStatus(Session.STATUS_AUTHENTICATED); 369 } 370 371 376 public AuthToken getAuthToken() { 377 return authToken; 378 } 379 380 390 public boolean isInitialized() { 391 return initialized; 392 } 393 394 400 public void setInitialized(boolean isInit) { 401 initialized = isInit; 402 } 403 404 414 public boolean canFloodOfflineMessages() { 415 for (ClientSession session : sessionManager.getSessions()) { 416 if (session.isOfflineFloodStopped()) { 417 return false; 418 } 419 } 420 return true; 421 } 422 423 433 public boolean isOfflineFloodStopped() { 434 return offlineFloodStopped; 435 } 436 437 447 public void setOfflineFloodStopped(boolean offlineFloodStopped) { 448 this.offlineFloodStopped = offlineFloodStopped; 449 } 450 451 456 public Presence getPresence() { 457 return presence; 458 } 459 460 466 public Presence setPresence(Presence presence) { 467 Presence oldPresence = this.presence; 468 this.presence = presence; 469 if (oldPresence.isAvailable() && !this.presence.isAvailable()) { 470 sessionManager.sessionUnavailable(this); 472 setInitialized(false); 476 } 477 else if (!oldPresence.isAvailable() && this.presence.isAvailable()) { 478 sessionManager.sessionAvailable(this); 480 } 481 else if (oldPresence.getPriority() != this.presence.getPriority()) { 482 sessionManager.changePriority(getAddress(), this.presence.getPriority()); 484 } 485 return oldPresence; 486 } 487 488 499 public int getConflictCount() { 500 return conflictCount; 501 } 502 503 506 public void incrementConflictCount() { 507 conflictCount++; 508 } 509 510 public void process(Packet packet) { 511 deliver(packet); 512 } 513 514 private void deliver(Packet packet) { 515 if (conn != null && !conn.isClosed()) { 516 try { 517 conn.deliver(packet); 518 } 519 catch (Exception e) { 520 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 521 } 522 } 523 } 524 525 public String toString() { 526 return super.toString() + " presence: " + presence; 527 } 528 } 529 | Popular Tags |