/** * Creates a new client session that was established to the specified connection manager. The new * session will not be findable through its stream ID. * * @param connectionManagerDomain the connection manager that is handling the connection of the * session. * @param streamID the stream ID created by the connection manager for the new session. * @param hostName the address's hostname of the client or null if using old connection manager. * @param hostAddress the textual representation of the address of the client or null if using old * CM. * @return true if a session was created or false if the client should disconnect. */ public boolean createClientSession( String connectionManagerDomain, String streamID, String hostName, String hostAddress) { Connection connection = new ClientSessionConnection(connectionManagerDomain, hostName, hostAddress); // Check if client is allowed to connect from the specified IP address. Ignore the checking if // connection // manager is old version and is not passing client's address byte[] address = null; try { address = connection.getAddress(); } catch (UnknownHostException e) { // Ignore } if (address == null || LocalClientSession.isAllowed(connection)) { LocalClientSession session = SessionManager.getInstance().createClientSession(connection, new BasicStreamID(streamID)); // Register that this streamID belongs to the specified connection manager streamIDs.put(streamID, connectionManagerDomain); // Register which sessions are being hosted by the speicifed connection manager Map<String, LocalClientSession> sessions = sessionsByManager.get(connectionManagerDomain); if (sessions == null) { synchronized (connectionManagerDomain.intern()) { sessions = sessionsByManager.get(connectionManagerDomain); if (sessions == null) { sessions = new ConcurrentHashMap<>(); sessionsByManager.put(connectionManagerDomain, sessions); } } } sessions.put(streamID, session); return true; } return false; }
@Override boolean createSession( String namespace, String serverName, XmlPullParser xpp, Connection connection) throws XmlPullParserException { if ("jabber:client".equals(namespace)) { // The connected client is a regular client so create a ClientSession session = LocalClientSession.createSession(serverName, xpp, connection); return true; } return false; }
/** * Login to the XMPP server and establish a non-anonymous user session using the given username * and resource. When <tt>createIfNotExist</tt> is <tt>true</tt>, a new user with the username * will be created and stored in the database if it does not exist. When <tt>false</tt>, and the * user does not exist, the method will not attempt the login. Whenever there's an error, the bot * will not login. * * @param username Username to login with. * @param resource The resource the user will bind to. * @param createIfNotExist When specified as <tt>true</tt>, a new user will be created and stored * in the database if it does not exist. * @throws SessionAlreadyExistsException If the bot's session already exists. * @throws UserNotFoundException If it fails to create the user. */ public void login(String username, String resource, boolean createIfNotExist) throws SessionAlreadyExistsException, UserNotFoundException { LOGGER.debug("Bot login with username:{} with resource:{}", username, resource); if (isClosed()) throw new SessionAlreadyExistsException(); JID jid = new JID( username.toLowerCase(), XMPPServer.getInstance().getServerInfo().getXMPPDomain(), resource); ClientSession oldSession = SessionManager.getInstance().getSession(jid); // Check for session conflict if (oldSession != null) { try { int count = oldSession.incrementConflictCount(); int conflictLimit = SessionManager.getInstance().getConflictKickLimit(); if (conflictLimit != SessionManager.NEVER_KICK && count > conflictLimit) { // Kick out the old connection that is conflicting with the // new one StreamError error = new StreamError(StreamError.Condition.conflict); oldSession.deliverRawText(error.toXML()); oldSession.close(); } else throw new SessionAlreadyExistsException(); } catch (Exception e) { LOGGER.error("Error during login", e); } } if (!XMPPServer.getInstance().getUserManager().isRegisteredUser(jid.getNode())) { if (createIfNotExist) { try { // Bot doesn't care of whatever password it is. XMPPServer.getInstance() .getUserManager() .createUser(jid.getNode(), StringUtils.randomString(15), null, null); } catch (UserAlreadyExistsException e) { // Ignore } } else { throw new UserNotFoundException(); } } localClientSession = SessionManager.getInstance().createClientSession(this); localClientSession.setAuthToken(new AuthToken(jid.getNode()), jid.getResource()); if (packetProcessor != null) { packetProcessor.initialize(this); initProcessor = true; } }
private void updateClearspaceClientSettings() { String xmppBoshSslPort = "0"; String xmppBoshPort = "0"; String xmppPort = String.valueOf(XMPPServer.getInstance().getConnectionManager().getClientListenerPort()); if (JiveGlobals.getBooleanProperty( HttpBindManager.HTTP_BIND_ENABLED, HttpBindManager.HTTP_BIND_ENABLED_DEFAULT)) { int boshSslPort = HttpBindManager.getInstance().getHttpBindSecurePort(); int boshPort = HttpBindManager.getInstance().getHttpBindUnsecurePort(); try { if (HttpBindManager.getInstance().isHttpsBindActive() && LocalClientSession.getTLSPolicy() != org.jivesoftware.openfire.Connection.TLSPolicy.disabled) { xmppBoshSslPort = String.valueOf(boshSslPort); } } catch (Exception e) { // Exception while working with certificate Log.debug( "Error while checking SSL certificate. Instructing Clearspace not to use SSL port."); } if (HttpBindManager.getInstance().isHttpBindActive() && boshPort > 0) { xmppBoshPort = String.valueOf(boshPort); } } try { String path = CHAT_URL_PREFIX + "updateClientSettings/"; // Creates the XML with the data Document groupDoc = DocumentHelper.createDocument(); Element rootE = groupDoc.addElement("updateClientSettings"); rootE.addElement("boshSslPort").setText(xmppBoshSslPort); rootE.addElement("boshPort").setText(xmppBoshPort); rootE.addElement("tcpPort").setText(xmppPort); executeRequest(POST, path, groupDoc.asXML()); } catch (UnauthorizedException ue) { Log.error("Error updating the client settings of Clearspace", ue); } catch (Exception e) { Log.error("Error updating the client settings of Clearspace", e); } }
/** * Returns a newly created session between the server and a client. The session will be created * and returned only if correct name/prefix (i.e. 'stream' or 'flash') and namespace were provided * by the client. * * @param serverName the name of the server where the session is connecting to. * @param xpp the parser that is reading the provided XML through the connection. * @param connection the connection with the client. * @return a newly created session between the server and a client. * @throws org.xmlpull.v1.XmlPullParserException if an error occurs while parsing incoming data. */ public static LocalClientSession createSession( String serverName, XmlPullParser xpp, Connection connection) throws XmlPullParserException { boolean isFlashClient = xpp.getPrefix().equals("flash"); connection.setFlashClient(isFlashClient); // Conduct error checking, the opening tag should be 'stream' // in the 'etherx' namespace if (!xpp.getName().equals("stream") && !isFlashClient) { throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.bad-stream")); } if (!xpp.getNamespace(xpp.getPrefix()).equals(ETHERX_NAMESPACE) && !(isFlashClient && xpp.getNamespace(xpp.getPrefix()).equals(FLASH_NAMESPACE))) { throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.bad-namespace")); } if (!allowedIPs.isEmpty()) { String hostAddress = "Unknown"; // The server is using a whitelist so check that the IP address of the client // is authorized to connect to the server try { hostAddress = connection.getHostAddress(); } catch (UnknownHostException e) { // Do nothing } if (!isAllowed(connection)) { // Client cannot connect from this IP address so end the stream and // TCP connection Log.debug( "LocalClientSession: Closed connection to client attempting to connect from: " + hostAddress); // Include the not-authorized error in the response StreamError error = new StreamError(StreamError.Condition.not_authorized); connection.deliverRawText(error.toXML()); // Close the underlying connection connection.close(); return null; } } // Default language is English ("en"). String language = "en"; // Default to a version of "0.0". Clients written before the XMPP 1.0 spec may // not report a version in which case "0.0" should be assumed (per rfc3920 // section 4.4.1). int majorVersion = 0; int minorVersion = 0; for (int i = 0; i < xpp.getAttributeCount(); i++) { if ("lang".equals(xpp.getAttributeName(i))) { language = xpp.getAttributeValue(i); } if ("version".equals(xpp.getAttributeName(i))) { try { int[] version = decodeVersion(xpp.getAttributeValue(i)); majorVersion = version[0]; minorVersion = version[1]; } catch (Exception e) { Log.error(e.getMessage(), e); } } } // If the client supports a greater major version than the server, // set the version to the highest one the server supports. if (majorVersion > MAJOR_VERSION) { majorVersion = MAJOR_VERSION; minorVersion = MINOR_VERSION; } else if (majorVersion == MAJOR_VERSION) { // If the client supports a greater minor version than the // server, set the version to the highest one that the server // supports. if (minorVersion > MINOR_VERSION) { minorVersion = MINOR_VERSION; } } // Store language and version information in the connection. connection.setLanaguage(language); connection.setXMPPVersion(majorVersion, minorVersion); // Indicate the TLS policy to use for this connection if (!connection.isSecure()) { boolean hasCertificates = false; try { hasCertificates = SSLConfig.getKeyStore().size() > 0; } catch (Exception e) { Log.error(e.getMessage(), e); } Connection.TLSPolicy tlsPolicy = getTLSPolicy(); if (Connection.TLSPolicy.required == tlsPolicy && !hasCertificates) { Log.error( "Client session rejected. TLS is required but no certificates " + "were created."); return null; } // Set default TLS policy connection.setTlsPolicy(hasCertificates ? tlsPolicy : Connection.TLSPolicy.disabled); } else { // Set default TLS policy connection.setTlsPolicy(Connection.TLSPolicy.disabled); } // Indicate the compression policy to use for this connection connection.setCompressionPolicy(getCompressionPolicy()); // Create a ClientSession for this user. LocalClientSession session = SessionManager.getInstance().createClientSession(connection); // Build the start packet response StringBuilder sb = new StringBuilder(200); sb.append("<?xml version='1.0' encoding='"); sb.append(CHARSET); sb.append("'?>"); if (isFlashClient) { sb.append("<flash:stream xmlns:flash=\"http://www.jabber.com/streams/flash\" "); } else { sb.append("<stream:stream "); } sb.append("xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\" from=\""); sb.append(serverName); sb.append("\" id=\""); sb.append(session.getStreamID().toString()); sb.append("\" xml:lang=\""); sb.append(language); // Don't include version info if the version is 0.0. if (majorVersion != 0) { sb.append("\" version=\""); sb.append(majorVersion).append(".").append(minorVersion); } sb.append("\">"); connection.deliverRawText(sb.toString()); // If this is a "Jabber" connection, the session is now initialized and we can // return to allow normal packet parsing. if (majorVersion == 0) { return session; } // Otherwise, this is at least XMPP 1.0 so we need to announce stream features. sb = new StringBuilder(490); sb.append("<stream:features>"); if (connection.getTlsPolicy() != Connection.TLSPolicy.disabled) { sb.append("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\">"); if (connection.getTlsPolicy() == Connection.TLSPolicy.required) { sb.append("<required/>"); } sb.append("</starttls>"); } // Include available SASL Mechanisms sb.append(SASLAuthentication.getSASLMechanisms(session)); // Include Stream features String specificFeatures = session.getAvailableStreamFeatures(); if (specificFeatures != null) { sb.append(specificFeatures); } sb.append("</stream:features>"); connection.deliverRawText(sb.toString()); return session; }
/** * Get the node's portion of the bot's JID. * * @return Node portion of the bot's JID. */ public String getUsername() { if (localClientSession == null) return null; return localClientSession.getAddress().getNode(); }
/** * Get the resource portion of the bot's JID. * * @return Resource portion of the bot's JID. */ public String getResource() { if (localClientSession == null) return null; return localClientSession.getAddress().getResource(); }
private void stopOfflineFlooding(JID senderJID) { LocalClientSession session = (LocalClientSession) sessionManager.getSession(senderJID); if (session != null) { session.setOfflineFloodStopped(true); } }