Search in sources :

Example 6 with Connection

use of org.jivesoftware.openfire.Connection in project Openfire by igniterealtime.

the class ConnectionHandler method exceptionCaught.

@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
    Log.warn("Closing connection due to exception in session: " + session, cause);
    try {
        // OF-524: Determine stream:error message.
        final StreamError error;
        if (cause != null && (cause instanceof XMLNotWellFormedException || (cause.getCause() != null && cause.getCause() instanceof XMLNotWellFormedException))) {
            error = new StreamError(StreamError.Condition.not_well_formed);
        } else {
            error = new StreamError(StreamError.Condition.internal_server_error);
        }
        final Connection connection = (Connection) session.getAttribute(CONNECTION);
        connection.deliverRawText(error.toXML());
    } finally {
        final Connection connection = (Connection) session.getAttribute(CONNECTION);
        if (connection != null) {
            connection.close();
        }
    }
}
Also used : StreamError(org.xmpp.packet.StreamError) Connection(org.jivesoftware.openfire.Connection)

Example 7 with Connection

use of org.jivesoftware.openfire.Connection in project Openfire by igniterealtime.

the class LocalClientSession method createSession.

/**
     * 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);
    // 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 (!isAllowed(connection)) {
        // Client cannot connect from this IP address so end the stream and TCP connection.
        String hostAddress = "Unknown";
        try {
            hostAddress = connection.getHostAddress();
        } catch (UnknownHostException e) {
        // Do nothing
        }
        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").
    Locale language = Locale.forLanguageTag("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 = Locale.forLanguageTag(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);
            }
        }
    }
    // 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) {
        // supports.
        if (minorVersion > MINOR_VERSION) {
            minorVersion = MINOR_VERSION;
        }
    }
    connection.setXMPPVersion(majorVersion, minorVersion);
    final ConnectionConfiguration connectionConfiguration = connection.getConfiguration();
    // Indicate the TLS policy to use for this connection
    if (!connection.isSecure()) {
        boolean hasCertificates = false;
        try {
            hasCertificates = connectionConfiguration.getIdentityStore().getAllCertificates().size() > 0;
        } catch (Exception e) {
            Log.error(e.getMessage(), e);
        }
        Connection.TLSPolicy tlsPolicy = connectionConfiguration.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(connectionConfiguration.getCompressionPolicy());
    // Create a ClientSession for this user.
    LocalClientSession session = SessionManager.getInstance().createClientSession(connection, language);
    // 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.toLanguageTag());
    // 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());
    // 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;
}
Also used : UnknownHostException(java.net.UnknownHostException) Connection(org.jivesoftware.openfire.Connection) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) UnknownHostException(java.net.UnknownHostException) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) StreamError(org.xmpp.packet.StreamError) ConnectionConfiguration(org.jivesoftware.openfire.spi.ConnectionConfiguration) XmlPullParserException(org.xmlpull.v1.XmlPullParserException)

Example 8 with Connection

use of org.jivesoftware.openfire.Connection in project Openfire by igniterealtime.

the class LocalIncomingServerSession method createSession.

/**
     * Creates a new session that will receive packets. The new session will be authenticated
     * before being returned. If the authentication process fails then the answer will be
     * <tt>null</tt>.<p>
     *
     * @param serverName hostname of this server.
     * @param reader reader on the new established connection with the remote server.
     * @param connection the new established connection with the remote server.
     * @return a new session that will receive packets or null if a problem occured while
     *         authenticating the remote server or when acting as the Authoritative Server during
     *         a Server Dialback authentication process.
     * @throws org.xmlpull.v1.XmlPullParserException if an error occurs while parsing the XML.
     * @throws java.io.IOException if an input/output error occurs while using the connection.
     */
