Java Code Examples for org.xmpp.packet.StreamError

The following examples show how to use org.xmpp.packet.StreamError. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source Project: Openfire   Author: igniterealtime   File: XmppWebSocket.java    License: Apache License 2.0 6 votes vote down vote up
private void closeStream(StreamError streamError)
{
    if (isWebSocketOpen()) {

        if (streamError != null) {
            deliver(streamError.toXML());
        }

        StringBuilder sb = new StringBuilder(250);
        sb.append("<close ");
        sb.append("xmlns='").append(FRAMING_NAMESPACE).append("'");
        sb.append("/>");
        deliver(sb.toString());
        closeWebSocket();
    }
}
 
Example #2
Source Project: Openfire   Author: igniterealtime   File: LocalConnectionMultiplexerSession.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Authenticates the connection manager. Shared secret is validated with the one provided
 * by the connection manager. If everything went fine then the session will have a status
 * of "authenticated" and the connection manager will receive the client configuration
 * options.
 *
 * @param digest the digest provided by the connection manager with the handshake stanza.
 * @return true if the connection manager was sucessfully authenticated.
 */
public boolean authenticate(String digest) {
    // Perform authentication. Wait for the handshake (with the secret key)
    String anticipatedDigest = AuthFactory.createDigest(getStreamID().getID(),
            ConnectionMultiplexerManager.getDefaultSecret());
    // Check that the provided handshake (secret key + sessionID) is correct
    if (!anticipatedDigest.equalsIgnoreCase(digest)) {
        Log.debug("LocalConnectionMultiplexerSession: [ConMng] Incorrect handshake for connection manager with domain: " +
                getAddress().getDomain());
        //  The credentials supplied by the initiator are not valid (answer an error
        // and close the connection)
        conn.deliverRawText(new StreamError(StreamError.Condition.not_authorized).toXML());
        // Close the underlying connection
        conn.close();
        return false;
    }
    else {
        // Component has authenticated fine
        setStatus(STATUS_AUTHENTICATED);
        // Send empty handshake element to acknowledge success
        conn.deliverRawText("<handshake></handshake>");
        Log.debug("LocalConnectionMultiplexerSession: [ConMng] Connection manager was AUTHENTICATED with domain: " + getAddress());
        sendClientOptions();
        return true;
    }
}
 
Example #3
Source Project: Openfire   Author: igniterealtime   File: XmppWebSocket.java    License: Apache License 2.0 5 votes vote down vote up
@OnWebSocketError
public void onError(Throwable error)
{
    Log.error("Error detected; session: " + wsSession, error);
    closeStream(new StreamError(StreamError.Condition.internal_server_error));
    try {
        if (wsSession != null) {
            wsSession.disconnect();
        }
    } catch ( Exception e ) {
        Log.error("Error disconnecting websocket", e);
    }
}
 
Example #4
Source Project: Openfire   Author: igniterealtime   File: SocketReader.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Close the connection since TLS was mandatory and the entity never negotiated TLS. Before
 * closing the connection a stream error will be sent to the entity.
 */
void closeNeverSecuredConnection() {
    // Set the not_authorized error
    StreamError error = new StreamError(StreamError.Condition.not_authorized);
    // Deliver stanza
    connection.deliverRawText(error.toXML());
    // Close the underlying connection
    connection.close();
    // Log a warning so that admins can track this case from the server side
    Log.warn("TLS was required by the server and connection was never secured. " +
            "Closing connection : " + connection);
}
 
Example #5
Source Project: Openfire   Author: igniterealtime   File: XmppWebSocket.java    License: Apache License 2.0 4 votes vote down vote up
private void processStanza(Element stanza) {

        try {
            String tag = stanza.getName();
            if (STREAM_FOOTER.equals(tag)) {
                xmppSession.getStreamManager().formalClose();
                closeStream(null);
            } else if ("auth".equals(tag)) {
                // User is trying to authenticate using SASL
                startedSASL = true;
                // Process authentication stanza
                xmppSession.incrementClientPacketCount();
                saslStatus = SASLAuthentication.handle(xmppSession, stanza);
            } else if (startedSASL && "response".equals(tag) || "abort".equals(tag)) {
                // User is responding to SASL challenge. Process response
                xmppSession.incrementClientPacketCount();
                saslStatus = SASLAuthentication.handle(xmppSession, stanza);
            } else if (STREAM_HEADER.equals(tag)) {
                // restart the stream
                openStream(stanza.attributeValue(QName.get("lang", XMLConstants.XML_NS_URI), "en"), stanza.attributeValue("from"));
                configureStream();
            } else if (Status.authenticated.equals(saslStatus)) {
                if (router == null) {
                    if (StreamManager.isStreamManagementActive()) {
                        router = new StreamManagementPacketRouter(xmppSession);
                    } else {
                        // fall back for older Openfire installations
                        router = new SessionPacketRouter(xmppSession);
                    }
                }
                router.route(stanza);
            } else {
                // require authentication
                Log.warn("Not authorized: " + stanza.asXML());
                sendPacketError(stanza, PacketError.Condition.not_authorized);
            }
        } catch (UnknownStanzaException use) {
            Log.warn("Received invalid stanza: " + stanza.asXML());
            sendPacketError(stanza, PacketError.Condition.bad_request);
        } catch (Exception ex) {
            Log.error("Failed to process incoming stanza: " + stanza.asXML(), ex);
            closeStream(new StreamError(StreamError.Condition.internal_server_error));
        }
    }
 
