JDK8/Java8源码在线阅读

JDK8/Java8源码在线阅读 / sun / management / jmxremote / ConnectorBootstrap.java
/*
 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.management.jmxremote;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RemoteObject;
import java.rmi.server.UnicastRemoteObject;
import java.security.KeyStore;
import java.security.Principal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import javax.management.MBeanServer;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnectorServer;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
import javax.security.auth.Subject;

import com.sun.jmx.remote.internal.RMIExporter;
import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
import com.sun.jmx.remote.util.ClassLogger;

import sun.management.Agent;
import sun.management.AgentConfigurationError;
import static sun.management.AgentConfigurationError.*;
import sun.management.ConnectorAddressLink;
import sun.management.FileSystem;
import sun.rmi.server.UnicastRef;
import sun.rmi.server.UnicastServerRef;
import sun.rmi.server.UnicastServerRef2;

/**
 * This class initializes and starts the RMIConnectorServer for JSR 163
 * JMX Monitoring.
 **/
public final class ConnectorBootstrap {

    /**
     * Default values for JMX configuration properties.
     **/
    public static interface DefaultValues {

        public static final String PORT = "0";
        public static final String CONFIG_FILE_NAME = "management.properties";
        public static final String USE_SSL = "true";
        public static final String USE_LOCAL_ONLY = "true";
        public static final String USE_REGISTRY_SSL = "false";
        public static final String USE_AUTHENTICATION = "true";
        public static final String PASSWORD_FILE_NAME = "jmxremote.password";
        public static final String ACCESS_FILE_NAME = "jmxremote.access";
        public static final String SSL_NEED_CLIENT_AUTH = "false";
    }

    /**
     * Names of JMX configuration properties.
     **/
    public static interface PropertyNames {

        public static final String PORT =
                "com.sun.management.jmxremote.port";
        public static final String RMI_PORT =
                "com.sun.management.jmxremote.rmi.port";
        public static final String CONFIG_FILE_NAME =
                "com.sun.management.config.file";
        public static final String USE_LOCAL_ONLY =
                "com.sun.management.jmxremote.local.only";
        public static final String USE_SSL =
                "com.sun.management.jmxremote.ssl";
        public static final String USE_REGISTRY_SSL =
                "com.sun.management.jmxremote.registry.ssl";
        public static final String USE_AUTHENTICATION =
                "com.sun.management.jmxremote.authenticate";
        public static final String PASSWORD_FILE_NAME =
                "com.sun.management.jmxremote.password.file";
        public static final String ACCESS_FILE_NAME =
                "com.sun.management.jmxremote.access.file";
        public static final String LOGIN_CONFIG_NAME =
                "com.sun.management.jmxremote.login.config";
        public static final String SSL_ENABLED_CIPHER_SUITES =
                "com.sun.management.jmxremote.ssl.enabled.cipher.suites";
        public static final String SSL_ENABLED_PROTOCOLS =
                "com.sun.management.jmxremote.ssl.enabled.protocols";
        public static final String SSL_NEED_CLIENT_AUTH =
                "com.sun.management.jmxremote.ssl.need.client.auth";
        public static final String SSL_CONFIG_FILE_NAME =
                "com.sun.management.jmxremote.ssl.config.file";
    }

    /**
     * JMXConnectorServer associated data.
     */
    private static class JMXConnectorServerData {

        public JMXConnectorServerData(
                JMXConnectorServer jmxConnectorServer,
                JMXServiceURL jmxRemoteURL) {
            this.jmxConnectorServer = jmxConnectorServer;
            this.jmxRemoteURL = jmxRemoteURL;
        }
        JMXConnectorServer jmxConnectorServer;
        JMXServiceURL jmxRemoteURL;
    }

