Merge pull request #1164 from algairim/smart-159

Mask velues of sensitive keys of shell.env configuration in env strea…
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTaskTags.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTaskTags.java
index 5f6c657..8a7182f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTaskTags.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTaskTags.java
@@ -20,7 +20,9 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.Map;
@@ -36,6 +38,7 @@
 import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.mgmt.entitlement.EntitlementContext;
 import org.apache.brooklyn.api.objs.EntityAdjunct;
+import org.apache.brooklyn.core.config.Sanitizer;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext;
 import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
@@ -345,14 +348,26 @@
         return new WrappedStream(streamType, contents, size);
     }
     
-    /** creates a tag suitable for attaching a snapshot of an environment var map as a "stream" on a task;
-     * mainly for use with STREAM_ENV */ 
+    /**
+     * Creates a tag suitable for attaching a snapshot of an environment var map as a "stream" on a task; mainly for use
+     * with STREAM_ENV. Sensitive data like passwords is always masked, see {@link Sanitizer#IS_SECRET_PREDICATE}.
+     *
+     * @param streamEnv Never used
+     * @param env The {@link Map} with environment variables
+     * @return The {@link WrappedStream}
+     * */
     public static WrappedStream tagForEnvStream(String streamEnv, Map<?, ?> env) {
         StringBuilder sb = new StringBuilder();
         for (Map.Entry<?,?> kv: env.entrySet()) {
-            Object val = kv.getValue();
-            sb.append(kv.getKey()+"=" +
-                (val!=null ? BashStringEscapes.wrapBash(val.toString()) : "") + "\n");
+            String stringValue = kv.getValue() != null ? kv.getValue().toString() : "";
+            if (!stringValue.isEmpty()) {
+                if (Sanitizer.IS_SECRET_PREDICATE.apply(kv.getKey())) {
+                    String md5Checksum = Streams.getMd5Checksum(new ByteArrayInputStream(stringValue.getBytes()));
+                    stringValue = "<suppressed> (MD5 hash: " + md5Checksum + ")";
+                }
+                stringValue = BashStringEscapes.wrapBash(stringValue);
+            }
+            sb.append(kv.getKey()).append("=").append(stringValue).append("\n");
         }
         // TODO also make soft - this is often larger than the streams themselves
         return BrooklynTaskTags.tagForStream(BrooklynTaskTags.STREAM_ENV, Streams.byteArrayOfString(sb.toString()));