[ 
https://issues.apache.org/jira/browse/TOMEE-2294?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17136310#comment-17136310
 ] 

Frans commented on TOMEE-2294:
------------------------------

Okay! Finally some progress!

Looking at the log line
{code:java}
org.apache.activemq.broker.jmx.ManagementContext$1.run JMX consoles can connect 
to service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi {code}
I browsed through the tomee jars until I found 
org.apache.activemq.broker.jmx.ManagementContext in activemq-broker-5.15.10.jar

I used FernFlower to decompile the class, and found where the line was being 
logged.

Scrolling around the class, I found that createConnector was the variable used 
to toggle whether or not to enable the dodgy unauthenticated JMX port, which is 
by default on connectorPort = 1099

createConnector defaults to true, and is overridden by a system property: 
org.apache.activemq.broker.jmx.createConnector
{code:java}
     /**
     * Default activemq domain
     */
    public static final String DEFAULT_DOMAIN = "org.apache.activemq";    
static {
        String option = Boolean.TRUE.toString();
        try {
            option = 
System.getProperty("org.apache.activemq.broker.jmx.createConnector", "true");
        } catch (Exception ex) {
        }        DEFAULT_CREATE_CONNECTOR = Boolean.valueOf(option);
    }    public static final boolean DEFAULT_CREATE_CONNECTOR;
{code}
So it appears that any call to ManagementContext.getMbeanServer() - of which 
there are many - tries to find an mbean server
{code:java}
    public MBeanServer getMBeanServer() {
        if (this.beanServer == null) {
            this.beanServer = findMBeanServer();
        }
        return beanServer;
    }{code}
Which then creates one if it's not been initialised
{code:java}
    protected synchronized MBeanServer findMBeanServer() {
        MBeanServer result = null;        try {
            if (useMBeanServer) {
                if (findTigerMbeanServer) {
                    result = findTigerMBeanServer();
                }
                if (result == null) {
                    // lets piggy back on another MBeanServer - we could be in 
an appserver!
                    List<MBeanServer> list = 
MBeanServerFactory.findMBeanServer(null);
                    if (list != null && list.size() > 0) {
                        result = list.get(0);
                    }
                }
            }
            if (result == null && createMBeanServer) {
                result = createMBeanServer();
            }
        } catch (NoClassDefFoundError e) {
            LOG.error("Could not load MBeanServer", e);
        } catch (Throwable e) {
            // probably don't have access to system properties
            LOG.error("Failed to initialize MBeanServer", e);
        }
        return result;
    } {code}