Example #6
Source Project: Openfire   Author: igniterealtime   File: WebSocketConnection.java    License: Apache License 2.0 4 votes vote down vote up
@Override
public void systemShutdown() {
    deliverRawText(new StreamError(StreamError.Condition.system_shutdown).toXML());
    close();
}
 
Example #7
Source Project: Openfire   Author: igniterealtime   File: LocalComponentSession.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Authenticate the external component using a digest method. The digest includes the
 * stream ID and the secret key of the main domain of the external component. A component
 * needs to authenticate just once but it may bind several domains.
 *
 * @param digest the digest sent in the handshake.
 * @return true if the authentication was successful.
 */
public boolean authenticate(String digest) {
    // Perform authentication. Wait for the handshake (with the secret key)
    String secretKey = ExternalComponentManager.getSecretForComponent(defaultSubdomain);
    String anticipatedDigest = AuthFactory.createDigest(getStreamID().getID(), secretKey);
    // Check that the provided handshake (secret key + sessionID) is correct
    if (!anticipatedDigest.equalsIgnoreCase(digest)) {
        Log.debug("LocalComponentSession: [ExComp] Incorrect handshake for component with domain: " +
                defaultSubdomain);
        //  The credentials supplied by the initiator are not valid (answer an error
        // and close the connection)
        conn.deliverRawText(new StreamError(StreamError.Condition.not_authorized).toXML());
        // Close the underlying connection
        conn.close();
        return false;
    }
    else {
        // Component has authenticated fine
        setStatus(STATUS_AUTHENTICATED);
        // Send empty handshake element to acknowledge success
        conn.deliverRawText("<handshake></handshake>");
        // Bind the domain to this component
        ExternalComponent component = getExternalComponent();
        try {
            InternalComponentManager.getInstance().addComponent(defaultSubdomain, component);
            conn.registerCloseListener( handback -> InternalComponentManager.getInstance().removeComponent( defaultSubdomain, (ExternalComponent) handback ), component );
            Log.debug(
                    "LocalComponentSession: [ExComp] External component was registered SUCCESSFULLY with domain: " +
                            defaultSubdomain);
            return true;
        }
        catch (ComponentException e) {
            Log.debug("LocalComponentSession: [ExComp] Another component is already using domain: " +
                    defaultSubdomain);
            //  The credentials supplied by the initiator are not valid (answer an error
            // and close the connection)
            conn.deliverRawText(new StreamError(StreamError.Condition.conflict).toXML());
            // Close the underlying connection
            conn.close();
            return false;
        }
    }
}
 