    /**
     * <p>Prevents our RMI server objects from keeping the JVM alive.</p>
     *
     * <p>We use a private interface in Sun's JMX Remote API implementation
     * that allows us to specify how to export RMI objects.  We do so using
     * UnicastServerRef, a class in Sun's RMI implementation.  This is all
     * non-portable, of course, so this is only valid because we are inside
     * Sun's JRE.</p>
     *
     * <p>Objects are exported using {@link
     * UnicastServerRef#exportObject(Remote, Object, boolean)}.  The
     * boolean parameter is called <code>permanent</code> and means
     * both that the object is not eligible for Distributed Garbage
     * Collection, and that its continued existence will not prevent
     * the JVM from exiting.  It is the latter semantics we want (we
     * already have the former because of the way the JMX Remote API
     * works).  Hence the somewhat misleading name of this class.</p>
     */
    private static class PermanentExporter implements RMIExporter {

        public Remote exportObject(Remote obj,
                int port,
                RMIClientSocketFactory csf,
                RMIServerSocketFactory ssf)
                throws RemoteException {

            synchronized (this) {
                if (firstExported == null) {
                    firstExported = obj;
                }
            }

            final UnicastServerRef ref;
            if (csf == null && ssf == null) {
                ref = new UnicastServerRef(port);
            } else {
                ref = new UnicastServerRef2(port, csf, ssf);
            }
            return ref.exportObject(obj, null, true);
        }

        // Nothing special to be done for this case
        public boolean unexportObject(Remote obj, boolean force)
                throws NoSuchObjectException {
            return UnicastRemoteObject.unexportObject(obj, force);
        }
        Remote firstExported;
    }

    /**
     * This JMXAuthenticator wraps the JMXPluggableAuthenticator and verifies
     * that at least one of the principal names contained in the authenticated
     * Subject is present in the access file.
     */
    private static class AccessFileCheckerAuthenticator
            implements JMXAuthenticator {

        public AccessFileCheckerAuthenticator(Map<String, Object> env) throws IOException {
            environment = env;
            accessFile = (String) env.get("jmx.remote.x.access.file");
            properties = propertiesFromFile(accessFile);
        }

        public Subject authenticate(Object credentials) {
            final JMXAuthenticator authenticator =
                    new JMXPluggableAuthenticator(environment);
            final Subject subject = authenticator.authenticate(credentials);
            checkAccessFileEntries(subject);
            return subject;
        }

        private void checkAccessFileEntries(Subject subject) {
            if (subject == null) {
                throw new SecurityException(
                        "Access denied! No matching entries found in " +
                        "the access file [" + accessFile + "] as the " +
                        "authenticated Subject is null");
            }
            final Set<Principal> principals = subject.getPrincipals();
            for (Principal p1: principals) {
                if (properties.containsKey(p1.getName())) {
                    return;
                }
            }

            final Set<String> principalsStr = new HashSet<>();
            for (Principal p2: principals) {
                principalsStr.add(p2.getName());
            }
            throw new SecurityException(
                    "Access denied! No entries found in the access file [" +
                    accessFile + "] for any of the authenticated identities " +
                    principalsStr);
        }

        private static Properties propertiesFromFile(String fname)
                throws IOException {
            Properties p = new Properties();
            if (fname == null) {
                return p;
            }
            try (FileInputStream fin = new FileInputStream(fname)) {
                p.load(fin);
            }
            return p;
        }
        private final Map<String, Object> environment;
        private final Properties properties;
        private final String accessFile;
    }

    // The variable below is here to support stop functionality
    // It would be overriten if you call startRemoteCommectionServer second
    // time. It's OK for now as logic in Agent.java forbids mutiple agents
    private static Registry registry = null;

    public static void unexportRegistry() {
        // Remove the entry from registry
        try {
            if (registry != null) {
                UnicastRemoteObject.unexportObject(registry, true);
                registry = null;
            }
        } catch(NoSuchObjectException ex) {
            // This exception can appears only if we attempt
            // to unexportRegistry second time. So it's safe
            // to ignore it without additional messages.
        }
    }

