This is an automated email from the ASF dual-hosted git repository.

dmitriusan pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 97a6bc8  AMBARI-24745. Enable encryption of sensitive data in Ambari 
DB using … (#2755)
97a6bc8 is described below

commit 97a6bc8b389fa5cfb73c87392af91e2d4d405ae3
Author: Lisnichenko Dmitro <dmitriu...@apache.org>
AuthorDate: Fri Jan 18 17:07:53 2019 +0200

    AMBARI-24745. Enable encryption of sensitive data in Ambari DB using … 
(#2755)
    
    AMBARI-24745. Enable encryption of sensitive data in Ambari DB using Ambari 
CLI (dlysnichenko)
---
 ambari-server/src/main/python/ambari-server.py     |   6 +-
 .../python/ambari_server/serverConfiguration.py    |   8 +-
 .../src/main/python/ambari_server/setupSecurity.py | 188 +++---
 ambari-server/src/test/python/TestAmbariServer.py  | 272 +--------
 .../src/test/python/TestSensitiveDataEncryption.py | 667 +++++++++++++++++++++
 5 files changed, 802 insertions(+), 339 deletions(-)

diff --git a/ambari-server/src/main/python/ambari-server.py 
b/ambari-server/src/main/python/ambari-server.py
index 4539879..78d5405 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -54,7 +54,7 @@ from ambari_server.setupActions import BACKUP_ACTION, 
LDAP_SETUP_ACTION, LDAP_SY
 from ambari_server.setupHttps import setup_https, setup_truststore
 from ambari_server.setupMpacks import install_mpack, uninstall_mpack, 
upgrade_mpack, STACK_DEFINITIONS_RESOURCE_NAME, \
   SERVICE_DEFINITIONS_RESOURCE_NAME, MPACKS_RESOURCE_NAME
-from ambari_server.setupSecurity import setup_ldap, sync_ldap, 
setup_master_key, setup_ambari_krb5_jaas, setup_pam, \
+from ambari_server.setupSecurity import setup_ldap, sync_ldap, 
setup_sensitive_data_encryption, setup_ambari_krb5_jaas, setup_pam, \
   migrate_ldap_pam, LDAP_TYPES
 from ambari_server.setupSso import setup_sso
 from ambari_server.setupTrustedProxy import setup_trusted_proxy
@@ -253,7 +253,7 @@ def refresh_stack_hash_action():
 def create_setup_security_actions(args):
   action_list = [
       ['setup-https', 'Enable HTTPS for Ambari server.', 
UserActionRestart(setup_https, args)],
-      ['encrypt-passwords', 'Encrypt passwords stored in ambari.properties 
file.', UserAction(setup_master_key, args)],
+      ['encrypt-passwords', 'Encrypt passwords managed by Ambari.', 
UserAction(setup_sensitive_data_encryption, args)],
       ['setup-kerberos-jaas', 'Setup Ambari kerberos JAAS configuration.', 
UserAction(setup_ambari_krb5_jaas, args)],
       ['setup-truststore', 'Setup truststore.', 
UserActionRestart(setup_truststore, args)],
       ['import-certificate', 'Import certificate to truststore.', 
UserActionRestart(setup_truststore, True, args)],
@@ -264,7 +264,7 @@ def create_setup_security_actions(args):
 def create_setup_security_actions(args):
   action_list = [
       ['setup-https', 'Enable HTTPS for Ambari server.', 
UserActionRestart(setup_https, args)],
-      ['encrypt-passwords', 'Encrypt passwords stored in ambari.properties 
file.', UserAction(setup_master_key, args)],
+      ['encrypt-passwords', 'Encrypt passwords managed by Ambari.', 
UserAction(setup_sensitive_data_encryption, args)],
       ['setup-kerberos-jaas', 'Setup Ambari kerberos JAAS configuration.', 
UserAction(setup_ambari_krb5_jaas, args)],
       ['setup-truststore', 'Setup truststore.', 
UserActionRestart(setup_truststore, args)],
       ['import-certificate', 'Import certificate to truststore.', 
UserActionRestart(setup_truststore, args, True)],
diff --git a/ambari-server/src/main/python/ambari_server/serverConfiguration.py 
b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
index fb0e0a2..f340ff6 100644
--- a/ambari-server/src/main/python/ambari_server/serverConfiguration.py
+++ b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
@@ -608,6 +608,7 @@ SECURITY_KEY_IS_PERSISTED = 
"security.master.key.ispersisted"
 SECURITY_KEY_ENV_VAR_NAME = "AMBARI_SECURITY_MASTER_KEY"
 SECURITY_MASTER_KEY_FILENAME = "master"
 SECURITY_IS_ENCRYPTION_ENABLED = "security.passwords.encryption.enabled"
+SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED = 
"security.server.encrypt_sensitive_data"
 SECURITY_KERBEROS_JASS_FILENAME = "krb5JAASLogin.conf"
 
 SECURITY_PROVIDER_GET_CMD = "{0} -cp {1} " + \
@@ -625,6 +626,11 @@ SECURITY_PROVIDER_KEY_CMD = "{0} -cp {1} " + \
                             ".MasterKeyServiceImpl {2} {3} {4} " + \
                             "> " + configDefaults.SERVER_OUT_FILE + " 2>&1"
 
+SECURITY_SENSITIVE_DATA_ENCRYPTON_CMD = "{0} -cp {1} " + \
+                            
"org.apache.ambari.server.security.encryption.SensitiveDataEncryption" + \
+                            " {2} " + \
+                            "> " + configDefaults.SERVER_OUT_FILE + " 2>&1"
+
 
 
 def read_ambari_user():
@@ -1045,7 +1051,7 @@ def get_original_master_key(properties, options = None):
           masterKey = options.master_key
         if not masterKey:
           masterKey = get_validated_string_input('Enter current Master Key: ',
-                                                 "", ".*", "", True, False)
+                                                 "", ".*", "", True, True)
           if options is not None:
             options.master_key = masterKey
       except KeyboardInterrupt:
diff --git a/ambari-server/src/main/python/ambari_server/setupSecurity.py 
b/ambari-server/src/main/python/ambari_server/setupSecurity.py
index 7952a07..460e147 100644
--- a/ambari-server/src/main/python/ambari_server/setupSecurity.py
+++ b/ambari-server/src/main/python/ambari_server/setupSecurity.py
@@ -47,8 +47,8 @@ from ambari_server.serverConfiguration import configDefaults, 
parse_properties_f
   BLIND_PASSWORD, BOOTSTRAP_DIR_PROPERTY, JDBC_PASSWORD_FILENAME, 
JDBC_PASSWORD_PROPERTY, \
   JDBC_RCA_PASSWORD_ALIAS, JDBC_RCA_PASSWORD_FILE_PROPERTY, 
JDBC_USE_INTEGRATED_AUTH_PROPERTY, \
   LDAP_MGR_PASSWORD_ALIAS, LDAP_MGR_PASSWORD_PROPERTY, CLIENT_SECURITY, \
-  SECURITY_IS_ENCRYPTION_ENABLED, SECURITY_KEY_ENV_VAR_NAME, 
SECURITY_KERBEROS_JASS_FILENAME, \
-  SECURITY_PROVIDER_KEY_CMD, SECURITY_MASTER_KEY_FILENAME, 
SSL_TRUSTSTORE_PASSWORD_ALIAS, \
+  SECURITY_IS_ENCRYPTION_ENABLED, SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED, 
SECURITY_KEY_ENV_VAR_NAME, SECURITY_KERBEROS_JASS_FILENAME, \
+  SECURITY_PROVIDER_KEY_CMD, SECURITY_SENSITIVE_DATA_ENCRYPTON_CMD, 
SECURITY_MASTER_KEY_FILENAME, SSL_TRUSTSTORE_PASSWORD_ALIAS, \
   SSL_TRUSTSTORE_PASSWORD_PROPERTY, SSL_TRUSTSTORE_PATH_PROPERTY, 
SSL_TRUSTSTORE_TYPE_PROPERTY, \
   JDK_NAME_PROPERTY, JCE_NAME_PROPERTY, JAVA_HOME_PROPERTY, \
   get_resources_location, SECURITY_MASTER_KEY_LOCATION, SETUP_OR_UPGRADE_MSG, \
@@ -487,9 +487,24 @@ def sync_ldap(options):
   sys.stdout.write('\n')
   sys.stdout.flush()
 
-def setup_master_key(options):
+def sensitive_data_encryption(options, direction, masterKey=None):
+  environ = os.environ.copy()
+  if masterKey:
+    environ[SECURITY_KEY_ENV_VAR_NAME] = masterKey
+  jdk_path = find_jdk()
+  if jdk_path is None:
+    print_error_msg("No JDK found, please run the \"setup\" "
+                    "command to install a JDK automatically or install any "
+                    "JDK manually to " + configDefaults.JDK_INSTALL_DIR)
+    return 1
+  serverClassPath = ServerClassPath(get_ambari_properties(), options)
+  command = SECURITY_SENSITIVE_DATA_ENCRYPTON_CMD.format(get_java_exe_path(), 
serverClassPath.get_full_ambari_classpath_escaped_for_shell(), direction)
+  (retcode, stdout, stderr) = run_os_command(command, environ)
+  pass
+
+def setup_sensitive_data_encryption(options):
   if not is_root():
-    warn = 'ambari-server setup-https is run as ' \
+    warn = 'ambari-server encrypt-passwords is run as ' \
           'non-root user, some sudo privileges might be required'
     print warn
 
@@ -516,76 +531,67 @@ def setup_master_key(options):
 
   ts_password = properties.get_property(SSL_TRUSTSTORE_PASSWORD_PROPERTY)
   resetKey = False
+  decrypt = False
   masterKey = None
 
   if isSecure:
     print "Password encryption is enabled."
-    resetKey = True if options.security_option is not None else 
get_YN_input("Do you want to reset Master Key? [y/n] (n): ", False)
-
-  # For encrypting of only unencrypted passwords without resetting the key ask
-  # for master key if not persisted.
-  if isSecure and not isPersisted and not resetKey:
-    print "Master Key not persisted."
-    masterKey = get_original_master_key(properties, options)
-  pass
+    decrypt = get_YN_input("Do you want to decrypt passwords managed by 
Ambari? [y/n] (n): ", False)
+    if not decrypt:
+      resetKey = get_YN_input("Do you want to reset Master Key? [y/n] (n): ", 
False)
 
   # Make sure both passwords are clear-text if master key is lost
-  if resetKey:
-    if not isPersisted:
+  if resetKey or decrypt:
+    if isPersisted:
+      sensitive_data_encryption(options, "decryption")
+    else:
       print "Master Key not persisted."
       masterKey = get_original_master_key(properties, options)
       # Unable get the right master key or skipped question <enter>
       if not masterKey:
-        print "To disable encryption, do the following:"
-        print "- Edit " + find_properties_file() + \
-              " and set " + SECURITY_IS_ENCRYPTION_ENABLED + " = " + "false."
-        err = "{0} is already encrypted. Please call {1} to store unencrypted" 
\
-              " password and call 'encrypt-passwords' again."
-        if db_sql_auth and db_password and is_alias_string(db_password):
-          print err.format('- Database password', "'" + SETUP_ACTION + "'")
-        if ts_password and is_alias_string(ts_password):
-          print err.format('TrustStore password', "'" + LDAP_SETUP_ACTION + 
"'")
-
+        # todo fix unreachable code
+        printManualDecryptionWarning(db_password, db_sql_auth, ts_password)
         return 1
-      pass
-    pass
-  pass
+      sensitive_data_encryption(options, "decryption", masterKey)
 
   # Read back any encrypted passwords
-  if db_sql_auth  and db_password and is_alias_string(db_password):
-    db_password = read_passwd_for_alias(JDBC_RCA_PASSWORD_ALIAS, masterKey)
-  if ts_password and is_alias_string(ts_password):
-    ts_password = read_passwd_for_alias(SSL_TRUSTSTORE_PASSWORD_ALIAS, 
masterKey)
-  # Read master key, if non-secure or reset is true
-  if resetKey or not isSecure:
-    masterKey = read_master_key(resetKey, options)
-    persist = get_YN_input("Do you want to persist master key. If you choose " 
\
-                           "not to persist, you need to provide the Master " \
-                           "Key while starting the ambari server as an env " \
-                           "variable named " + SECURITY_KEY_ENV_VAR_NAME + \
-                           " or the start will prompt for the master key."
-                           " Persist [y/n] (y)? ", True, 
options.master_key_persist)
-    if persist:
-      save_master_key(options, masterKey, get_master_key_location(properties) 
+ os.sep +
-                      SECURITY_MASTER_KEY_FILENAME, persist)
-    elif not persist and masterKeyFile:
-      try:
-        os.remove(masterKeyFile)
-        print_info_msg("Deleting master key file at location: " + str(
-          masterKeyFile))
-      except Exception, e:
-        print 'ERROR: Could not remove master key file. %s' % e
-    # Blow up the credential store made with previous key, if any
-    store_file = get_credential_store_location(properties)
-    if os.path.exists(store_file):
-      try:
-        os.remove(store_file)
-      except:
-        print_warning_msg("Failed to remove credential store file.")
-      pass
-    pass
-  pass
+  db_password, ts_password = deryptPasswordsConfigs(db_password, db_sql_auth, 
masterKey, ts_password)
+  save_decrypted_ambari_properties(db_password, properties, ts_password)
+
 
+  if not decrypt:
+    if resetKey or not isSecure:
+      # Read master key and encrypt sensitive data, if non-secure or reset is 
true
+      masterKey, isPersisted = setup_master_key(masterKeyFile, options, 
properties, resetKey)
+    else:
+      if not isPersisted:
+        # For encrypting of only unencrypted passwords without resetting the 
key ask
+        # for master key if not persisted.
+        print "Master Key not persisted."
+        masterKey = get_original_master_key(properties, options)
+    encrypt_sensitive_data(db_password, masterKey, options, isPersisted, 
properties, ts_password)
+
+  # Since files for store and master are created we need to ensure correct
+  # permissions
+  ambari_user = read_ambari_user()
+  if ambari_user:
+    adjust_directory_permissions(ambari_user)
+  return 0
+
+
+def save_decrypted_ambari_properties(db_password, properties, ts_password):
+  propertyMap = {SECURITY_IS_ENCRYPTION_ENABLED: 'false'}
+  propertyMap[SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED] = 'false'
+  if db_password:
+    propertyMap[JDBC_PASSWORD_PROPERTY] = db_password
+    if properties.get_property(JDBC_RCA_PASSWORD_FILE_PROPERTY):
+      propertyMap[JDBC_RCA_PASSWORD_FILE_PROPERTY] = db_password
+  if ts_password:
+    propertyMap[SSL_TRUSTSTORE_PASSWORD_PROPERTY] = ts_password
+  update_properties_2(properties, propertyMap)
+
+
+def encrypt_sensitive_data(db_password, masterKey, options, persist, 
properties, ts_password):
   propertyMap = {SECURITY_IS_ENCRYPTION_ENABLED: 'true'}
   # Encrypt only un-encrypted passwords
   if db_password and not is_alias_string(db_password):
@@ -597,7 +603,6 @@ def setup_master_key(options):
       remove_password_file(JDBC_PASSWORD_FILENAME)
       if properties.get_property(JDBC_RCA_PASSWORD_FILE_PROPERTY):
         propertyMap[JDBC_RCA_PASSWORD_FILE_PROPERTY] = 
get_alias_string(JDBC_RCA_PASSWORD_ALIAS)
-  pass
 
   if ts_password and not is_alias_string(ts_password):
     retCode = save_passwd_for_alias(SSL_TRUSTSTORE_PASSWORD_ALIAS, 
ts_password, masterKey)
@@ -605,17 +610,64 @@ def setup_master_key(options):
       print 'Failed to save secure TrustStore password.'
     else:
       propertyMap[SSL_TRUSTSTORE_PASSWORD_PROPERTY] = 
get_alias_string(SSL_TRUSTSTORE_PASSWORD_ALIAS)
-  pass
 
+  propertyMap[SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED] = 'true'
+  if persist:
+    sensitive_data_encryption(options, "encryption")
+  else:
+    sensitive_data_encryption(options, "encryption", masterKey)
   update_properties_2(properties, propertyMap)
 
-  # Since files for store and master are created we need to ensure correct
-  # permissions
-  ambari_user = read_ambari_user()
-  if ambari_user:
-    adjust_directory_permissions(ambari_user)
 
-  return 0
+def setup_master_key(masterKeyFile, options, properties, resetKey):
+  masterKey = read_master_key(resetKey, options)
+  persist = get_YN_input("Do you want to persist master key. If you choose " \
+                         "not to persist, you need to provide the Master " \
+                         "Key while starting the ambari server as an env " \
+                         "variable named " + SECURITY_KEY_ENV_VAR_NAME + \
+                         " or the start will prompt for the master key."
+                         " Persist [y/n] (y)? ", True, 
options.master_key_persist)
+  if persist:
+    save_master_key(options, masterKey, get_master_key_location(properties) + 
os.sep +
+                    SECURITY_MASTER_KEY_FILENAME, persist)
+  elif not persist and masterKeyFile:
+    try:
+      os.remove(masterKeyFile)
+      print_info_msg("Deleting master key file at location: " + str(
+        masterKeyFile))
+    except Exception, e:
+      print 'ERROR: Could not remove master key file. %s' % e
+  # Blow up the credential store made with previous key, if any
+  store_file = get_credential_store_location(properties)
+  if os.path.exists(store_file):
+    try:
+      os.remove(store_file)
+    except:
+      print_warning_msg("Failed to remove credential store file.")
+  return masterKey, persist
+
+
+def deryptPasswordsConfigs(db_password, db_sql_auth, masterKey, ts_password):
+  if db_sql_auth and db_password and is_alias_string(db_password):
+    db_password = read_passwd_for_alias(JDBC_RCA_PASSWORD_ALIAS, masterKey)
+  if ts_password and is_alias_string(ts_password):
+    ts_password = read_passwd_for_alias(SSL_TRUSTSTORE_PASSWORD_ALIAS, 
masterKey)
+  return db_password, ts_password
+
+
+def printManualDecryptionWarning(db_password, db_sql_auth, ts_password):
+  print "To disable encryption, do the following:"
+  print "- Edit " + find_properties_file() + \
+        " and set " + SECURITY_IS_ENCRYPTION_ENABLED + " = " + "false." + \
+        " and set " + SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED + " = " + 
"false." + \
+        " and set all passwords and sensitive data in service configs to right 
value."
+  err = "{0} is already encrypted. Please call {1} to store unencrypted" \
+        " password and call 'encrypt-passwords' again."
+  if db_sql_auth and db_password and is_alias_string(db_password):
+    print err.format('- Database password', "'" + SETUP_ACTION + "'")
+  if ts_password and is_alias_string(ts_password):
+    print err.format('TrustStore password', "'" + LDAP_SETUP_ACTION + "'")
+
 
 def setup_ambari_krb5_jaas(options):
   jaas_conf_file = search_file(SECURITY_KERBEROS_JASS_FILENAME, get_conf_dir())
diff --git a/ambari-server/src/test/python/TestAmbariServer.py 
b/ambari-server/src/test/python/TestAmbariServer.py
index ebf0a9d..7089ecf 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -92,7 +92,7 @@ with patch.object(platform, "linux_distribution", 
return_value = MagicMock(retur
                   RESOURCES_DIR_PROPERTY, JDBC_RCA_PASSWORD_ALIAS, 
JDBC_RCA_SCHEMA_PROPERTY, \
                   SSL_API, SSL_API_PORT, CLIENT_API_PORT_PROPERTY,\
                   JDBC_CONNECTION_POOL_TYPE, LDAP_MGR_PASSWORD_PROPERTY, 
LDAP_MGR_PASSWORD_ALIAS, JDBC_PASSWORD_FILENAME, NR_USER_PROPERTY, 
SECURITY_KEY_IS_PERSISTED, \
-                  SSL_TRUSTSTORE_PASSWORD_PROPERTY, 
SECURITY_IS_ENCRYPTION_ENABLED, PID_DIR_PROPERTY, 
SSL_TRUSTSTORE_PASSWORD_ALIAS, \
+                  SECURITY_IS_ENCRYPTION_ENABLED, PID_DIR_PROPERTY, \
                   SECURITY_MASTER_KEY_LOCATION, SECURITY_KEYS_DIR, 
store_password_file, \
                   get_pass_file_path, GET_FQDN_SERVICE_URL, 
SECURITY_KEY_ENV_VAR_NAME, \
                   JAVA_HOME_PROPERTY, JDK_NAME_PROPERTY, JCE_NAME_PROPERTY, 
STACK_LOCATION_KEY, SERVER_VERSION_FILE_PATH, \
@@ -108,7 +108,7 @@ with patch.object(platform, "linux_distribution", 
return_value = MagicMock(retur
                   SSL_DATE_FORMAT, import_cert_and_key, is_valid_cert_host, 
setup_truststore, \
                   SRVR_ONE_WAY_SSL_PORT_PROPERTY, 
SRVR_TWO_WAY_SSL_PORT_PROPERTY
                 from ambari_server.setupSecurity import 
adjust_directory_permissions, get_alias_string, get_ldap_event_spec_names, 
sync_ldap, \
-                  configure_ldap_password, setup_ldap, REGEX_HOSTNAME_PORT, 
REGEX_TRUE_FALSE, REGEX_ANYTHING, setup_master_key, \
+                  configure_ldap_password, setup_ldap, REGEX_HOSTNAME_PORT, 
REGEX_TRUE_FALSE, REGEX_ANYTHING,\
                   setup_ambari_krb5_jaas, LDAP_GENERIC, 
should_query_ldap_type, LdapPropTemplate, LdapDefault, LdapDefaultMap
                 from ambari_server.userInput import get_YN_input, 
get_choice_string_input, get_validated_string_input, \
                   read_password
@@ -313,13 +313,13 @@ class TestAmbariServer(TestCase):
 
   @patch.object(OSCheck, "os_distribution", new = MagicMock(return_value = 
os_distro_value))
   @patch.object(_ambari_server_, "setup_ambari_krb5_jaas")
-  @patch.object(_ambari_server_, "setup_master_key")
+  @patch.object(_ambari_server_, "setup_sensitive_data_encryption")
   @patch.object(_ambari_server_, "setup_truststore")
   @patch.object(_ambari_server_, "setup_https")
   @patch.object(_ambari_server_, "get_validated_string_input")
   @patch.object(_ambari_server_, "logger")
   def test_setup_security(self, logger_mock, get_validated_string_input_mock, 
setup_https_mock,
-                          setup_truststore_mock, setup_master_key_mock,
+                          setup_truststore_mock, 
setup_sensitive_data_encryption_mock,
                           setup_ambari_krb5_jaas_mock):
 
     args = self._create_empty_options_mock()
@@ -329,7 +329,7 @@ class TestAmbariServer(TestCase):
 
     get_validated_string_input_mock.return_value = '2'
     _ambari_server_.setup_security(args)
-    self.assertTrue(setup_master_key_mock.called)
+    self.assertTrue(setup_sensitive_data_encryption_mock.called)
 
     get_validated_string_input_mock.return_value = '3'
     _ambari_server_.setup_security(args)
@@ -6724,197 +6724,6 @@ class TestAmbariServer(TestCase):
     sys.stdout = sys.__stdout__
     pass
 
-  @patch("os.path.exists")
-  @patch("ambari_server.setupSecurity.get_is_secure")
-  @patch("ambari_server.setupSecurity.get_is_persisted")
-  @patch("ambari_server.setupSecurity.remove_password_file")
-  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
-  @patch("ambari_server.setupSecurity.read_master_key")
-  @patch("ambari_server.setupSecurity.read_ambari_user")
-  @patch("ambari_server.setupSecurity.get_master_key_location")
-  @patch("ambari_server.setupSecurity.update_properties_2")
-  @patch("ambari_server.setupSecurity.save_master_key")
-  @patch("ambari_server.setupSecurity.get_YN_input")
-  @patch("ambari_server.setupSecurity.search_file")
-  @patch("ambari_server.setupSecurity.get_ambari_properties")
-  @patch("ambari_server.setupSecurity.is_root")
-  def test_setup_master_key_not_persist(self, is_root_method,
-                                        get_ambari_properties_method, 
search_file_message,
-                                        get_YN_input_method, 
save_master_key_method,
-                                        update_properties_method, 
get_master_key_location_method,
-                                        read_ambari_user_method, 
read_master_key_method,
-                                        save_passwd_for_alias_method, 
remove_password_file_method,
-                                        get_is_persisted_method, 
get_is_secure_method, exists_mock):
-
-    is_root_method.return_value = True
-
-    p = Properties()
-    FAKE_PWD_STRING = "fakepasswd"
-    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
-    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
-    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
-    get_ambari_properties_method.return_value = p
-
-    read_master_key_method.return_value = "aaa"
-    get_YN_input_method.return_value = False
-    read_ambari_user_method.return_value = None
-    save_passwd_for_alias_method.return_value = 0
-    get_is_persisted_method.return_value = (True, "filepath")
-    get_is_secure_method.return_value = False
-    exists_mock.return_value = False
-
-    options = self._create_empty_options_mock()
-    setup_master_key(options)
-
-    self.assertTrue(get_YN_input_method.called)
-    self.assertTrue(read_master_key_method.called)
-    self.assertTrue(read_ambari_user_method.called)
-    self.assertTrue(update_properties_method.called)
-    self.assertFalse(save_master_key_method.called)
-    self.assertTrue(save_passwd_for_alias_method.called)
-    self.assertEquals(2, save_passwd_for_alias_method.call_count)
-    self.assertTrue(remove_password_file_method.called)
-
-    result_expected = {JDBC_PASSWORD_PROPERTY:
-                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
-                       JDBC_RCA_PASSWORD_FILE_PROPERTY:
-                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
-                       SSL_TRUSTSTORE_PASSWORD_PROPERTY:
-                         get_alias_string(SSL_TRUSTSTORE_PASSWORD_ALIAS),
-                       SECURITY_IS_ENCRYPTION_ENABLED: 'true'}
-
-    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
-    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
-                      key=operator.itemgetter(0))
-    self.assertEquals(sorted_x, sorted_y)
-    pass
-
-
-  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
-  @patch("os.path.exists")
-  @patch("ambari_server.setupSecurity.get_is_secure")
-  @patch("ambari_server.setupSecurity.get_is_persisted")
-  @patch("ambari_server.setupSecurity.read_master_key")
-  @patch("ambari_server.setupSecurity.read_ambari_user")
-  @patch("ambari_server.setupSecurity.get_master_key_location")
-  @patch("ambari_server.setupSecurity.update_properties_2")
-  @patch("ambari_server.setupSecurity.save_master_key")
-  @patch("ambari_server.setupSecurity.get_YN_input")
-  @patch("ambari_server.serverConfiguration.search_file")
-  @patch("ambari_server.setupSecurity.get_ambari_properties")
-  @patch("ambari_server.setupSecurity.is_root")
-  def test_setup_master_key_persist(self, is_root_method,
-                                    get_ambari_properties_method, 
search_file_message,
-                                    get_YN_input_method, 
save_master_key_method,
-                                    update_properties_method, 
get_master_key_location_method,
-                                    read_ambari_user_method, 
read_master_key_method,
-                                    get_is_persisted_method, 
get_is_secure_method, exists_mock,
-                                    save_passwd_for_alias_method):
-    is_root_method.return_value = True
-
-    p = Properties()
-    FAKE_PWD_STRING = "fakepasswd"
-    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
-    get_ambari_properties_method.return_value = p
-
-    search_file_message.return_value = "propertiesfile"
-
-    read_master_key_method.return_value = "aaa"
-    get_YN_input_method.side_effect = [True, False]
-    read_ambari_user_method.return_value = None
-    get_is_persisted_method.return_value = (True, "filepath")
-    get_is_secure_method.return_value = False
-    exists_mock.return_value = False
-    save_passwd_for_alias_method.return_value = 0
-
-    options = self._create_empty_options_mock()
-    setup_master_key(options)
-
-    self.assertTrue(get_YN_input_method.called)
-    self.assertTrue(read_master_key_method.called)
-    self.assertTrue(read_ambari_user_method.called)
-    self.assertTrue(update_properties_method.called)
-    self.assertTrue(save_master_key_method.called)
-
-    result_expected = {JDBC_PASSWORD_PROPERTY:
-                        get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
-                        SECURITY_IS_ENCRYPTION_ENABLED: 'true'}
-
-    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
-    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
-                      key=operator.itemgetter(0))
-    self.assertEquals(sorted_x, sorted_y)
-    pass
-
-
-  @patch("ambari_server.setupSecurity.read_master_key")
-  @patch("ambari_server.setupSecurity.remove_password_file")
-  @patch("os.path.exists")
-  @patch("ambari_server.setupSecurity.read_ambari_user")
-  @patch("ambari_server.setupSecurity.get_master_key_location")
-  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
-  @patch("ambari_server.setupSecurity.read_passwd_for_alias")
-  @patch("ambari_server.setupSecurity.update_properties_2")
-  @patch("ambari_server.setupSecurity.save_master_key")
-  @patch("ambari_server.setupSecurity.get_validated_string_input")
-  @patch("ambari_server.setupSecurity.get_YN_input")
-  @patch("ambari_server.setupSecurity.search_file")
-  @patch("ambari_server.setupSecurity.get_ambari_properties")
-  @patch("ambari_server.setupSecurity.is_root")
-  def test_reset_master_key_persisted(self, is_root_method,
-                                      get_ambari_properties_method, 
search_file_message,
-                                      get_YN_input_method, 
get_validated_string_input_method,
-                                      save_master_key_method, 
update_properties_method,
-                                      read_passwd_for_alias_method, 
save_passwd_for_alias_method,
-                                      get_master_key_location_method,
-                                      read_ambari_user_method, exists_mock,
-                                      remove_password_file_method, 
read_master_key_method):
-
-    # Testing call under root
-    is_root_method.return_value = True
-
-    search_file_message.return_value = "filepath"
-    read_ambari_user_method.return_value = None
-
-    p = Properties()
-    FAKE_PWD_STRING = '${alias=fakealias}'
-    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
-    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
-    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
-    get_ambari_properties_method.return_value = p
-
-    get_YN_input_method.side_effect = [True, True]
-    read_master_key_method.return_value = "aaa"
-    read_passwd_for_alias_method.return_value = "fakepassword"
-    save_passwd_for_alias_method.return_value = 0
-    exists_mock.return_value = False
-
-
-    options = self._create_empty_options_mock()
-    setup_master_key(options)
-
-    self.assertTrue(save_master_key_method.called)
-    self.assertTrue(get_YN_input_method.called)
-    self.assertTrue(read_master_key_method.called)
-    self.assertTrue(update_properties_method.called)
-    self.assertTrue(read_passwd_for_alias_method.called)
-    self.assertTrue(2, read_passwd_for_alias_method.call_count)
-    self.assertTrue(2, save_passwd_for_alias_method.call_count)
-
-    result_expected = {JDBC_PASSWORD_PROPERTY:
-                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
-                       JDBC_RCA_PASSWORD_FILE_PROPERTY:
-                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
-                       SSL_TRUSTSTORE_PASSWORD_PROPERTY:
-                         get_alias_string(SSL_TRUSTSTORE_PASSWORD_ALIAS),
-                       SECURITY_IS_ENCRYPTION_ENABLED: 'true'}
-
-    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
-    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
-                      key=operator.itemgetter(0))
-    self.assertEquals(sorted_x, sorted_y)
-    pass
-
   @patch("os.path.isdir", new = MagicMock(return_value=True))
   @patch("os.access", new = MagicMock(return_value=True))
   @patch.object(ServerClassPath, 
"get_full_ambari_classpath_escaped_for_shell", new = MagicMock(return_value = 
'test' + os.pathsep + 'path12'))
@@ -6953,77 +6762,6 @@ class TestAmbariServer(TestCase):
 
     pass
 
-  @patch("ambari_server.setupSecurity.get_is_persisted")
-  @patch("ambari_server.setupSecurity.get_is_secure")
-  @patch("ambari_server.setupSecurity.remove_password_file")
-  @patch("os.path.exists")
-  @patch("ambari_server.setupSecurity.read_ambari_user")
-  @patch("ambari_server.setupSecurity.get_master_key_location")
-  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
-  @patch("ambari_server.setupSecurity.read_passwd_for_alias")
-  @patch("ambari_server.setupSecurity.update_properties_2")
-  @patch("ambari_server.setupSecurity.save_master_key")
-  @patch("ambari_server.setupSecurity.get_validated_string_input")
-  @patch("ambari_server.setupSecurity.get_YN_input")
-  @patch("ambari_server.setupSecurity.search_file")
-  @patch("ambari_server.setupSecurity.get_ambari_properties")
-  @patch("ambari_server.setupSecurity.is_root")
-  def test_reset_master_key_not_persisted(self, is_root_method,
-                                          get_ambari_properties_method,
-                                          search_file_message, 
get_YN_input_method,
-                                          get_validated_string_input_method, 
save_master_key_method,
-                                          update_properties_method, 
read_passwd_for_alias_method,
-                                          save_passwd_for_alias_method,
-                                          get_master_key_location_method, 
read_ambari_user_method,
-                                          exists_mock, 
remove_password_file_method, get_is_secure_method,
-                                          get_is_persisted_method):
-
-    is_root_method.return_value = True
-    search_file_message.return_value = False
-    read_ambari_user_method.return_value = None
-
-    p = Properties()
-    FAKE_PWD_STRING = '${alias=fakealias}'
-    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
-    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
-    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
-    get_ambari_properties_method.return_value = p
-
-    get_YN_input_method.side_effect = [True, False]
-    get_validated_string_input_method.return_value = "aaa"
-    read_passwd_for_alias_method.return_value = "fakepassword"
-    save_passwd_for_alias_method.return_value = 0
-    exists_mock.return_value = False
-    get_is_secure_method.return_value = True
-    get_is_persisted_method.return_value = (True, "filePath")
-
-    options = self._create_empty_options_mock()
-    setup_master_key(options)
-
-    self.assertFalse(save_master_key_method.called)
-    self.assertTrue(get_YN_input_method.called)
-    self.assertTrue(get_validated_string_input_method.called)
-    self.assertTrue(update_properties_method.called)
-    self.assertTrue(read_passwd_for_alias_method.called)
-    self.assertTrue(2, read_passwd_for_alias_method.call_count)
-    self.assertTrue(2, save_passwd_for_alias_method.call_count)
-    self.assertFalse(save_master_key_method.called)
-
-    result_expected = {JDBC_PASSWORD_PROPERTY:
-                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
-                       JDBC_RCA_PASSWORD_FILE_PROPERTY:
-                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
-                       SSL_TRUSTSTORE_PASSWORD_PROPERTY:
-                         get_alias_string(SSL_TRUSTSTORE_PASSWORD_ALIAS),
-                       SECURITY_IS_ENCRYPTION_ENABLED: 'true'}
-
-    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
-    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
-                      key=operator.itemgetter(0))
-    self.assertEquals(sorted_x, sorted_y)
-    pass
-
-
   @staticmethod
   @OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
   def _init_test_ldap_properties_map_invalid_input_1():
diff --git a/ambari-server/src/test/python/TestSensitiveDataEncryption.py 
b/ambari-server/src/test/python/TestSensitiveDataEncryption.py
new file mode 100644
index 0000000..4e839c4
--- /dev/null
+++ b/ambari-server/src/test/python/TestSensitiveDataEncryption.py
@@ -0,0 +1,667 @@
+'''
+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.
+'''
+import os
+import sys
+
+from ambari_commons.exceptions import FatalException
+from mock.mock import patch, MagicMock, call
+
+with patch.object(os, "geteuid", new=MagicMock(return_value=0)):
+  from resource_management.core import sudo
+  reload(sudo)
+
+import operator
+import platform
+import StringIO
+from unittest import TestCase
+os.environ["ROOT"] = ""
+
+from only_for_platform import get_platform, os_distro_value, PLATFORM_WINDOWS
+from ambari_commons import os_utils
+
+if get_platform() != PLATFORM_WINDOWS:
+  pass
+
+import shutil
+project_dir = 
os.path.join(os.path.abspath(os.path.dirname(__file__)),os.path.normpath("../../../../"))
+shutil.copyfile(project_dir+"/ambari-server/conf/unix/ambari.properties", 
"/tmp/ambari.properties")
+
+# We have to use this import HACK because the filename contains a dash
+_search_file = os_utils.search_file
+
+
+def search_file_proxy(filename, searchpatch, pathsep=os.pathsep):
+  global _search_file
+
+  if "ambari.properties" in filename:
+    return "/tmp/ambari.properties"
+
+  return _search_file(filename, searchpatch, pathsep)
+
+
+os_utils.search_file = search_file_proxy
+with patch.object(platform, "linux_distribution", return_value = 
MagicMock(return_value=('Redhat', '6.4', 'Final'))):
+  with patch("os.path.isdir", return_value = MagicMock(return_value=True)):
+    with patch("os.access", return_value = MagicMock(return_value=True)):
+      with patch.object(os_utils, "parse_log4j_file", 
return_value={'ambari.log.dir': '/var/log/ambari-server'}):
+        with patch("platform.linux_distribution", return_value = 
os_distro_value):
+          with patch("os.symlink"):
+            with patch("glob.glob", return_value = 
['/etc/init.d/postgresql-9.3']):
+              _ambari_server_ = __import__('ambari-server')
+              with patch("__builtin__.open"):
+                from ambari_server.properties import Properties
+                from ambari_server.serverConfiguration import configDefaults, 
JDBC_RCA_PASSWORD_FILE_PROPERTY, JDBC_PASSWORD_PROPERTY, \
+  JDBC_RCA_PASSWORD_ALIAS, SSL_TRUSTSTORE_PASSWORD_PROPERTY, 
SECURITY_IS_ENCRYPTION_ENABLED, \
+  SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED, SSL_TRUSTSTORE_PASSWORD_ALIAS, 
SECURITY_KEY_ENV_VAR_NAME
+                from ambari_server.setupSecurity import get_alias_string, 
setup_sensitive_data_encryption, sensitive_data_encryption
+                from ambari_server.serverClassPath import ServerClassPath
+
+
+@patch.object(platform, "linux_distribution", new = 
MagicMock(return_value=('Redhat', '6.4', 'Final')))
+@patch("ambari_server.dbConfiguration_linux.get_postgre_hba_dir", new = 
MagicMock(return_value = "/var/lib/pgsql/data"))
+@patch("ambari_server.dbConfiguration_linux.get_postgre_running_status", new = 
MagicMock(return_value = "running"))
+class TestSensitiveDataEncryption(TestCase):
+  def setUp(self):
+    out = StringIO.StringIO()
+    sys.stdout = out
+
+
+  def tearDown(self):
+    sys.stdout = sys.__stdout__
+
+  @patch("os.path.isdir", new = MagicMock(return_value=True))
+  @patch("os.access", new = MagicMock(return_value=True))
+  @patch.object(ServerClassPath, 
"get_full_ambari_classpath_escaped_for_shell", new = MagicMock(return_value = 
'test' + os.pathsep + 'path12'))
+  @patch("ambari_server.setupSecurity.find_jdk")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.run_os_command")
+  def test_sensitive_data_encryption(self, run_os_command_mock, 
get_ambari_properties_method, find_jdk_mock):
+    find_jdk_mock.return_value = "/"
+    environ = os.environ.copy()
+
+    run_os_command_mock.return_value = 0,"",""
+    properties = Properties()
+    get_ambari_properties_method.return_value = properties
+    options = self._create_empty_options_mock()
+    sensitive_data_encryption(options, "encription")
+    run_os_command_mock.assert_called_with('None -cp test:path12 
org.apache.ambari.server.security.encryption.SensitiveDataEncryption encription 
> /var/log/ambari-server/ambari-server.out 2>&1', environ)
+    pass
+
+  @patch("ambari_server.setupSecurity.print_error_msg")
+  @patch("ambari_server.setupSecurity.find_jdk")
+  def test_sensitive_data_encryption_nojdk(self, find_jdk_mock, print_mock):
+    find_jdk_mock.return_value = None
+
+    options = self._create_empty_options_mock()
+    code = sensitive_data_encryption(options, "encription")
+    self.assertEquals(code, 1)
+    print_mock.assert_called_with("No JDK found, please run the \"setup\" "
+                                  "command to install a JDK automatically or 
install any "
+                                  "JDK manually to " + 
configDefaults.JDK_INSTALL_DIR)
+    pass
+
+  @patch("os.path.isdir", new = MagicMock(return_value=True))
+  @patch("os.access", new = MagicMock(return_value=True))
+  @patch.object(ServerClassPath, 
"get_full_ambari_classpath_escaped_for_shell", new = MagicMock(return_value = 
'test' + os.pathsep + 'path12'))
+  @patch("ambari_server.setupSecurity.find_jdk")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.run_os_command")
+  def test_sensitive_data_decryption_not_persisted(self, run_os_command_mock, 
get_ambari_properties_method, find_jdk_mock):
+    find_jdk_mock.return_value = "/"
+    environ = os.environ.copy()
+    master = "master"
+    environ[SECURITY_KEY_ENV_VAR_NAME] = master
+
+    run_os_command_mock.return_value = 0,"",""
+    properties = Properties()
+    get_ambari_properties_method.return_value = properties
+    options = self._create_empty_options_mock()
+    sensitive_data_encryption(options, "decryption", master)
+    run_os_command_mock.assert_called_with('None -cp test:path12 
org.apache.ambari.server.security.encryption.SensitiveDataEncryption decryption 
> /var/log/ambari-server/ambari-server.out 2>&1', environ)
+    pass
+
+  @patch("ambari_server.setupSecurity.get_is_persisted")
+  @patch("ambari_server.setupSecurity.get_is_secure")
+  @patch("os.path.exists")
+  @patch("ambari_server.setupSecurity.read_ambari_user")
+  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.read_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.update_properties_2")
+  @patch("ambari_server.setupSecurity.save_master_key")
+  @patch("ambari_server.setupSecurity.get_validated_string_input")
+  @patch("ambari_server.setupSecurity.get_YN_input")
+  @patch("ambari_server.setupSecurity.search_file")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.is_root")
+  @patch("ambari_server.setupSecurity.sensitive_data_encryption")
+  @patch("ambari_server.setupSecurity.get_original_master_key")
+  def test_reset_master_key_not_persisted(self, get_original_master_key_mock, 
sensitive_data_encryption_metod, is_root_method,
+                                          get_ambari_properties_method,
+                                          search_file_message, 
get_YN_input_method,
+                                          get_validated_string_input_method, 
save_master_key_method,
+                                          update_properties_method, 
read_passwd_for_alias_method,
+                                          save_passwd_for_alias_method,
+                                          read_ambari_user_method,
+                                          exists_mock, get_is_secure_method,
+                                          get_is_persisted_method):
+
+    is_root_method.return_value = True
+    search_file_message.return_value = False
+    read_ambari_user_method.return_value = None
+
+    p = Properties()
+    FAKE_PWD_STRING = '${alias=fakealias}'
+    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
+    get_ambari_properties_method.return_value = p
+
+    master_key = "aaa"
+    get_YN_input_method.side_effect = [False, True, False]
+    get_validated_string_input_method.return_value = master_key
+    get_original_master_key_mock.return_value = master_key
+    read_passwd_for_alias_method.return_value = "fakepassword"
+    save_passwd_for_alias_method.return_value = 0
+    exists_mock.return_value = False
+    get_is_secure_method.return_value = True
+    get_is_persisted_method.return_value = (False, "")
+
+    options = self._create_empty_options_mock()
+    setup_sensitive_data_encryption(options)
+    calls = [call(options, "decryption", master_key), call(options, 
"encryption", master_key)]
+    sensitive_data_encryption_metod.assert_has_calls(calls)
+
+    self.assertFalse(save_master_key_method.called)
+    self.assertTrue(get_original_master_key_mock.called)
+    self.assertTrue(get_YN_input_method.called)
+    self.assertTrue(get_validated_string_input_method.called)
+    self.assertTrue(update_properties_method.called)
+    self.assertTrue(read_passwd_for_alias_method.called)
+    self.assertTrue(2, read_passwd_for_alias_method.call_count)
+    self.assertTrue(2, save_passwd_for_alias_method.call_count)
+    self.assertFalse(save_master_key_method.called)
+
+    result_expected = {JDBC_PASSWORD_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       JDBC_RCA_PASSWORD_FILE_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       SSL_TRUSTSTORE_PASSWORD_PROPERTY:
+                         get_alias_string(SSL_TRUSTSTORE_PASSWORD_ALIAS),
+                       SECURITY_IS_ENCRYPTION_ENABLED: 'true',
+                       SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED: 'true'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
+    pass
+
+  @patch("ambari_server.setupSecurity.get_is_persisted")
+  @patch("ambari_server.setupSecurity.get_is_secure")
+  @patch("os.path.exists")
+  @patch("ambari_server.setupSecurity.read_ambari_user")
+  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.read_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.update_properties_2")
+  @patch("ambari_server.setupSecurity.save_master_key")
+  @patch("ambari_server.setupSecurity.get_YN_input")
+  @patch("ambari_server.setupSecurity.search_file")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.is_root")
+  @patch("ambari_server.setupSecurity.sensitive_data_encryption")
+  @patch("ambari_server.setupSecurity.get_original_master_key")
+  def test_encrypt_part_not_persisted(self, get_original_master_key_mock, 
sensitive_data_encryption_metod, is_root_method,
+                                          get_ambari_properties_method,
+                                          search_file_message, 
get_YN_input_method,
+                                          save_master_key_method,
+                                          update_properties_method, 
read_passwd_for_alias_method,
+                                          save_passwd_for_alias_method,
+                                          read_ambari_user_method,
+                                          exists_mock, get_is_secure_method,
+                                          get_is_persisted_method):
+
+    is_root_method.return_value = True
+    search_file_message.return_value = False
+    read_ambari_user_method.return_value = None
+
+    p = Properties()
+    FAKE_PWD_STRING = '${alias=fakealias}'
+    p.process_pair(JDBC_PASSWORD_PROPERTY, 
get_alias_string(JDBC_RCA_PASSWORD_ALIAS))
+    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
+    get_ambari_properties_method.return_value = p
+
+    master_key = "aaa"
+    get_YN_input_method.side_effect = [False, False, False]
+    get_original_master_key_mock.return_value = master_key
+    read_passwd_for_alias_method.return_value = "fakepassword"
+    save_passwd_for_alias_method.return_value = 0
+    exists_mock.return_value = False
+    get_is_secure_method.return_value = True
+    get_is_persisted_method.return_value = (False, "filePath")
+
+    options = self._create_empty_options_mock()
+    setup_sensitive_data_encryption(options)
+    calls = [call(options, "encryption", master_key)]
+    sensitive_data_encryption_metod.assert_has_calls(calls)
+
+    self.assertFalse(save_master_key_method.called)
+    self.assertTrue(get_YN_input_method.called)
+    self.assertTrue(get_original_master_key_mock.called)
+    self.assertTrue(update_properties_method.called)
+    self.assertTrue(read_passwd_for_alias_method.called)
+    self.assertTrue(2, read_passwd_for_alias_method.call_count)
+    self.assertTrue(2, save_passwd_for_alias_method.call_count)
+    self.assertFalse(save_master_key_method.called)
+
+    result_expected = {JDBC_PASSWORD_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       JDBC_RCA_PASSWORD_FILE_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       SSL_TRUSTSTORE_PASSWORD_PROPERTY:
+                         get_alias_string(SSL_TRUSTSTORE_PASSWORD_ALIAS),
+                       SECURITY_IS_ENCRYPTION_ENABLED: 'true',
+                       SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED: 'true'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
+    pass
+
+  @patch("ambari_server.setupSecurity.get_is_persisted")
+  @patch("ambari_server.setupSecurity.get_is_secure")
+  @patch("os.path.exists")
+  @patch("ambari_server.setupSecurity.read_ambari_user")
+  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.read_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.save_master_key")
+  @patch("ambari_server.setupSecurity.get_YN_input")
+  @patch("ambari_server.setupSecurity.search_file")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.is_root")
+  @patch("ambari_server.setupSecurity.get_original_master_key")
+  def test_decrypt_missed_masterkey_not_persisted(self, 
get_original_master_key_mock, is_root_method,
+                                      get_ambari_properties_method,
+                                      search_file_message, get_YN_input_method,
+                                      save_master_key_method,
+                                      read_passwd_for_alias_method,
+                                      save_passwd_for_alias_method,
+                                      read_ambari_user_method,
+                                      exists_mock, get_is_secure_method,
+                                      get_is_persisted_method):
+
+    is_root_method.return_value = True
+    search_file_message.return_value = False
+    read_ambari_user_method.return_value = None
+
+    p = Properties()
+    FAKE_PWD_STRING = '${alias=fakealias}'
+    p.process_pair(JDBC_PASSWORD_PROPERTY, 
get_alias_string(JDBC_RCA_PASSWORD_ALIAS))
+    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
+    get_ambari_properties_method.return_value = p
+
+    get_YN_input_method.side_effect = [True, False]
+    get_original_master_key_mock.return_value = None
+    read_passwd_for_alias_method.return_value = "fakepassword"
+    save_passwd_for_alias_method.return_value = 0
+    exists_mock.return_value = False
+    get_is_secure_method.return_value = True
+    get_is_persisted_method.return_value = (False, "filePath")
+
+    options = self._create_empty_options_mock()
+    self.assertTrue(setup_sensitive_data_encryption(options) == 1)
+
+    self.assertFalse(save_master_key_method.called)
+    self.assertTrue(get_YN_input_method.called)
+    pass
+
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.is_root")
+  def test_setup_sensitive_data_encryption_no_ambari_prop_not_root(self,  
is_root_method, get_ambari_properties_method):
+
+    is_root_method.return_value = False
+    get_ambari_properties_method.return_value = -1
+    options = self._create_empty_options_mock()
+
+    try:
+      setup_sensitive_data_encryption(options)
+      self.fail("Should throw exception")
+    except FatalException as fe:
+      self.assertTrue('Failed to read properties file.' == fe.reason)
+      pass
+    pass
+
+  @patch("os.path.exists")
+  @patch("ambari_server.setupSecurity.get_is_secure")
+  @patch("ambari_server.setupSecurity.get_is_persisted")
+  @patch("ambari_server.setupSecurity.remove_password_file")
+  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.read_master_key")
+  @patch("ambari_server.setupSecurity.read_ambari_user")
+  @patch("ambari_server.setupSecurity.update_properties_2")
+  @patch("ambari_server.setupSecurity.save_master_key")
+  @patch("ambari_server.setupSecurity.get_YN_input")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.is_root")
+  @patch("ambari_server.setupSecurity.sensitive_data_encryption")
+  @patch("ambari_server.setupSecurity.adjust_directory_permissions")
+  def test_setup_sensitive_data_encryption_not_persist(self, 
adjust_directory_permissions_mock, sensitive_data_encryption_metod, 
is_root_method,
+                                                       
get_ambari_properties_method, get_YN_input_method, save_master_key_method,
+                                                       
update_properties_method,
+                                                       
read_ambari_user_method, read_master_key_method,
+                                                       
save_passwd_for_alias_method, remove_password_file_method,
+                                                       
get_is_persisted_method, get_is_secure_method, exists_mock):
+
+    is_root_method.return_value = True
+
+    p = Properties()
+    FAKE_PWD_STRING = "fakepasswd"
+    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
+    get_ambari_properties_method.return_value = p
+
+    master_key = "aaa"
+    read_master_key_method.return_value = master_key
+    get_YN_input_method.return_value = False
+    read_ambari_user_method.return_value = "asd"
+    save_passwd_for_alias_method.return_value = 0
+    get_is_persisted_method.return_value = (True, "filepath")
+    get_is_secure_method.return_value = False
+    exists_mock.return_value = False
+
+    options = self._create_empty_options_mock()
+    setup_sensitive_data_encryption(options)
+
+    self.assertTrue(get_YN_input_method.called)
+    self.assertTrue(read_master_key_method.called)
+    self.assertTrue(read_ambari_user_method.called)
+    self.assertTrue(update_properties_method.called)
+    self.assertFalse(save_master_key_method.called)
+    self.assertTrue(save_passwd_for_alias_method.called)
+    self.assertEquals(2, save_passwd_for_alias_method.call_count)
+    self.assertTrue(remove_password_file_method.called)
+    self.assertTrue(adjust_directory_permissions_mock.called)
+    sensitive_data_encryption_metod.assert_called_with(options, "encryption", 
master_key)
+
+    result_expected = {JDBC_PASSWORD_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       JDBC_RCA_PASSWORD_FILE_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       SSL_TRUSTSTORE_PASSWORD_PROPERTY:
+                         get_alias_string(SSL_TRUSTSTORE_PASSWORD_ALIAS),
+                       SECURITY_IS_ENCRYPTION_ENABLED: 'true',
+                       SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED: 'true'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
+    pass
+
+  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
+  @patch("os.path.exists")
+  @patch("ambari_server.setupSecurity.get_is_secure")
+  @patch("ambari_server.setupSecurity.get_is_persisted")
+  @patch("ambari_server.setupSecurity.read_master_key")
+  @patch("ambari_server.setupSecurity.read_ambari_user")
+  @patch("ambari_server.setupSecurity.update_properties_2")
+  @patch("ambari_server.setupSecurity.save_master_key")
+  @patch("ambari_server.setupSecurity.get_YN_input")
+  @patch("ambari_server.serverConfiguration.search_file")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.is_root")
+  @patch("ambari_server.setupSecurity.sensitive_data_encryption")
+  def test_setup_sensitive_data_encryption_persist(self, 
sensitive_data_encryption_metod, is_root_method,
+                                                   
get_ambari_properties_method, search_file_message,
+                                                   get_YN_input_method, 
save_master_key_method,
+                                                   update_properties_method,
+                                                   read_ambari_user_method, 
read_master_key_method,
+                                                   get_is_persisted_method, 
get_is_secure_method, exists_mock,
+                                                   
save_passwd_for_alias_method):
+    is_root_method.return_value = True
+
+    p = Properties()
+    FAKE_PWD_STRING = "fakepasswd"
+    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    get_ambari_properties_method.return_value = p
+
+    search_file_message.return_value = "propertiesfile"
+
+    master_key = "aaa"
+    read_master_key_method.return_value = master_key
+    get_YN_input_method.return_value = True
+    read_ambari_user_method.return_value = None
+    get_is_persisted_method.return_value = (True, "filepath")
+    get_is_secure_method.return_value = False
+    exists_mock.return_value = False
+    save_passwd_for_alias_method.return_value = 0
+
+    options = self._create_empty_options_mock()
+    setup_sensitive_data_encryption(options)
+
+    self.assertTrue(get_YN_input_method.called)
+    self.assertTrue(read_master_key_method.called)
+    self.assertTrue(read_ambari_user_method.called)
+    self.assertTrue(update_properties_method.called)
+    self.assertTrue(save_master_key_method.called)
+    sensitive_data_encryption_metod.assert_called_with(options, "encryption")
+
+    result_expected = {JDBC_PASSWORD_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       SECURITY_IS_ENCRYPTION_ENABLED: 'true',
+                       SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED: 'true'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
+    pass
+
+  @patch("ambari_server.setupSecurity.read_master_key")
+  @patch("os.path.exists")
+  @patch("ambari_server.setupSecurity.read_ambari_user")
+  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.read_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.update_properties_2")
+  @patch("ambari_server.setupSecurity.save_master_key")
+  @patch("ambari_server.setupSecurity.get_YN_input")
+  @patch("ambari_server.setupSecurity.search_file")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.is_root")
+  @patch("ambari_server.setupSecurity.sensitive_data_encryption")
+  @patch("ambari_server.setupSecurity.get_is_secure")
+  def test_reset_master_key_persisted(self, get_is_secure_method, 
sensitive_data_encryption_metod, is_root_method,
+                                      get_ambari_properties_method, 
search_file_message,
+                                      get_YN_input_method,
+                                      save_master_key_method, 
update_properties_method,
+                                      read_passwd_for_alias_method, 
save_passwd_for_alias_method,
+                                      read_ambari_user_method, exists_mock,
+                                      read_master_key_method):
+
+    # Testing call under root
+    is_root_method.return_value = True
+
+    search_file_message.return_value = "filepath"
+    read_ambari_user_method.return_value = None
+
+    p = Properties()
+    FAKE_PWD_STRING = '${alias=fakealias}'
+    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
+    get_ambari_properties_method.return_value = p
+
+    master_key = "aaa"
+
+    get_is_secure_method.return_value = True
+    get_YN_input_method.side_effect = [False, True, True]
+    read_master_key_method.return_value = master_key
+    read_passwd_for_alias_method.return_value = "fakepassword"
+    save_passwd_for_alias_method.return_value = 0
+    exists_mock.return_value = False
+
+
+    options = self._create_empty_options_mock()
+    setup_sensitive_data_encryption(options)
+    calls = [call(options, "decryption"), call(options, "encryption")]
+    sensitive_data_encryption_metod.assert_has_calls(calls)
+
+    self.assertTrue(save_master_key_method.called)
+    self.assertTrue(get_YN_input_method.called)
+    self.assertTrue(read_master_key_method.called)
+    self.assertTrue(update_properties_method.called)
+    self.assertTrue(read_passwd_for_alias_method.called)
+    self.assertTrue(2, read_passwd_for_alias_method.call_count)
+    self.assertTrue(2, save_passwd_for_alias_method.call_count)
+
+    result_expected = {JDBC_PASSWORD_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       JDBC_RCA_PASSWORD_FILE_PROPERTY:
+                         get_alias_string(JDBC_RCA_PASSWORD_ALIAS),
+                       SSL_TRUSTSTORE_PASSWORD_PROPERTY:
+                         get_alias_string(SSL_TRUSTSTORE_PASSWORD_ALIAS),
+                       SECURITY_IS_ENCRYPTION_ENABLED: 'true',
+                       SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED: 'true'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
+    pass
+
+  @patch("ambari_server.setupSecurity.read_master_key")
+  @patch("os.path.exists")
+  @patch("ambari_server.setupSecurity.read_ambari_user")
+  @patch("ambari_server.setupSecurity.save_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.read_passwd_for_alias")
+  @patch("ambari_server.setupSecurity.update_properties_2")
+  @patch("ambari_server.setupSecurity.get_YN_input")
+  @patch("ambari_server.setupSecurity.search_file")
+  @patch("ambari_server.setupSecurity.get_ambari_properties")
+  @patch("ambari_server.setupSecurity.is_root")
+  @patch("ambari_server.setupSecurity.sensitive_data_encryption")
+  @patch("ambari_server.setupSecurity.get_is_secure")
+  def test_decrypt_sensitive_data(self, get_is_secure_method, 
sensitive_data_encryption_metod, is_root_method,
+                                  get_ambari_properties_method, 
search_file_message,
+                                  get_YN_input_method,
+                                  update_properties_method,
+                                  read_passwd_for_alias_method, 
save_passwd_for_alias_method,
+                                  read_ambari_user_method, exists_mock,
+                                  read_master_key_method):
+
+    # Testing call under root
+    is_root_method.return_value = True
+
+    search_file_message.return_value = "filepath"
+    read_ambari_user_method.return_value = None
+
+    p = Properties()
+    FAKE_PWD_STRING = '${alias=fakealias}'
+    p.process_pair(JDBC_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(SSL_TRUSTSTORE_PASSWORD_PROPERTY, FAKE_PWD_STRING)
+    p.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, FAKE_PWD_STRING)
+    get_ambari_properties_method.return_value = p
+
+    master_key = "aaa"
+    get_is_secure_method.return_value = True
+    get_YN_input_method.side_effect = [True, False]
+    read_master_key_method.return_value = master_key
+    read_passwd_for_alias_method.return_value = "fakepassword"
+    save_passwd_for_alias_method.return_value = 0
+    exists_mock.return_value = False
+
+
+    options = self._create_empty_options_mock()
+    setup_sensitive_data_encryption(options)
+    calls = [call(options, "decryption")]
+    sensitive_data_encryption_metod.assert_has_calls(calls)
+
+    self.assertTrue(get_YN_input_method.called)
+    self.assertTrue(update_properties_method.called)
+    self.assertTrue(read_passwd_for_alias_method.called)
+    self.assertTrue(2, read_passwd_for_alias_method.call_count)
+    self.assertTrue(2, save_passwd_for_alias_method.call_count)
+
+    result_expected = {JDBC_PASSWORD_PROPERTY: "fakepassword",
+                       JDBC_RCA_PASSWORD_FILE_PROPERTY: "fakepassword",
+                       SSL_TRUSTSTORE_PASSWORD_PROPERTY: "fakepassword",
+                       SECURITY_IS_ENCRYPTION_ENABLED: 'false',
+                       SECURITY_SENSITIVE_DATA_ENCRYPTON_ENABLED: 'false'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
+    pass
+
+  def _create_empty_options_mock(self):
+    options = MagicMock()
+    options.ldap_enabled = None
+    options.ldap_enabled_ambari = None
+    options.ldap_manage_services = None
+    options.ldap_enabled_services = None
+    options.ldap_url = None
+    options.ldap_primary_host = None
+    options.ldap_primary_port = None
+    options.ldap_secondary_url = None
+    options.ldap_secondary_host = None
+    options.ldap_secondary_port = None
+    options.ldap_ssl = None
+    options.ldap_user_class = None
+    options.ldap_user_attr = None
+    options.ldap_user_group_member_attr = None
+    options.ldap_group_class = None
+    options.ldap_group_attr = None
+    options.ldap_member_attr = None
+    options.ldap_dn = None
+    options.ldap_base_dn = None
+    options.ldap_manager_dn = None
+    options.ldap_manager_password = None
+    options.ldap_save_settings = None
+    options.ldap_referral = None
+    options.ldap_bind_anonym = None
+    options.ldap_force_setup = None
+    options.ambari_admin_username = None
+    options.ambari_admin_password = None
+    options.ldap_sync_admin_name = None
+    options.ldap_sync_username_collisions_behavior = None
+    options.ldap_sync_disable_endpoint_identification = None
+    options.ldap_force_lowercase_usernames = None
+    options.ldap_pagination_enabled = None
+    options.ldap_sync_admin_password = None
+    options.custom_trust_store = None
+    options.trust_store_type = None
+    options.trust_store_path = None
+    options.trust_store_password = None
+    options.security_option = None
+    options.api_ssl = None
+    options.api_ssl_port = None
+    options.import_cert_path = None
+    options.import_cert_alias = None
+    options.pem_password = None
+    options.import_key_path = None
+    options.master_key = None
+    options.master_key_persist = None
+    options.jaas_principal = None
+    options.jaas_keytab = None
+    return options
+
+

Reply via email to