Example #8
Source Project: Openfire   Author: igniterealtime   File: ServerDialback.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Returns a new {@link IncomingServerSession} with a domain validated by the Authoritative
 * Server. New domains may be added to the returned IncomingServerSession after they have
 * been validated. See
 * {@link LocalIncomingServerSession#validateSubsequentDomain(org.dom4j.Element)}. The remote
 * server will be able to send packets through this session whose domains were previously
 * validated.<p>
 *
 * When acting as an Authoritative Server this method will verify the requested key
 * and will return null since the underlying TCP connection will be closed after sending the
 * response to the Receiving Server.<p>
 *
 * @param reader reader of DOM documents on the connection to the remote server.
 * @return an IncomingServerSession that was previously validated against the remote server.
 * @throws IOException if an I/O error occurs while communicating with the remote server.
 * @throws XmlPullParserException if an error occurs while parsing XML packets.
 */
public LocalIncomingServerSession createIncomingSession(XMPPPacketReader reader) throws IOException,
        XmlPullParserException {
    XmlPullParser xpp = reader.getXPPParser();
    StringBuilder sb;
    if ("jabber:server:dialback".equals(xpp.getNamespace("db"))) {
        Log.debug("ServerDialback: Processing incoming session.");

        StreamID streamID = sessionManager.nextStreamID();

        sb = new StringBuilder();
        sb.append("<stream:stream");
        sb.append(" xmlns:stream=\"http://etherx.jabber.org/streams\"");
        sb.append(" xmlns=\"jabber:server\" xmlns:db=\"jabber:server:dialback\"");
        sb.append(" id=\"");
        sb.append(streamID.toString());
        sb.append("\">");
        connection.deliverRawText(sb.toString());

        try {
            Element doc = reader.parseDocument().getRootElement();
            if ("db".equals(doc.getNamespacePrefix()) && "result".equals(doc.getName())) {
                String hostname = doc.attributeValue("from");
                String recipient = doc.attributeValue("to");
                Log.debug("ServerDialback: RS - Validating remote domain for incoming session from {} to {}", hostname, recipient);
                if (validateRemoteDomain(doc, streamID)) {
                    Log.debug("ServerDialback: RS - Validation of remote domain for incoming session from {} to {} was successful.", hostname, recipient);
                    // Create a server Session for the remote server
                    LocalIncomingServerSession session = sessionManager.
                            createIncomingServerSession(connection, streamID, hostname);
                    // Add the validated domain as a valid domain
                    session.addValidatedDomain(hostname);
                    // Set the domain or subdomain of the local server used when
                    // validating the session
                    session.setLocalDomain(recipient);
                    // After the session has been created, inform all listeners as well.
                    ServerSessionEventDispatcher.dispatchEvent(session, ServerSessionEventDispatcher.EventType.session_created);
                    return session;
                } else {
                    Log.debug("ServerDialback: RS - Validation of remote domain for incoming session from {} to {} was not successful.", hostname, recipient);
                    return null;
                }
            }
            else if ("db".equals(doc.getNamespacePrefix()) && "verify".equals(doc.getName())) {
                // When acting as an Authoritative Server the Receiving Server will send a
                // db:verify packet for verifying a key that was previously sent by this
                // server when acting as the Originating Server
                verifyReceivedKey(doc, connection);
                // Close the underlying connection
                connection.close();
                String verifyFROM = doc.attributeValue("from");
                String id = doc.attributeValue("id");
                Log.debug("ServerDialback: AS - Connection closed for host: " + verifyFROM + " id: " + id);
                return null;
            }
            else {
                Log.debug("ServerDialback: Received an invalid/unknown packet while trying to process an incoming session: {}", doc.asXML());
                // The remote server sent an invalid/unknown packet
                connection.deliverRawText(
                        new StreamError(StreamError.Condition.invalid_xml).toXML());
                // Close the underlying connection
                connection.close();
                return null;
            }
        }
        catch (Exception e) {
            Log.error("An error occured while creating a server session", e);
            // Close the underlying connection
            connection.close();
            return null;
        }

    }
    else {
        Log.debug("ServerDialback: Received a stanza in an invalid namespace while trying to process an incoming session: {}", xpp.getNamespace("db"));
        connection.deliverRawText(
                new StreamError(StreamError.Condition.invalid_namespace).toXML());
        // Close the underlying connection
        connection.close();
        return null;
    }
}
 
Example #9
Source Project: Openfire   Author: igniterealtime   File: BlockingReadingMode.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Read the incoming stream until it ends.
 */
private void readStream() throws Exception {
    socketReader.open = true;
    while (socketReader.open) {
        Element doc = socketReader.reader.parseDocument().getRootElement();
        if (doc == null) {
            // Stop reading the stream since the client has sent an end of
            // stream element and probably closed the connection.
            return;
        }
        String tag = doc.getName();
        if ("starttls".equals(tag)) {
            // Negotiate TLS
            if (negotiateTLS()) {
                tlsNegotiated();
            }
            else {
                socketReader.open = false;
                socketReader.session = null;
            }
        }
        else if ("auth".equals(tag)) {
            // User is trying to authenticate using SASL
            if (authenticateClient(doc)) {
                // SASL authentication was successful so open a new stream and offer
                // resource binding and session establishment (to client sessions only)
                saslSuccessful();
            }
            else if (socketReader.connection.isClosed()) {
                socketReader.open = false;
                socketReader.session = null;
            }
        }
        else if ("error".equals(tag)) {
            try {
                final StreamError error = new StreamError( doc );
                Log.info( "Peer '{}' sent a stream error: '{}'{}. Closing connection.", socketReader.session != null ? socketReader.session.getAddress() : "(unknown)", error.getCondition().toXMPP(), error.getText() != null ? " ('" + error.getText() +"')" : "" );
            } catch ( Exception e ) {
                Log.debug( "An unexpected exception occurred while trying to parse a stream error.", e );
            } finally {
                if ( socketReader.session != null ) {
                    socketReader.session.close();
                    socketReader.session = null;
                }
                socketReader.open = false;
            }
        }
        else if ("compress".equals(tag))
        {
            // Client is trying to initiate compression
            if (compressClient(doc)) {
                // Compression was successful so open a new stream and offer
                // resource binding and session establishment (to client sessions only)
                compressionSuccessful();
            }
        }
        else {
            socketReader.process(doc);
        }
    }
}