public static LocalIncomingServerSession createSession(String serverName, XMPPPacketReader reader, SocketConnection connection) throws XmlPullParserException, IOException {
    XmlPullParser xpp = reader.getXPPParser();
    String version = xpp.getAttributeValue("", "version");
    String fromDomain = xpp.getAttributeValue("", "from");
    String toDomain = xpp.getAttributeValue("", "to");
    int[] serverVersion = version != null ? decodeVersion(version) : new int[] { 0, 0 };
    if (toDomain == null) {
        toDomain = serverName;
    }
    try {
        // Get the stream ID for the new session
        StreamID streamID = SessionManager.getInstance().nextStreamID();
        // Create a server Session for the remote server
        LocalIncomingServerSession session = SessionManager.getInstance().createIncomingServerSession(connection, streamID, fromDomain);
        // Send the stream header
        StringBuilder openingStream = new StringBuilder();
        openingStream.append("<stream:stream");
        openingStream.append(" xmlns:db=\"jabber:server:dialback\"");
        openingStream.append(" xmlns:stream=\"http://etherx.jabber.org/streams\"");
        openingStream.append(" xmlns=\"jabber:server\"");
        openingStream.append(" from=\"").append(toDomain).append("\"");
        if (fromDomain != null) {
            openingStream.append(" to=\"").append(fromDomain).append("\"");
        }
        openingStream.append(" id=\"").append(streamID).append("\"");
        // implementations appears to reduce connection issues with those domains (patch by Marcin Cieślak).
        if (serverVersion[0] >= 1) {
            openingStream.append(" version=\"1.0\">");
        } else {
            openingStream.append('>');
        }
        connection.deliverRawText(openingStream.toString());
        if (serverVersion[0] >= 1) {
            // Remote server is XMPP 1.0 compliant so offer TLS and SASL to establish the connection (and server dialback)
            // Indicate the TLS policy to use for this connection
            Connection.TLSPolicy tlsPolicy = connection.getTlsPolicy();
            boolean hasCertificates = false;
            try {
                hasCertificates = XMPPServer.getInstance().getCertificateStoreManager().getIdentityStore(ConnectionType.SOCKET_S2S).getStore().size() > 0;
            } catch (Exception e) {
                Log.error(e.getMessage(), e);
            }
            if (Connection.TLSPolicy.required == tlsPolicy && !hasCertificates) {
                Log.error("Server session rejected. TLS is required but no certificates " + "were created.");
                return null;
            }
            connection.setTlsPolicy(hasCertificates ? tlsPolicy : Connection.TLSPolicy.disabled);
        }
        // Indicate the compression policy to use for this connection
        connection.setCompressionPolicy(connection.getConfiguration().getCompressionPolicy());
        StringBuilder sb = new StringBuilder();
        if (serverVersion[0] >= 1) {
            // Remote server is XMPP 1.0 compliant so offer TLS and SASL to establish the connection (and server dialback)
            // Don't offer stream-features to pre-1.0 servers, as it confuses them. Sending features to Openfire < 3.7.1 confuses it too - OF-443) 
            sb.append("<stream:features>");
            if (JiveGlobals.getBooleanProperty(ConnectionSettings.Server.TLS_ENABLED, true)) {
                sb.append("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\">");
                if (!ServerDialback.isEnabled()) {
                    // Server dialback is disabled so TLS is required
                    sb.append("<required/>");
                }
                sb.append("</starttls>");
            }
            // Include available SASL Mechanisms
            sb.append(SASLAuthentication.getSASLMechanisms(session));
            if (ServerDialback.isEnabled()) {
                // Also offer server dialback (when TLS is not required). Server dialback may be offered
                // after TLS has been negotiated and a self-signed certificate is being used
                sb.append("<dialback xmlns=\"urn:xmpp:features:dialback\"><errors/></dialback>");
            }
            sb.append("</stream:features>");
        }
        connection.deliverRawText(sb.toString());
        // Set the domain or subdomain of the local server targeted by the remote server
        session.setLocalDomain(serverName);
        return session;
    } catch (Exception e) {
        Log.error("Error establishing connection from remote server:" + connection, e);
        connection.close();
        return null;
    }
}
Also used : StreamID(org.jivesoftware.openfire.StreamID) XmlPullParser(org.xmlpull.v1.XmlPullParser) Connection(org.jivesoftware.openfire.Connection) SocketConnection(org.jivesoftware.openfire.net.SocketConnection) KeyStoreException(java.security.KeyStoreException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) IOException(java.io.IOException) XmlPullParserException(org.xmlpull.v1.XmlPullParserException)

Aggregations

Connection (org.jivesoftware.openfire.Connection)8 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)3 UnknownHostException (java.net.UnknownHostException)2 KeyStore (java.security.KeyStore)2 X509Certificate (java.security.cert.X509Certificate)2 StreamID (org.jivesoftware.openfire.StreamID)2 UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)2 StreamError (org.xmpp.packet.StreamError)2 IOException (java.io.IOException)1 KeyStoreException (java.security.KeyStoreException)1 Certificate (java.security.cert.Certificate)1 ArrayList (java.util.ArrayList)1 SaslException (javax.security.sasl.SaslException)1 Element (org.dom4j.Element)1 Namespace (org.dom4j.Namespace)1 QName (org.dom4j.QName)1 XMPPPacketReader (org.dom4j.io.XMPPPacketReader)1 ClientStanzaHandler (org.jivesoftware.openfire.net.ClientStanzaHandler)1 SocketConnection (org.jivesoftware.openfire.net.SocketConnection)1 StanzaHandler (org.jivesoftware.openfire.net.StanzaHandler)1