     /**
      * Initializes and starts the JMX Connector Server.
      * If the com.sun.management.jmxremote.port property is not defined,
      * simply return. Otherwise, attempts to load the config file, and
      * then calls {@link #startRemoteConnectorServer
      *                            (java.lang.String, java.util.Properties)}.
      *
      * This method is used by some jtreg tests.
      **/
      public static synchronized JMXConnectorServer initialize() {

         // Load a new management properties
         final Properties props = Agent.loadManagementProperties();
         if (props == null) {
              return null;
         }

         final String portStr = props.getProperty(PropertyNames.PORT);
         return startRemoteConnectorServer(portStr, props);
     }

    /**
     * This method is used by some jtreg tests.
     *
     * @see #startRemoteConnectorServer
     *             (String portStr, Properties props)
     */
    public static synchronized JMXConnectorServer initialize(String portStr, Properties props)  {
         return startRemoteConnectorServer(portStr, props);
    }

    /**
     * Initializes and starts a JMX Connector Server for remote
     * monitoring and management.
     **/
    public static synchronized JMXConnectorServer startRemoteConnectorServer(String portStr, Properties props) {

        // Get port number
        final int port;
        try {
            port = Integer.parseInt(portStr);
        } catch (NumberFormatException x) {
            throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, x, portStr);
        }
        if (port < 0) {
            throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, portStr);
        }

        // User can specify a port to be used to export rmi object,
        // in order to simplify firewall rules
        // if port is not specified random one will be allocated.
        int rmiPort = 0;
        String rmiPortStr = props.getProperty(PropertyNames.RMI_PORT);
        try {
            if (rmiPortStr != null) {
               rmiPort = Integer.parseInt(rmiPortStr);
            }
        } catch (NumberFormatException x) {
            throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, x, rmiPortStr);
        }
        if (rmiPort < 0) {
            throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, rmiPortStr);
        }

        // Do we use authentication?
        final String useAuthenticationStr =
                props.getProperty(PropertyNames.USE_AUTHENTICATION,
                DefaultValues.USE_AUTHENTICATION);
        final boolean useAuthentication =
                Boolean.valueOf(useAuthenticationStr).booleanValue();

        // Do we use SSL?
        final String useSslStr =
                props.getProperty(PropertyNames.USE_SSL,
                DefaultValues.USE_SSL);
        final boolean useSsl =
                Boolean.valueOf(useSslStr).booleanValue();

        // Do we use RMI Registry SSL?
        final String useRegistrySslStr =
                props.getProperty(PropertyNames.USE_REGISTRY_SSL,
                DefaultValues.USE_REGISTRY_SSL);
        final boolean useRegistrySsl =
                Boolean.valueOf(useRegistrySslStr).booleanValue();

        final String enabledCipherSuites =
                props.getProperty(PropertyNames.SSL_ENABLED_CIPHER_SUITES);
        String enabledCipherSuitesList[] = null;
        if (enabledCipherSuites != null) {
            StringTokenizer st = new StringTokenizer(enabledCipherSuites, ",");
            int tokens = st.countTokens();
            enabledCipherSuitesList = new String[tokens];
            for (int i = 0; i < tokens; i++) {
                enabledCipherSuitesList[i] = st.nextToken();
            }
        }

        final String enabledProtocols =
                props.getProperty(PropertyNames.SSL_ENABLED_PROTOCOLS);
        String enabledProtocolsList[] = null;
        if (enabledProtocols != null) {
            StringTokenizer st = new StringTokenizer(enabledProtocols, ",");
            int tokens = st.countTokens();
            enabledProtocolsList = new String[tokens];
            for (int i = 0; i < tokens; i++) {
                enabledProtocolsList[i] = st.nextToken();
            }
        }

        final String sslNeedClientAuthStr =
                props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,
                DefaultValues.SSL_NEED_CLIENT_AUTH);
        final boolean sslNeedClientAuth =
                Boolean.valueOf(sslNeedClientAuthStr).booleanValue();

        // Read SSL config file name
        final String sslConfigFileName =
                props.getProperty(PropertyNames.SSL_CONFIG_FILE_NAME);

        String loginConfigName = null;
        String passwordFileName = null;
        String accessFileName = null;

        // Initialize settings when authentication is active
        if (useAuthentication) {

            // Get non-default login configuration
            loginConfigName =
                    props.getProperty(PropertyNames.LOGIN_CONFIG_NAME);

            if (loginConfigName == null) {
                // Get password file
                passwordFileName =
                        props.getProperty(PropertyNames.PASSWORD_FILE_NAME,
                        getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME));
                checkPasswordFile(passwordFileName);
            }

            // Get access file
            accessFileName = props.getProperty(PropertyNames.ACCESS_FILE_NAME,
                    getDefaultFileName(DefaultValues.ACCESS_FILE_NAME));
            checkAccessFile(accessFileName);
        }

        if (log.debugOn()) {
            log.debug("startRemoteConnectorServer",
                    Agent.getText("jmxremote.ConnectorBootstrap.starting") +
                    "\n\t" + PropertyNames.PORT + "=" + port +
                    "\n\t" + PropertyNames.RMI_PORT + "=" + rmiPort +
                    "\n\t" + PropertyNames.USE_SSL + "=" + useSsl +
                    "\n\t" + PropertyNames.USE_REGISTRY_SSL + "=" + useRegistrySsl +
                    "\n\t" + PropertyNames.SSL_CONFIG_FILE_NAME + "=" + sslConfigFileName +
                    "\n\t" + PropertyNames.SSL_ENABLED_CIPHER_SUITES + "=" +
                    enabledCipherSuites +
                    "\n\t" + PropertyNames.SSL_ENABLED_PROTOCOLS + "=" +
                    enabledProtocols +
                    "\n\t" + PropertyNames.SSL_NEED_CLIENT_AUTH + "=" +
                    sslNeedClientAuth +
                    "\n\t" + PropertyNames.USE_AUTHENTICATION + "=" +
                    useAuthentication +
                    (useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" +
                    passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" +
                    loginConfigName)) : "\n\t" +
                    Agent.getText("jmxremote.ConnectorBootstrap.noAuthentication")) +
                    (useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" +
                    accessFileName) : "") +
                    "");
        }

        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        JMXConnectorServer cs = null;
        JMXServiceURL url = null;
        try {
            final JMXConnectorServerData data = exportMBeanServer(
                    mbs, port, rmiPort, useSsl, useRegistrySsl,
                    sslConfigFileName, enabledCipherSuitesList,
                    enabledProtocolsList, sslNeedClientAuth,
                    useAuthentication, loginConfigName,
                    passwordFileName, accessFileName);
            cs = data.jmxConnectorServer;
            url = data.jmxRemoteURL;
            log.config("startRemoteConnectorServer",
                    Agent.getText("jmxremote.ConnectorBootstrap.ready",
                    url.toString()));
        } catch (Exception e) {
            throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
        }
        try {
            // Export remote connector address and associated configuration
            // properties to the instrumentation buffer.
            Map<String, String> properties = new HashMap<>();
            properties.put("remoteAddress", url.toString());
            properties.put("authenticate", useAuthenticationStr);
            properties.put("ssl", useSslStr);
            properties.put("sslRegistry", useRegistrySslStr);
            properties.put("sslNeedClientAuth", sslNeedClientAuthStr);
            ConnectorAddressLink.exportRemote(properties);
        } catch (Exception e) {
            // Remote connector server started but unable to export remote
            // connector address and associated configuration properties to
            // the instrumentation buffer - non-fatal error.
            log.debug("startRemoteConnectorServer", e);
        }
        return cs;
    }

    /*
     * Creates and starts a RMI Connector Server for "local" monitoring
     * and management.
     */
    public static JMXConnectorServer startLocalConnectorServer() {
        // Ensure cryptographically strong random number generater used
        // to choose the object number - see java.rmi.server.ObjID
        System.setProperty("java.rmi.server.randomIDs", "true");

        // This RMI server should not keep the VM alive
        Map<String, Object> env = new HashMap<>();
        env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter());

        // The local connector server need only be available via the
        // loopback connection.
        String localhost = "localhost";
        InetAddress lh = null;
        try {
            lh = InetAddress.getByName(localhost);
            localhost = lh.getHostAddress();
        } catch (UnknownHostException x) {
        }

        // localhost unknown or (somehow) didn't resolve to
        // a loopback address.
        if (lh == null || !lh.isLoopbackAddress()) {
            localhost = "127.0.0.1";
        }

        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        try {
            JMXServiceURL url = new JMXServiceURL("rmi", localhost, 0);
            // Do we accept connections from local interfaces only?
            Properties props = Agent.getManagementProperties();
            if (props ==  null) {
                props = new Properties();
            }
            String useLocalOnlyStr = props.getProperty(
                    PropertyNames.USE_LOCAL_ONLY, DefaultValues.USE_LOCAL_ONLY);
            boolean useLocalOnly = Boolean.valueOf(useLocalOnlyStr).booleanValue();
            if (useLocalOnly) {
                env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
                        new LocalRMIServerSocketFactory());
            }
            JMXConnectorServer server =
                    JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
            server.start();
            return server;
        } catch (Exception e) {
            throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
        }
    }

    private static void checkPasswordFile(String passwordFileName) {
        if (passwordFileName == null || passwordFileName.length() == 0) {
            throw new AgentConfigurationError(PASSWORD_FILE_NOT_SET);
        }
        File file = new File(passwordFileName);
        if (!file.exists()) {
            throw new AgentConfigurationError(PASSWORD_FILE_NOT_FOUND, passwordFileName);
        }

        if (!file.canRead()) {
            throw new AgentConfigurationError(PASSWORD_FILE_NOT_READABLE, passwordFileName);
        }

        FileSystem fs = FileSystem.open();
        try {
            if (fs.supportsFileSecurity(file)) {
                if (!fs.isAccessUserOnly(file)) {
                    final String msg = Agent.getText("jmxremote.ConnectorBootstrap.password.readonly",
                            passwordFileName);
                    log.config("startRemoteConnectorServer", msg);
                    throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED,
                            passwordFileName);
                }
            }
        } catch (IOException e) {
            throw new AgentConfigurationError(PASSWORD_FILE_READ_FAILED,
                    e, passwordFileName);
        }
    }

    private static void checkAccessFile(String accessFileName) {
        if (accessFileName == null || accessFileName.length() == 0) {
            throw new AgentConfigurationError(ACCESS_FILE_NOT_SET);
        }
        File file = new File(accessFileName);
        if (!file.exists()) {
            throw new AgentConfigurationError(ACCESS_FILE_NOT_FOUND, accessFileName);
        }

        if (!file.canRead()) {
            throw new AgentConfigurationError(ACCESS_FILE_NOT_READABLE, accessFileName);
        }
    }

    private static void checkRestrictedFile(String restrictedFileName) {
        if (restrictedFileName == null || restrictedFileName.length() == 0) {
            throw new AgentConfigurationError(FILE_NOT_SET);
        }
        File file = new File(restrictedFileName);
        if (!file.exists()) {
            throw new AgentConfigurationError(FILE_NOT_FOUND, restrictedFileName);
        }
        if (!file.canRead()) {
            throw new AgentConfigurationError(FILE_NOT_READABLE, restrictedFileName);
        }
        FileSystem fs = FileSystem.open();
        try {
            if (fs.supportsFileSecurity(file)) {
                if (!fs.isAccessUserOnly(file)) {
                    final String msg = Agent.getText(
                            "jmxremote.ConnectorBootstrap.file.readonly",
                            restrictedFileName);
                    log.config("startRemoteConnectorServer", msg);
                    throw new AgentConfigurationError(
                            FILE_ACCESS_NOT_RESTRICTED, restrictedFileName);
                }
            }
        } catch (IOException e) {
            throw new AgentConfigurationError(
                    FILE_READ_FAILED, e, restrictedFileName);
        }
    }

    /**
     * Compute the full path name for a default file.
     * @param basename basename (with extension) of the default file.
     * @return ${JRE}/lib/management/${basename}
     **/
    private static String getDefaultFileName(String basename) {
        final String fileSeparator = File.separator;
        return System.getProperty("java.home") + fileSeparator + "lib" +
                fileSeparator + "management" + fileSeparator +
                basename;
    }

    private static SslRMIServerSocketFactory createSslRMIServerSocketFactory(
            String sslConfigFileName,
            String[] enabledCipherSuites,
            String[] enabledProtocols,
            boolean sslNeedClientAuth) {
        if (sslConfigFileName == null) {
            return new SslRMIServerSocketFactory(
                    enabledCipherSuites,
                    enabledProtocols,
                    sslNeedClientAuth);
        } else {
            checkRestrictedFile(sslConfigFileName);
            try {
                // Load the SSL keystore properties from the config file
                Properties p = new Properties();
                try (InputStream in = new FileInputStream(sslConfigFileName)) {
                    BufferedInputStream bin = new BufferedInputStream(in);
                    p.load(bin);
                }
                String keyStore =
                        p.getProperty("javax.net.ssl.keyStore");
                String keyStorePassword =
                        p.getProperty("javax.net.ssl.keyStorePassword", "");
                String trustStore =
                        p.getProperty("javax.net.ssl.trustStore");
                String trustStorePassword =
                        p.getProperty("javax.net.ssl.trustStorePassword", "");

                char[] keyStorePasswd = null;
                if (keyStorePassword.length() != 0) {
                    keyStorePasswd = keyStorePassword.toCharArray();
                }

                char[] trustStorePasswd = null;
                if (trustStorePassword.length() != 0) {
                    trustStorePasswd = trustStorePassword.toCharArray();
                }

                KeyStore ks = null;
                if (keyStore != null) {
                    ks = KeyStore.getInstance(KeyStore.getDefaultType());
                    try (FileInputStream ksfis = new FileInputStream(keyStore)) {
                        ks.load(ksfis, keyStorePasswd);
                    }
                }
                KeyManagerFactory kmf = KeyManagerFactory.getInstance(
                        KeyManagerFactory.getDefaultAlgorithm());
                kmf.init(ks, keyStorePasswd);

                KeyStore ts = null;
                if (trustStore != null) {
                    ts = KeyStore.getInstance(KeyStore.getDefaultType());
                    try (FileInputStream tsfis = new FileInputStream(trustStore)) {
                        ts.load(tsfis, trustStorePasswd);
                    }
                }
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(
                        TrustManagerFactory.getDefaultAlgorithm());
                tmf.init(ts);

                SSLContext ctx = SSLContext.getInstance("SSL");
                ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

                return new SslRMIServerSocketFactory(
                        ctx,
                        enabledCipherSuites,
                        enabledProtocols,
                        sslNeedClientAuth);
            } catch (Exception e) {
                throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
            }
        }
    }

    private static JMXConnectorServerData exportMBeanServer(
            MBeanServer mbs,
            int port,
            int rmiPort,
            boolean useSsl,
            boolean useRegistrySsl,
            String sslConfigFileName,
            String[] enabledCipherSuites,
            String[] enabledProtocols,
            boolean sslNeedClientAuth,
            boolean useAuthentication,
            String loginConfigName,
            String passwordFileName,
            String accessFileName)
            throws IOException, MalformedURLException {

        /* Make sure we use non-guessable RMI object IDs.  Otherwise
         * attackers could hijack open connections by guessing their
         * IDs.  */
        System.setProperty("java.rmi.server.randomIDs", "true");

        JMXServiceURL url = new JMXServiceURL("rmi", null, rmiPort);

        Map<String, Object> env = new HashMap<>();


/**代码未完, 请加载全部代码(NowJava.com).**/
展开阅读全文

关注时代Java

关注时代Java