You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2016/04/07 23:19:40 UTC

ambari git commit: AMBARI-15773. Password must not by displayed by UpgradeItem and Stage resources in the API (alejandro)

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 <af...@hortonworks.com>
Authored: Thu Apr 7 14:13:38 2016 -0700
Committer: Alejandro Fernandez <af...@hortonworks.com>
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