CAMEL-4974: Added santizie option to JMX to hide sensitive information like password in URIs exposed in JMX MBean names and attributes.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/abba6b31 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/abba6b31 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/abba6b31 Branch: refs/heads/master Commit: abba6b3124f61bf759632424208e55905514166a Parents: e1d57c3 Author: Claus Ibsen <davscl...@apache.org> Authored: Tue Jul 30 16:27:41 2013 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Tue Jul 30 16:28:01 2013 +0200 ---------------------------------------------------------------------- .../DefaultManagementMBeanAssembler.java | 12 ++- .../management/DefaultRequiredModelMBean.java | 97 -------------------- .../management/SanitizeRequiredModelMBean.java | 94 +++++++++++++++++++ 3 files changed, 103 insertions(+), 100 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/abba6b31/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java b/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java index fe23006..b50b006 100644 --- a/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java +++ b/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java @@ -22,6 +22,7 @@ import javax.management.ObjectName; import javax.management.modelmbean.InvalidTargetObjectTypeException; import javax.management.modelmbean.ModelMBean; import javax.management.modelmbean.ModelMBeanInfo; +import javax.management.modelmbean.RequiredModelMBean; import org.apache.camel.CamelContext; import org.apache.camel.api.management.ManagedInstance; @@ -75,9 +76,14 @@ public class DefaultManagementMBeanAssembler implements ManagementMBeanAssembler return null; } - boolean santizie = camelContext.getManagementStrategy().getManagementAgent().getSanitize() != null && camelContext.getManagementStrategy().getManagementAgent().getSanitize(); - DefaultRequiredModelMBean mbean = new DefaultRequiredModelMBean(mbi); - mbean.setSanitize(santizie); + RequiredModelMBean mbean; + boolean sanitize = camelContext.getManagementStrategy().getManagementAgent().getSanitize() != null && camelContext.getManagementStrategy().getManagementAgent().getSanitize(); + if (sanitize) { + mbean = new SanitizeRequiredModelMBean(mbi, sanitize); + } else { + mbean = (RequiredModelMBean) mBeanServer.instantiate(RequiredModelMBean.class.getName()); + mbean.setModelMBeanInfo(mbi); + } try { mbean.setManagedResource(obj, "ObjectReference"); http://git-wip-us.apache.org/repos/asf/camel/blob/abba6b31/camel-core/src/main/java/org/apache/camel/management/DefaultRequiredModelMBean.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/management/DefaultRequiredModelMBean.java b/camel-core/src/main/java/org/apache/camel/management/DefaultRequiredModelMBean.java deleted file mode 100644 index 5664e17..0000000 --- a/camel-core/src/main/java/org/apache/camel/management/DefaultRequiredModelMBean.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.management; - -import javax.management.Descriptor; -import javax.management.MBeanException; -import javax.management.MBeanOperationInfo; -import javax.management.ReflectionException; -import javax.management.RuntimeOperationsException; -import javax.management.modelmbean.ModelMBeanInfo; -import javax.management.modelmbean.RequiredModelMBean; - -import org.apache.camel.util.ObjectHelper; -import org.apache.camel.util.URISupport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A {@link RequiredModelMBean} which allows us to intercept invoking operations on the MBean. - * <p/> - * For example if sanitize has been enabled on JMX, then we use this implementation - * to hide sensitive information from the returned JMX attributes / operations. - */ -public class DefaultRequiredModelMBean extends RequiredModelMBean { - - private static final Logger LOG = LoggerFactory.getLogger(DefaultRequiredModelMBean.class); - private boolean sanitize; - - public DefaultRequiredModelMBean() throws MBeanException, RuntimeOperationsException { - // must have default no-arg constructor - } - - public DefaultRequiredModelMBean(ModelMBeanInfo mbi) throws MBeanException, RuntimeOperationsException { - super(mbi); - } - - public boolean isSanitize() { - return sanitize; - } - - public void setSanitize(boolean sanitize) { - this.sanitize = sanitize; - } - - @Override - public Object invoke(String opName, Object[] opArgs, String[] sig) throws MBeanException, ReflectionException { - Object answer = super.invoke(opName, opArgs, sig); - // sanitize the answer if enabled and it was a String type (we cannot sanitize other types) - if (sanitize && answer instanceof String && ObjectHelper.isNotEmpty(answer) && isSanitizedOperation(opName)) { - answer = sanitize(opName, (String) answer); - } - return answer; - } - - protected boolean isSanitizedOperation(String opName) { - for (MBeanOperationInfo info : getMBeanInfo().getOperations()) { - if (info.getName().equals(opName)) { - Descriptor desc = info.getDescriptor(); - if (desc != null) { - Object val = desc.getFieldValue("sanitize"); - return val != null && "true".equals(val); - } - } - } - return false; - } - - /** - * Sanitizes the returned value from invoking the operation - * - * @param opName the operation name invoked - * @param value the current value - * @return the sanitized value - */ - protected String sanitize(String opName, String value) { - String answer = URISupport.sanitizeUri(value); - if (LOG.isTraceEnabled()) { - LOG.trace("Sanitizing JMX operation: {}.{} value: {} -> {}", - new Object[]{getMBeanInfo().getClassName(), opName, value, answer}); - } - return answer; - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/abba6b31/camel-core/src/main/java/org/apache/camel/management/SanitizeRequiredModelMBean.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/management/SanitizeRequiredModelMBean.java b/camel-core/src/main/java/org/apache/camel/management/SanitizeRequiredModelMBean.java new file mode 100644 index 0000000..6d34e75 --- /dev/null +++ b/camel-core/src/main/java/org/apache/camel/management/SanitizeRequiredModelMBean.java @@ -0,0 +1,94 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.management; + +import javax.management.Descriptor; +import javax.management.MBeanException; +import javax.management.MBeanOperationInfo; +import javax.management.ReflectionException; +import javax.management.RuntimeOperationsException; +import javax.management.modelmbean.ModelMBeanInfo; +import javax.management.modelmbean.RequiredModelMBean; + +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.URISupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link RequiredModelMBean} which allows us to intercept invoking operations on the MBean. + * <p/> + * For example if sanitize has been enabled on JMX, then we use this implementation + * to hide sensitive information from the returned JMX attributes / operations. + */ +public class SanitizeRequiredModelMBean extends RequiredModelMBean { + + private static final Logger LOG = LoggerFactory.getLogger(SanitizeRequiredModelMBean.class); + private boolean sanitize; + + public SanitizeRequiredModelMBean() throws MBeanException, RuntimeOperationsException { + // must have default no-arg constructor + } + + public SanitizeRequiredModelMBean(ModelMBeanInfo mbi, boolean sanitize) throws MBeanException, RuntimeOperationsException { + super(mbi); + this.sanitize = sanitize; + } + + public boolean isSanitize() { + return sanitize; + } + + @Override + public Object invoke(String opName, Object[] opArgs, String[] sig) throws MBeanException, ReflectionException { + Object answer = super.invoke(opName, opArgs, sig); + // sanitize the answer if enabled and it was a String type (we cannot sanitize other types) + if (sanitize && answer instanceof String && ObjectHelper.isNotEmpty(answer) && isSanitizedOperation(opName)) { + answer = sanitize(opName, (String) answer); + } + return answer; + } + + protected boolean isSanitizedOperation(String opName) { + for (MBeanOperationInfo info : getMBeanInfo().getOperations()) { + if (info.getName().equals(opName)) { + Descriptor desc = info.getDescriptor(); + if (desc != null) { + Object val = desc.getFieldValue("sanitize"); + return val != null && "true".equals(val); + } + } + } + return false; + } + + /** + * Sanitizes the returned value from invoking the operation + * + * @param opName the operation name invoked + * @param value the current value + * @return the sanitized value + */ + protected String sanitize(String opName, String value) { + String answer = URISupport.sanitizeUri(value); + if (LOG.isTraceEnabled()) { + LOG.trace("Sanitizing JMX operation: {}.{} value: {} -> {}", + new Object[]{getMBeanInfo().getClassName(), opName, value, answer}); + } + return answer; + } +}