And no matter whether it's looking for a tiger mbean server
{code:java}
    public MBeanServer findTigerMBeanServer() {
        String name = "java.lang.management.ManagementFactory";
        Class<?> type = loadClass(name, 
ManagementContext.class.getClassLoader());
        if (type != null) {
            try {
                Method method = type.getMethod("getPlatformMBeanServer", new 
Class[0]);
                if (method != null) {
                    Object answer = method.invoke(null, new Object[0]);
                    if (answer instanceof MBeanServer) {
                        if (createConnector) {
                            createConnector((MBeanServer)answer);
                        }
                        return (MBeanServer)answer;
                    } else {
                        LOG.warn("Could not cast: {} into an MBeanServer. There 
must be some classloader strangeness in town", answer);
                    }
                } else {
                    LOG.warn("Method getPlatformMBeanServer() does not appear 
visible on type: {}", type.getName());
                }
            } catch (Exception e) {
                LOG.warn("Failed to call getPlatformMBeanServer() due to: ", e);
            }
        } else {
            LOG.trace("Class not found: {} so probably running on Java 1.4", 
name);
        }
        return null;
    } {code}
or creating a non-tiger mbean server
{code:java}
     protected MBeanServer createMBeanServer() throws 
MalformedObjectNameException, IOException {
        MBeanServer mbeanServer = 
MBeanServerFactory.createMBeanServer(jmxDomainName);
        locallyCreateMBeanServer = true;
        if (createConnector) {
            createConnector(mbeanServer);
        }
        return mbeanServer;
    }{code}
it still does a check on createConnector.

And because the useJmx=false flag isn't propagated through to the 
setCreateConnector method before the first of these calls is made, and the hard 
coded default for creating this JMX port is true
{code:java}
    public void setCreateConnector(boolean createConnector) {
        this.createConnector = createConnector;
    }{code}
the connector is created.

Then, when the start method is called on the ManagementContext, because a 
management server exists (and the log entries on createConnector are DEBUG, you 
get that log line
{code:java}
    @Override
    public void start() throws Exception {
        // lets force the MBeanServer to be created if needed
        if (started.compareAndSet(false, true)) {            
populateMBeanSuppressionMap();            // fallback and use localhost
            if (connectorHost == null) {
                connectorHost = "localhost";
            }            // force mbean server to be looked up, so we have it
            getMBeanServer();            if (connectorServer != null) {
                try {
                    if (getMBeanServer().isRegistered(namingServiceObjectName)) 
{
                        LOG.debug("Invoking start on mbean: {}", 
namingServiceObjectName);
                        getMBeanServer().invoke(namingServiceObjectName, 
"start", null, null);
                    }
                } catch (Throwable ignore) {
                    LOG.debug("Error invoking start on MBean {}. This exception 
is ignored.", namingServiceObjectName, ignore);
                }                Thread t = new Thread("JMX connector") {
                    @Override
                    public void run() {
                        // ensure we use MDC logging with the broker name, so 
people can see the logs if MDC was in use
                        if (brokerName != null) {
                            MDC.put("activemq.broker", brokerName);
                        }
                        try {
                            JMXConnectorServer server = connectorServer;
                            if (started.get() && server != null) {
                                LOG.debug("Starting JMXConnectorServer...");
                                try {
                                    // need to remove MDC as we must not 
inherit MDC in child threads causing leaks
                                    MDC.remove("activemq.broker");
                                    server.start();
                                } finally {
                                    if (brokerName != null) {
                                        MDC.put("activemq.broker", brokerName);
                                    }
                                    connectorStarted.countDown();
                                }
                                LOG.info("JMX consoles can connect to {}", 
server.getAddress());
                            }
                        } catch (IOException e) {
                            LOG.warn("Failed to start JMX connector {}. Will 
restart management to re-create JMX connector, trying to remedy this issue.", 
e.getMessage());
                            LOG.debug("Reason for failed JMX connector start", 
e);
                        } finally {
                            MDC.remove("activemq.broker");
                        }
                    }
                };
                t.setDaemon(true);
                t.start();
            }
        }
    } {code}

> Can't disable unauthenticated JMX on 1099
> -----------------------------------------
>
>                 Key: TOMEE-2294
>                 URL: https://issues.apache.org/jira/browse/TOMEE-2294
>             Project: TomEE
>          Issue Type: Bug
>          Components: TomEE Core Server
>            Reporter: Frans
>            Priority: Major
>             Fix For: 8.0.3
>
>
> ActiveMQ comes bundled with a JMX host that is default on unauthenticated on 
> port 1099.
> {code:java}
> <Resource id="JmsResourceAdapter" type="ActiveMQResourceAdapter">
>   BrokerXmlConfig = broker:(vm://broker)?useJmx=false
>   ServerUrl = vm://broker
> </Resource>{code}
> Tomee's resource configuration doesn't allow this to be disabled. The above 
> doesn't work.
> This can be disabled by inspecting an activemq jar's manifest, pulling down 
> the same version of activemq-all, and putting that in the tomee/lib 
> directory, at which point this works:
> {code:java}
> <Resource id="JmsResourceAdapter" type="ActiveMQResourceAdapter">
>   BrokerXmlConfig = xbean:file:activemq.xml
>   ServerUrl = vm://broker
> </Resource>
> {code}
> {code:java}
>   <broker xmlns="http://activemq.apache.org/schema/core";
>           useJmx="false"
>           brokerName="broker"
>           useShutdownHook="false"
>           persistent="true"
>           start="true"
>           schedulerSupport="false"
>           enableStatistics="false"
>           offlineDurableSubscriberTimeout="259200000"
>           offlineDurableSubscriberTaskSchedule="3600000">
> {code}
> However, convincing the guy hosting the server to inspect JAR manifests, pull 
> down specific jars, and maintain a second configuration file seems like a lot 
> of effort to go to just to have the ability to disable unauthenticated access 
> to every MBean in the VM



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to