Repository: ambari Updated Branches: refs/heads/trunk e3edcf574 -> 7c211e3ee
AMBARI-15773. Password must not by displayed by UpgradeItem and Stage resources in the API (alejandro) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7c211e3e Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7c211e3e Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7c211e3e Branch: refs/heads/trunk Commit: 7c211e3ee365889bf1e38f392f5f5adafe41e4a5 Parents: e3edcf5 Author: Alejandro Fernandez <[email protected]> Authored: Thu Apr 7 14:13:38 2016 -0700 Committer: Alejandro Fernandez <[email protected]> Committed: Thu Apr 7 14:19:35 2016 -0700 ---------------------------------------------------------------------- .../internal/ClientConfigResourceProvider.java | 1 - .../internal/StageResourceProvider.java | 20 ++++++++++-- .../internal/UpgradeItemResourceProvider.java | 11 +++++-- .../ambari/server/utils/SecretReference.java | 32 ++++++++++++++++++++ 4 files changed, 59 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/7c211e3e/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java index 4723d2a..3e4d7fd 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java @@ -311,7 +311,6 @@ public class ClientConfigResourceProvider extends AbstractControllerResourceProv hostLevelParams.put(ORACLE_JDBC_URL, managementController.getOjdbcUrl()); hostLevelParams.put(HOST_SYS_PREPPED, configs.areHostsSysPrepped()); hostLevelParams.putAll(managementController.getRcaParameters()); - hostLevelParams.putAll(managementController.getRcaParameters()); hostLevelParams.put(AGENT_STACK_RETRY_ON_UNAVAILABILITY, configs.isAgentStackRetryOnInstallEnabled()); hostLevelParams.put(AGENT_STACK_RETRY_COUNT, configs.getAgentStackRetryOnInstallCount()); http://git-wip-us.apache.org/repos/asf/ambari/blob/7c211e3e/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java index 8ebcd7b..a563420 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java @@ -30,6 +30,7 @@ import java.util.Set; import javax.inject.Inject; import javax.inject.Provider; +import com.google.common.collect.Sets; import org.apache.ambari.server.StaticallyInject; import org.apache.ambari.server.actionmanager.HostRoleStatus; import org.apache.ambari.server.controller.AmbariManagementController; @@ -51,6 +52,8 @@ import org.apache.ambari.server.orm.entities.StageEntity; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.topology.TopologyManager; +import org.apache.ambari.server.utils.SecretReference; +import org.apache.commons.lang.StringUtils; /** * ResourceProvider for Stage @@ -128,6 +131,11 @@ public class StageResourceProvider extends AbstractControllerResourceProvider im KEY_PROPERTY_IDS.put(Resource.Type.Request, STAGE_REQUEST_ID); } + /** + * These fields may contain password in them, so have to mask with. + */ + static final Set<String> PROPERTIES_TO_MASK_PASSWORD_IN = Sets.newHashSet(STAGE_COMMAND_PARAMS, STAGE_HOST_PARAMS); + // ----- Constructors ------------------------------------------------------ /** @@ -276,12 +284,20 @@ public class StageResourceProvider extends AbstractControllerResourceProvider im // this property is lazy loaded in JPA; don't use it unless requested if (isPropertyRequested(STAGE_COMMAND_PARAMS, requestedIds)) { - resource.setProperty(STAGE_COMMAND_PARAMS, entity.getCommandParamsStage()); + String value = entity.getCommandParamsStage(); + if (!StringUtils.isBlank(value)) { + value = SecretReference.maskPasswordInPropertyMap(value); + } + resource.setProperty(STAGE_COMMAND_PARAMS, value); } // this property is lazy loaded in JPA; don't use it unless requested if (isPropertyRequested(STAGE_HOST_PARAMS, requestedIds)) { - resource.setProperty(STAGE_HOST_PARAMS, entity.getHostParamsStage()); + String value = entity.getHostParamsStage(); + if (!StringUtils.isBlank(value)) { + value = SecretReference.maskPasswordInPropertyMap(value); + } + resource.setProperty(STAGE_HOST_PARAMS, value); } setResourceProperty(resource, STAGE_SKIPPABLE, entity.isSkippable(), requestedIds); http://git-wip-us.apache.org/repos/asf/ambari/blob/7c211e3e/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeItemResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeItemResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeItemResourceProvider.java index 8518593..0719430 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeItemResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeItemResourceProvider.java @@ -49,6 +49,8 @@ import org.apache.ambari.server.orm.entities.UpgradeItemEntity; import org.apache.ambari.server.state.UpgradeHelper; import com.google.inject.Inject; +import org.apache.ambari.server.utils.SecretReference; +import org.apache.commons.lang.StringUtils; /** * Manages the ability to get the status of upgrades. @@ -225,8 +227,13 @@ public class UpgradeItemResourceProvider extends ReadOnlyResourceProvider { Resource r = resultMap.get(l); if (null != r) { for (String propertyId : StageResourceProvider.PROPERTY_IDS) { - setResourceProperty(r, STAGE_MAPPED_IDS.get(propertyId), - stage.getPropertyValue(propertyId), requestPropertyIds); + // Attempt to mask any passwords in fields that are property maps. + Object value = stage.getPropertyValue(propertyId); + if (StageResourceProvider.PROPERTIES_TO_MASK_PASSWORD_IN.contains(propertyId) && + value.getClass().equals(String.class) && !StringUtils.isBlank((String) value)) { + value = SecretReference.maskPasswordInPropertyMap((String) value); + } + setResourceProperty(r, STAGE_MAPPED_IDS.get(propertyId), value, requestPropertyIds); } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/7c211e3e/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java index 6cfe53c..84f3109 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java @@ -18,20 +18,33 @@ package org.apache.ambari.server.utils; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.google.inject.Inject; import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.StaticallyInject; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Config; import org.apache.ambari.server.state.PropertyInfo; +import java.util.HashMap; import java.util.Map; import java.util.Set; + +@StaticallyInject public class SecretReference { private static final String secretPrefix = "SECRET"; private String configType; private Long version; private String value; + private final static String PASSWORD_TEXT = "password"; + private final static String PASSWD_TEXT = "passwd"; + + @Inject + private static Gson gson; + public SecretReference(String reference, Cluster cluster) throws AmbariException{ String[] values = reference.split(":"); @@ -75,6 +88,25 @@ public class SecretReference { } /** + * Helper function to mask a string of property bags that may contain a property with a password. + * @param propertyMap Property map to mask by replacing any passwords with the text "SECRET" + * @return New string with the passwords masked, or null if the property map is null. + */ + public static String maskPasswordInPropertyMap(String propertyMap) { + if (null == propertyMap) return null; + Map<String, String> maskedMap = new HashMap<>(); + Map<String, String> map = gson.fromJson(propertyMap, new TypeToken<Map<String, String>>() {}.getType()); + for (Map.Entry<String, String> e : map.entrySet()) { + String value = e.getValue(); + if (e.getKey().toLowerCase().contains(PASSWORD_TEXT) || e.getKey().toLowerCase().contains(PASSWD_TEXT)) { + value = secretPrefix; + } + maskedMap.put(e.getKey(), value); + } + return gson.toJson(maskedMap); + } + + /** * Replace secret references with appropriate real passwords. * @param targetMap map in which replacement will be performed * @param cluster current cluster
