⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serverdialback.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

    /**
     * Authenticates the Originating Server domain with the Receiving Server. Once the domain has
     * been authenticated the Receiving Server will start accepting packets from the Originating
     * Server.<p>
     *
     * The Receiving Server will connect to the Authoritative Server to verify the dialback key.
     * Most probably the Originating Server machine will be the Authoritative Server too.
     *
     * @param socketReader the reader to use for reading the answer from the Receiving Server.
     * @param domain the domain to authenticate.
     * @param hostname the hostname of the remote server (i.e. Receiving Server).
     * @param id the stream id to be used for creating the dialback key.
     * @return true if the Receiving Server authenticated the domain with the Authoritative Server.
     */
    public boolean authenticateDomain(OutgoingServerSocketReader socketReader, String domain,
            String hostname, String id) {
        String key = AuthFactory.createDigest(id, getSecretkey());
        Log.debug("ServerDialback: OS - Sent dialback key to host: " + hostname + " id: " + id + " from domain: " +
                domain);

        synchronized (socketReader) {
            // Send a dialback key to the Receiving Server
            StringBuilder sb = new StringBuilder();
            sb.append("<db:result");
            sb.append(" from=\"").append(domain).append("\"");
            sb.append(" to=\"").append(hostname).append("\">");
            sb.append(key);
            sb.append("</db:result>");
            connection.deliverRawText(sb.toString());

            // Process the answer from the Receiving Server
            try {
                Element doc = socketReader.getElement(RemoteServerManager.getSocketTimeout(),
                        TimeUnit.MILLISECONDS);
                if (doc == null) {
                    Log.debug("ServerDialback: OS - Time out waiting for answer in validation from: " + hostname +
                            " id: " +
                            id +
                            " for domain: " +
                            domain);
                    return false;
                }
                else if ("db".equals(doc.getNamespacePrefix()) && "result".equals(doc.getName())) {
                    boolean success = "valid".equals(doc.attributeValue("type"));
                    Log.debug("ServerDialback: OS - Validation " + (success ? "GRANTED" : "FAILED") + " from: " +
                            hostname +
                            " id: " +
                            id +
                            " for domain: " +
                            domain);
                    return success;
                }
                else {
                    Log.debug("ServerDialback: OS - Unexpected answer in validation from: " + hostname + " id: " +
                            id +
                            " for domain: " +
                            domain +
                            " answer:" +
                            doc.asXML());
                    return false;
                }
            }
            catch (InterruptedException e) {
                Log.debug("ServerDialback: OS - Validation FAILED from: " + hostname +
                        " id: " +
                        id +
                        " for domain: " +
                        domain, e);
                return false;
            }
        }
    }

    /**
     * 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"))) {

            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())) {
                    if (validateRemoteDomain(doc, streamID)) {
                        String hostname = doc.attributeValue("from");
                        String recipient = doc.attributeValue("to");
                        // Create a server Session for the remote server
                        LocalIncomingServerSession session = sessionManager.
                                createIncomingServerSession(connection, streamID);
                        // Set the first validated domain as the address of the session
                        session.setAddress(new JID(null, hostname, null));
                        // 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);
                        return session;
                    }
                }
                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 {
                    // 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 {
            // Include the invalid-namespace stream error condition in the response
            connection.deliverRawText(
                    new StreamError(StreamError.Condition.invalid_namespace).toXML());
            // Close the underlying connection
            connection.close();
            return null;
        }
        return null;
    }

    /**
     * Returns true if the domain requested by the remote server was validated by the Authoritative
     * Server. To validate the domain a new TCP connection will be established to the
     * Authoritative Server. The Authoritative Server may be the same Originating Server or
     * some other machine in the Originating Server's network.<p>
     *
     * If the domain was not valid or some error occured while validating the domain then the
     * underlying TCP connection will be closed.
     *
     * @param doc the request for validating the new domain.
     * @param streamID the stream id generated by this server for the Originating Server.
     * @return true if the requested domain is valid.
     */
    public boolean validateRemoteDomain(Element doc, StreamID streamID) {
        StringBuilder sb;
        String recipient = doc.attributeValue("to");
        String hostname = doc.attributeValue("from");
        Log.debug("ServerDialback: RS - Received dialback key from host: " + hostname + " to: " + recipient);
        if (!RemoteServerManager.canAccess(hostname)) {
            // Remote server is not allowed to establish a connection to this server
            connection.deliverRawText(new StreamError(StreamError.Condition.host_unknown).toXML());
            // Close the underlying connection
            connection.close();
            Log.debug("ServerDialback: RS - Error, hostname is not allowed to establish a connection to " +
                    "this server: " +
                    recipient);
            return false;
        }
        else if (isHostUnknown(recipient)) {
            // address does not match a recognized hostname
            connection.deliverRawText(new StreamError(StreamError.Condition.host_unknown).toXML());
            // Close the underlying connection
            connection.close();
            Log.debug("ServerDialback: RS - Error, hostname not recognized: " + recipient);
            return false;
        }
        else {
            // Check if the remote server already has a connection to the target domain/subdomain
            boolean alreadyExists = false;
            for (IncomingServerSession session : sessionManager.getIncomingServerSessions(hostname)) {
                if (recipient.equals(session.getLocalDomain())) {
                    alreadyExists = true;
                }
            }
            if (alreadyExists && !sessionManager.isMultipleServerConnectionsAllowed()) {
                // Remote server already has a IncomingServerSession created
                connection.deliverRawText(
                        new StreamError(StreamError.Condition.not_authorized).toXML());
                // Close the underlying connection
                connection.close();
                Log.debug("ServerDialback: RS - Error, incoming connection already exists from: " + hostname);
                return false;
            }
            else {
                String key = doc.getTextTrim();

                DNSUtil.HostAddress address = DNSUtil.resolveXMPPServerDomain(hostname,
                        RemoteServerManager.getPortForServer(hostname));

                try {
                    boolean valid = verifyKey(key, streamID.toString(), recipient, hostname,
                            address.getHost(), address.getPort());

                    Log.debug("ServerDialback: RS - Sending key verification result to OS: " + hostname);
                    sb = new StringBuilder();
                    sb.append("<db:result");
                    sb.append(" from=\"").append(recipient).append("\"");
                    sb.append(" to=\"").append(hostname).append("\"");
                    sb.append(" type=\"");
                    sb.append(valid ? "valid" : "invalid");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -