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

pradeep pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new d0e5fe9  Ranger-1644-Change the default Crypt Algo to use stronger 
cryptographic algo
d0e5fe9 is described below

commit d0e5fe90752b21365d5b86d92936b48ea53c6ab2
Author: mateenmansoori <[email protected]>
AuthorDate: Tue Jul 2 15:37:40 2019 +0530

    Ranger-1644-Change the default Crypt Algo to use stronger cryptographic algo
    
    Signed-off-by: Pradeep <[email protected]>
---
 .../apache/ranger/plugin/util/PasswordUtils.java   | 145 +++++++++++----
 .../ranger/plugin/util/PasswordUtilsTest.java      | 201 +++++++++++++++++----
 .../java/org/apache/ranger/biz/ServiceDBStore.java |  73 ++++----
 .../ranger/patch/cliutil/ChangePasswordUtil.java   |   1 -
 .../ranger/service/RangerServiceService.java       |  60 +++---
 .../conf.dist/ranger-admin-default-site.xml        |   2 +-
 .../org/apache/ranger/biz/TestServiceDBStore.java  |  83 +++++++++
 7 files changed, 417 insertions(+), 148 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/PasswordUtils.java 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/PasswordUtils.java
index 6480b17..c08f55d 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/PasswordUtils.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/PasswordUtils.java
@@ -17,40 +17,51 @@
 package org.apache.ranger.plugin.util;
 
 import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
 import java.util.Map;
 
 import javax.crypto.Cipher;
 import javax.crypto.SecretKey;
 import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.PBEParameterSpec;
 
-import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
 import com.sun.jersey.core.util.Base64;
 public class PasswordUtils {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(PasswordUtils.class);
 
-    private final String CRYPT_ALGO;
+    private final String cryptAlgo;
     private String password;
-    private final char[] ENCRYPT_KEY;
-    private final byte[] SALT;
-    private final int ITERATION_COUNT;
+    private final int iterationCount;
     private final char[] encryptKey;
     private final byte[] salt;
+    private final byte[] iv;
     private static final String LEN_SEPARATOR_STR = ":";
 
+    public static final String PBE_SHA512_AES_128 = 
"PBEWITHHMACSHA512ANDAES_128";
+
     public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";
     public static final String DEFAULT_ENCRYPT_KEY = 
"tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV";
     public static final String DEFAULT_SALT = "f77aLYLo";
     public static final int DEFAULT_ITERATION_COUNT = 17;
+    public static final byte[] DEFAULT_INITIAL_VECTOR = new byte[16];
 
-    public static String encryptPassword(String aPassword) throws IOException {
-        return new PasswordUtils(aPassword).encrypt();
-    }
+       public static String encryptPassword(String aPassword) throws 
IOException {
+               return build(aPassword).encrypt();
+       }
+
+       public static PasswordUtils build(String aPassword) {
+               return new PasswordUtils(aPassword);
+       }
 
     private String encrypt() throws IOException {
         String ret = null;
@@ -61,11 +72,11 @@ public class PasswordUtils {
             strToEncrypt = password.length() + LEN_SEPARATOR_STR + password;
         }
         try {
-            Cipher engine = Cipher.getInstance(CRYPT_ALGO);
+            Cipher engine = Cipher.getInstance(cryptAlgo);
             PBEKeySpec keySpec = new PBEKeySpec(encryptKey);
-            SecretKeyFactory skf = SecretKeyFactory.getInstance(CRYPT_ALGO);
+            SecretKeyFactory skf = SecretKeyFactory.getInstance(cryptAlgo);
             SecretKey key = skf.generateSecret(keySpec);
-            engine.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(salt, 
ITERATION_COUNT));
+            engine.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(salt, 
iterationCount, new IvParameterSpec(iv)));
             byte[] encryptedStr = engine.doFinal(strToEncrypt.getBytes());
             ret = new String(Base64.encode(encryptedStr));
         }
@@ -78,29 +89,36 @@ public class PasswordUtils {
 
         PasswordUtils(String aPassword) {
             String[] crypt_algo_array = null;
-            int count = 0;
-            if (aPassword != null && aPassword.contains(",")) {
-                count = StringUtils.countMatches(aPassword, ",");
-                crypt_algo_array = aPassword.split(",");
-            }
-            if (crypt_algo_array != null && crypt_algo_array.length > 4) {
-                CRYPT_ALGO = crypt_algo_array[0];
-                ENCRYPT_KEY = crypt_algo_array[1].toCharArray();
-                SALT = crypt_algo_array[2].getBytes();
-                ITERATION_COUNT = Integer.parseInt(crypt_algo_array[3]);
-                password = crypt_algo_array[4];
-                if (count > 4) {
-                    for (int i = 5 ; i<=count ; i++){
-                        password = password + "," + crypt_algo_array[i];
-                    }
-                }
-            } else {
-                    CRYPT_ALGO = DEFAULT_CRYPT_ALGO;
-                    ENCRYPT_KEY = DEFAULT_ENCRYPT_KEY.toCharArray();
-                    SALT = DEFAULT_SALT.getBytes();
-                    ITERATION_COUNT = DEFAULT_ITERATION_COUNT;
-                    password = aPassword;
-            }
+            byte[] SALT;
+            char[] ENCRYPT_KEY;
+               if (aPassword != null && aPassword.contains(",")) {
+                       crypt_algo_array = 
Lists.newArrayList(Splitter.on(",").split(aPassword)).toArray(new String[0]);
+               }
+               if (crypt_algo_array != null && crypt_algo_array.length > 4) {
+                       int index = 0;
+                       cryptAlgo = crypt_algo_array[index++]; // 0
+                       ENCRYPT_KEY = crypt_algo_array[index++].toCharArray(); 
// 1
+                       SALT = crypt_algo_array[index++].getBytes(); // 2
+                       iterationCount = 
Integer.parseInt(crypt_algo_array[index++]);// 3
+                       if (needsIv(cryptAlgo)) {
+                               iv = Base64.decode(crypt_algo_array[index++]);
+                       } else {
+                               iv = DEFAULT_INITIAL_VECTOR;
+                       }
+                       password = crypt_algo_array[index++];
+                       if (crypt_algo_array.length > index) {
+                               for (int i = index; i < 
crypt_algo_array.length; i++) {
+                                       password = password + "," + 
crypt_algo_array[i];
+                               }
+                       }
+               } else {
+                       cryptAlgo = DEFAULT_CRYPT_ALGO;
+                       ENCRYPT_KEY = DEFAULT_ENCRYPT_KEY.toCharArray();
+                       SALT = DEFAULT_SALT.getBytes();
+                       iterationCount = DEFAULT_ITERATION_COUNT;
+                       iv = DEFAULT_INITIAL_VECTOR;
+                       password = aPassword;
+               }
             Map<String, String> env = System.getenv();
             String encryptKeyStr = env.get("ENCRYPT_KEY");
             if (encryptKeyStr == null) {
@@ -116,19 +134,19 @@ public class PasswordUtils {
             }
         }
 
-    public static String decryptPassword(String aPassword) throws IOException {
-        return new PasswordUtils(aPassword).decrypt();
-    }
+       public static String decryptPassword(String aPassword) throws 
IOException {
+               return build(aPassword).decrypt();
+       }
 
     private String decrypt() throws IOException {
         String ret = null;
         try {
             byte[] decodedPassword = Base64.decode(password);
-            Cipher engine = Cipher.getInstance(CRYPT_ALGO);
+            Cipher engine = Cipher.getInstance(cryptAlgo);
             PBEKeySpec keySpec = new PBEKeySpec(encryptKey);
-            SecretKeyFactory skf = SecretKeyFactory.getInstance(CRYPT_ALGO);
+            SecretKeyFactory skf = SecretKeyFactory.getInstance(cryptAlgo);
             SecretKey key = skf.generateSecret(keySpec);
-            engine.init(Cipher.DECRYPT_MODE, key,new PBEParameterSpec(salt, 
ITERATION_COUNT));
+            engine.init(Cipher.DECRYPT_MODE, key,new PBEParameterSpec(salt, 
iterationCount, new IvParameterSpec(iv)));
             String decrypted = new String(engine.doFinal(decodedPassword));
             int foundAt = decrypted.indexOf(LEN_SEPARATOR_STR);
             if (foundAt > -1) {
@@ -150,6 +168,53 @@ public class PasswordUtils {
         return ret;
     }
 
+       public static boolean needsIv(String cryptoAlgo) {
+               if (Strings.isNullOrEmpty(cryptoAlgo))
+                       return false;
+
+               return 
PBE_SHA512_AES_128.toLowerCase().equals(cryptoAlgo.toLowerCase())
+                               || cryptoAlgo.toLowerCase().contains("aes_128") 
|| cryptoAlgo.toLowerCase().contains("aes_256");
+       }
+
+       public static String generateIvIfNeeded(String cryptAlgo) throws 
NoSuchAlgorithmException {
+               if (!needsIv(cryptAlgo))
+                       return null;
+               return generateBase64EncodedIV();
+       }
+
+       private static String generateBase64EncodedIV() throws 
NoSuchAlgorithmException {
+               byte[] iv = new byte[16];
+               SecureRandom.getInstanceStrong().nextBytes(iv);
+               return new String(Base64.encode(iv));
+       }
+
+       public String getCryptAlgo() {
+               return cryptAlgo;
+       }
+
+       public String getPassword() {
+               return password;
+       }
+
+       public int getIterationCount() {
+               return iterationCount;
+       }
+
+       public char[] getEncryptKey() {
+               return encryptKey;
+       }
+
+       public byte[] getSalt() {
+               return salt;
+       }
+
+       public byte[] getIv() {
+               return iv;
+       }
+
+       public String getIvAsString() {
+               return new String(Base64.encode(getIv()));
+       }
        public static String getDecryptPassword(String password) {
                String decryptedPwd = null;
                try {
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/util/PasswordUtilsTest.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/util/PasswordUtilsTest.java
index 4e135aa..d0b1806 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/util/PasswordUtilsTest.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/util/PasswordUtilsTest.java
@@ -22,46 +22,173 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
 import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
 
 import org.junit.Test;
 
+import com.google.common.base.Joiner;
+
 public class PasswordUtilsTest {
 
-    @Test
-    public void testEncrypt() throws IOException {
-        String string0 = 
PasswordUtils.encryptPassword("secretPasswordNoOneWillEverKnow");
-        assertNotNull(string0);
-        
assertEquals("ljoJ3gf4T018Xr+BujPAqBDW8Onp1PqprsLKmxus8pGGBETtAVU6OQ==", 
string0);
-    }
-
-    @Test
-    public void testDecrypt() throws IOException {
-        String string0 = 
PasswordUtils.decryptPassword("ljoJ3gf4T018Xr+BujPAqBDW8Onp1PqprsLKmxus8pGGBETtAVU6OQ==");
-        assertNotNull(string0);
-        assertEquals("secretPasswordNoOneWillEverKnow", string0);
-    }
-
-    @Test
-    public void testEncryptWithExplicitDefaultWeakAlgorithm() throws 
IOException {
-        String string0 = PasswordUtils
-                
.encryptPassword("PBEWithMD5AndDES,ENCRYPT_KEY,SALTSALT,4,secretPasswordNoOneWillEverKnow");
-        assertNotNull(string0);
-        String string1 = 
PasswordUtils.decryptPassword("PBEWithMD5AndDES,ENCRYPT_KEY,SALTSALT,4," + 
string0);
-        assertNotNull("secretPasswordNoOneWillEverKnow", string1);
-    }
-
-    @Test
-    public void testEncryptWithSHA1AndDESede() throws IOException {
-        String string0 = PasswordUtils
-                
.encryptPassword("PBEWithSHA1AndDESede,ENCRYPT_KEY,SALTSALT,4,secretPasswordNoOneWillEverKnow");
-        assertNotNull(string0);
-        String string1 = 
PasswordUtils.decryptPassword("PBEWithSHA1AndDESede,ENCRYPT_KEY,SALTSALT,4," + 
string0);
-        assertNotNull("secretPasswordNoOneWillEverKnow", string1);
-    }
-
-    @Test
-    public void testDecryptEmptyResultInNull() throws Throwable {
-        String string0 = PasswordUtils.decryptPassword("");
-        assertNull(string0);
-    }
+       @Test
+       public void testEncrypt() throws IOException {
+               // encryption of password that contains no configuration info 
is using legacy
+               // cryptography algorithm for backward compatibility.
+               String encryptedPassword = 
PasswordUtils.encryptPassword("secretPasswordNoOneWillEverKnow");
+               assertNotNull(encryptedPassword);
+               
assertEquals("ljoJ3gf4T018Xr+BujPAqBDW8Onp1PqprsLKmxus8pGGBETtAVU6OQ==", 
encryptedPassword);
+       }
+
+       @Test
+       public void testDecrypt() throws IOException {
+               String decryptedPassword = PasswordUtils
+                               
.decryptPassword("ljoJ3gf4T018Xr+BujPAqBDW8Onp1PqprsLKmxus8pGGBETtAVU6OQ==");
+
+               assertNotNull(decryptedPassword);
+               assertEquals("secretPasswordNoOneWillEverKnow", 
decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithExplicitDefaultWeakAlgorithm() throws 
IOException {
+               String freeTextPasswordMetaData = join("PBEWithMD5AndDES", 
"ENCRYPT_KEY", "SALTSALT", "4");
+               String encryptedPassword = PasswordUtils
+                               .encryptPassword(join(freeTextPasswordMetaData, 
"secretPasswordNoOneWillEverKnow"));
+               assertNotNull(encryptedPassword);
+
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals("secretPasswordNoOneWillEverKnow", 
decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA1AndDESede() throws IOException {
+               String freeTextPasswordMetaData = join("PBEWithSHA1AndDESede", 
"ENCRYPT_KEY", "SALTSALT", "4");
+               String encryptedPassword = PasswordUtils
+                               .encryptPassword(join(freeTextPasswordMetaData, 
"secretPasswordNoOneWillEverKnow"));
+               assertNotNull(encryptedPassword);
+
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals("secretPasswordNoOneWillEverKnow", 
decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128() throws IOException, 
NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
join("PBEWITHHMACSHA512ANDAES_128", "ENCRYPT_KEY", "SALTSALT", "4",
+                               
PasswordUtils.generateIvIfNeeded("PBEWITHHMACSHA512ANDAES_128"));
+               String encryptedPassword = PasswordUtils
+                               .encryptPassword(join(freeTextPasswordMetaData, 
"secretPasswordNoOneWillEverKnow"));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals("secretPasswordNoOneWillEverKnow", 
decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128WithMultipleComasInPass() 
throws IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = "asd,qwe,123";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128WithSingleComaInPass() throws 
IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = "asd,123";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128EndingWithSingleComa() throws 
IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = "asd,";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128StartingWithSingleComa() 
throws IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = ",asd";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128MultipleComasInTheEnd() 
throws IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = "asd,,";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128MultipleComasSurroundingText()
+                       throws IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = ",,a,,";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128MultipleComasBeforeText() 
throws IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = ",,,a";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128MultipleComasOnlyPassword() 
throws IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = ",,,";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testEncryptWithSHA512AndAES128SingleComaOnlyPassword() 
throws IOException, NoSuchAlgorithmException {
+               String freeTextPasswordMetaData = 
"PBEWITHHMACSHA512ANDAES_128,tzL1AKl5uc4NKYaoQ4P3WLGIBFPXWPWdu1fRm9004jtQiV,f77aLYLo,1000,9f3vNL0ijeHF4RWN/yUo0A==";
+               String freeTextPassword = ",";
+               String encryptedPassword = 
PasswordUtils.encryptPassword(join(freeTextPasswordMetaData, freeTextPassword));
+
+               assertNotNull(encryptedPassword);
+               String decryptedPassword = 
PasswordUtils.decryptPassword(join(freeTextPasswordMetaData, 
encryptedPassword));
+               assertEquals(freeTextPassword, decryptedPassword);
+       }
+
+       @Test
+       public void testDecryptEmptyResultInNull() throws Throwable {
+               String string0 = PasswordUtils.decryptPassword("");
+               assertNull(string0);
+       }
+
+       private String join(String... strings) {
+               return Joiner.on(",").skipNulls().join(strings);
+       }
 }
diff --git 
a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java 
b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 0e0e485..77c91ab 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -175,6 +175,7 @@ import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.support.TransactionCallback;
 import org.springframework.transaction.support.TransactionTemplate;
 
+import com.google.common.base.Joiner;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
@@ -1451,12 +1452,17 @@ public class ServiceDBStore extends 
AbstractServiceStore {
                        }
 
                        if (StringUtils.equalsIgnoreCase(configKey, 
CONFIG_KEY_PASSWORD)) {
-                                String cryptConfigString = CRYPT_ALGO + "," +  
ENCRYPT_KEY + "," + SALT + "," + ITERATION_COUNT + "," + configValue;
-                                String encryptedPwd = 
PasswordUtils.encryptPassword(cryptConfigString);
-                                encryptedPwd = CRYPT_ALGO + "," +  ENCRYPT_KEY 
+ "," + SALT + "," + ITERATION_COUNT + "," + encryptedPwd;
-                               String decryptedPwd = 
PasswordUtils.decryptPassword(encryptedPwd);
+                               Joiner joiner = Joiner.on(",").skipNulls();
+                               String iv = 
PasswordUtils.generateIvIfNeeded(CRYPT_ALGO);
+
+                               String cryptConfigString = 
joiner.join(CRYPT_ALGO, ENCRYPT_KEY, SALT, ITERATION_COUNT, iv, configValue);
+                               String encryptedPwd = 
PasswordUtils.encryptPassword(cryptConfigString);
+
+                               String paddedEncryptedPwd = 
joiner.join(CRYPT_ALGO, ENCRYPT_KEY, SALT, ITERATION_COUNT, iv,
+                                               encryptedPwd);
+                               String decryptedPwd = 
PasswordUtils.decryptPassword(paddedEncryptedPwd);
                                if (StringUtils.equals(decryptedPwd, 
configValue)) {
-                                       configValue = encryptedPwd;
+                                       configValue = paddedEncryptedPwd;
                                }
                        }
 
@@ -1633,42 +1639,31 @@ public class ServiceDBStore extends 
AbstractServiceStore {
 
                        if (StringUtils.equalsIgnoreCase(configKey, 
CONFIG_KEY_PASSWORD)) {
                                if (StringUtils.equalsIgnoreCase(configValue, 
HIDDEN_PASSWORD_STR)) {
-                                        String[] crypt_algo_array = null;
-                                        if (configValue.contains(",")) {
-                                                crypt_algo_array = 
configValue.split(",");
-                                        }
-                                        if (oldPassword != null && 
oldPassword.contains(",")) {
-                                               String encryptKey = null;
-                                               String salt = null;
-                                               int iterationCount = 0;
-
-                                                crypt_algo_array = 
oldPassword.split(",");
-                                                String OLD_CRYPT_ALGO = 
crypt_algo_array[0];
-                                                encryptKey = 
crypt_algo_array[1];
-                                                salt = crypt_algo_array[2];
-                                                iterationCount = 
Integer.parseInt(crypt_algo_array[3]);
-
-                                                if 
(!OLD_CRYPT_ALGO.equalsIgnoreCase(CRYPT_ALGO)) {
-                                                        String decryptedPwd = 
PasswordUtils.decryptPassword(oldPassword);
-                                                        String paddingString = 
CRYPT_ALGO + "," +  encryptKey + "," + salt + "," + iterationCount;
-                                                        String encryptedPwd = 
PasswordUtils.encryptPassword(paddingString + "," + decryptedPwd);
-                                                        String newDecryptedPwd 
= PasswordUtils.decryptPassword(paddingString + "," + encryptedPwd);
-                                                        if 
(StringUtils.equals(newDecryptedPwd, decryptedPwd)) {
-                                                                configValue = 
paddingString + "," + encryptedPwd;
-                                                        }
-                                                } else {
-                                                        configValue = 
oldPassword;
-                                                }
-                                        } else {
-                                                configValue = oldPassword;
-                                        }
+                                       if (oldPassword != null && 
oldPassword.contains(",")) {
+                                               PasswordUtils util = 
PasswordUtils.build(oldPassword);
+                                               if 
(!util.getCryptAlgo().equalsIgnoreCase(CRYPT_ALGO)) {
+                                                       String decryptedPwd = 
PasswordUtils.decryptPassword(oldPassword);
+                                                       String paddingString = 
Joiner.on(",").skipNulls().join(CRYPT_ALGO,
+                                                                       new 
String(util.getEncryptKey()), new String(util.getSalt()),
+                                                                       
util.getIterationCount(), PasswordUtils.generateIvIfNeeded(CRYPT_ALGO));
+                                                       String encryptedPwd = 
PasswordUtils.encryptPassword(paddingString + "," + decryptedPwd);
+                                                       String newDecryptedPwd 
= PasswordUtils.decryptPassword(paddingString + "," + encryptedPwd);
+                                                       if 
(StringUtils.equals(newDecryptedPwd, decryptedPwd)) {
+                                                               configValue = 
paddingString + "," + encryptedPwd;
+                                                       }
+                                               } else {
+                                                       configValue = 
oldPassword;
+                                               }
+                                       } else {
+                                                                               
                configValue = oldPassword;
+                                                                               
        }
                                } else {
-                                        String paddingString = CRYPT_ALGO + 
"," +  ENCRYPT_KEY + "," + SALT + "," + ITERATION_COUNT;
-                                        String encryptedPwd = 
PasswordUtils.encryptPassword(paddingString + "," +configValue);
-                                        String decryptedPwd = 
PasswordUtils.decryptPassword(paddingString + "," +encryptedPwd);
-
+                                       String paddingString = 
Joiner.on(",").skipNulls().join(CRYPT_ALGO, ENCRYPT_KEY, SALT,
+                                                       ITERATION_COUNT, 
PasswordUtils.generateIvIfNeeded(CRYPT_ALGO));
+                                       String encryptedPwd = 
PasswordUtils.encryptPassword(paddingString + "," + configValue);
+                                       String decryptedPwd = 
PasswordUtils.decryptPassword(paddingString + "," + encryptedPwd);
                                        if (StringUtils.equals(decryptedPwd, 
configValue)) {
-                                                configValue = paddingString + 
"," + encryptedPwd;
+                                               configValue = paddingString + 
"," + encryptedPwd;
                                        }
                                }
                        }
diff --git 
a/security-admin/src/main/java/org/apache/ranger/patch/cliutil/ChangePasswordUtil.java
 
b/security-admin/src/main/java/org/apache/ranger/patch/cliutil/ChangePasswordUtil.java
index 3037053..65b9ccb 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/patch/cliutil/ChangePasswordUtil.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/patch/cliutil/ChangePasswordUtil.java
@@ -189,7 +189,6 @@ public class ChangePasswordUtil extends BaseLoader {
                                        currentEncryptedPassword = 
userMgr.encrypt(userLoginIdTemp, currentPasswordTemp);
                                        if 
(currentEncryptedPassword.equals(dbPassword)) {
                                                
validatePassword(newPasswordTemp);
-                                               logger.info("User:" + 
userLoginIdTemp + "|Password:"+newPasswordTemp);
                                                
userMgr.updatePasswordInSHA256(userLoginIdTemp, newPasswordTemp, true);
                                                logger.info("User '" + 
userLoginIdTemp + "' Password updated sucessfully.");
                                        } else if 
(!currentEncryptedPassword.equals(dbPassword) && defaultPwdChangeRequest) {
diff --git 
a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceService.java
 
b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceService.java
index 2ddb5f3..6344209 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceService.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceService.java
@@ -17,7 +17,6 @@
 
 package org.apache.ranger.service;
 
-import java.io.IOException;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Date;
@@ -46,6 +45,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Service;
 
+import com.google.common.base.Joiner;
+
 @Service
 @Scope("singleton")
 public class RangerServiceService extends RangerServiceServiceBase<XXService, 
RangerService> {
@@ -290,42 +291,41 @@ public class RangerServiceService extends 
RangerServiceServiceBase<XXService, Ra
                return xTrxLog;
        }
 
-       public Map<String, String> 
getConfigsWithDecryptedPassword(RangerService service) throws IOException {
+       public Map<String, String> 
getConfigsWithDecryptedPassword(RangerService service) throws Exception  {
                Map<String, String> configs = service.getConfigs();
                
                String pwd = configs.get(ServiceDBStore.CONFIG_KEY_PASSWORD);
                if(!stringUtil.isEmpty(pwd) && 
ServiceDBStore.HIDDEN_PASSWORD_STR.equalsIgnoreCase(pwd)) {
                        XXServiceConfigMap pwdConfig = 
daoMgr.getXXServiceConfigMap().findByServiceAndConfigKey(service.getId(),
                                        ServiceDBStore.CONFIG_KEY_PASSWORD);
-                        if (pwdConfig != null) {
+
+                       if (pwdConfig != null) {
                                String encryptedPwd = 
pwdConfig.getConfigvalue();
-                                String decryptedPwd = "";
-                                String crypt_algo_array[] = null;
-                                if (encryptedPwd.contains(",")) {
-                                        crypt_algo_array = 
encryptedPwd.split(",");
-                                }
-                                if (crypt_algo_array != null && 
crypt_algo_array.length > 1) {
-                                        String cryptAlgo = null;
-                                        String encryptKey = null;
-                                        String salt = null;
-                                        int iterationCount = 0;
-                                        cryptAlgo = crypt_algo_array[0];
-                                        encryptKey = crypt_algo_array[1];
-                                        salt = crypt_algo_array[2];
-                                        iterationCount = 
Integer.parseInt(crypt_algo_array[3]);
-
-                                        String paddingString = cryptAlgo + "," 
+  encryptKey + "," + salt + "," + iterationCount;
-                                        decryptedPwd = 
PasswordUtils.decryptPassword(encryptedPwd);
-
-                                        if 
(StringUtils.equalsIgnoreCase(paddingString + "," + 
PasswordUtils.encryptPassword(paddingString + "," + decryptedPwd), 
encryptedPwd)) {
-                                                
configs.put(ServiceDBStore.CONFIG_KEY_PASSWORD, encryptedPwd);
-                                        }
-                                } else {
-                                        encryptedPwd = 
pwdConfig.getConfigvalue();
-                                        decryptedPwd = 
PasswordUtils.decryptPassword(encryptedPwd);
-                                        if 
(StringUtils.equalsIgnoreCase(PasswordUtils.encryptPassword(decryptedPwd), 
encryptedPwd)) {
-                                                
configs.put(ServiceDBStore.CONFIG_KEY_PASSWORD, encryptedPwd);
-                                        }
+                               if (encryptedPwd.contains(",")) {
+                                       PasswordUtils util = 
PasswordUtils.build(encryptedPwd);
+                                       String freeTextPasswordMetaData = 
Joiner.on(",").skipNulls().join(util.getCryptAlgo(),
+                                                       new 
String(util.getEncryptKey()), new String(util.getSalt()), 
util.getIterationCount(),
+                                                       
PasswordUtils.needsIv(util.getCryptAlgo()) ? util.getIvAsString() : null);
+                                       String decryptedPwd = 
PasswordUtils.decryptPassword(encryptedPwd);
+                                       if (StringUtils
+                                                       .equalsIgnoreCase(
+                                                                       
freeTextPasswordMetaData + ","
+                                                                               
        + PasswordUtils
+                                                                               
                        .encryptPassword(freeTextPasswordMetaData + "," + 
decryptedPwd),
+                                                                       
encryptedPwd)) {
+                                               
configs.put(ServiceDBStore.CONFIG_KEY_PASSWORD, encryptedPwd); // XXX: method 
name is
+                                                                               
                                                                                
                // getConfigsWithDecryptedPassword,
+                                                                               
                                                                                
                // then why do we store the
+                                                                               
                                                                                
                // encryptedPwd?
+                                       }
+                               } else {
+                                       String decryptedPwd = 
PasswordUtils.decryptPassword(encryptedPwd);
+                                       if 
(StringUtils.equalsIgnoreCase(PasswordUtils.encryptPassword(decryptedPwd), 
encryptedPwd)) {
+                                               
configs.put(ServiceDBStore.CONFIG_KEY_PASSWORD, encryptedPwd); // XXX: method 
name is
+                                                                               
                                                                                
                // getConfigsWithDecryptedPassword,
+                                                                               
                                                                                
                // then why do we store the
+                                                                               
                                                                                
                // encryptedPwd?
+                                       }
                                }
                        }
                }
diff --git 
a/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml 
b/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
index 8ebeeb5..eb7947a 100644
--- a/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
+++ b/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
@@ -568,7 +568,7 @@
        </property>
        <property>
                <name>ranger.password.encryption.algorithm</name>
-               <value>PBEWithMD5AndDES</value>
+               <value>PBEWithHmacSHA512AndAES_128</value>
        </property>
           <property>
                        <name>ranger.default.browser-useragents</name>
diff --git 
a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java 
b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
index f0a6079..b6f13f4 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
@@ -2215,6 +2215,89 @@ public class TestServiceDBStore {
                Mockito.verify(daoManager).getXXPolicy();
        }
 
+       @Test
+       public void test41updateServiceCryptAlgo() throws Exception {
+               XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
+               XXService xService = Mockito.mock(XXService.class);
+               XXServiceConfigMapDao xServiceConfigMapDao = Mockito
+                               .mock(XXServiceConfigMapDao.class);
+               XXServiceConfigDefDao xServiceConfigDefDao = Mockito
+                               .mock(XXServiceConfigDefDao.class);
+               XXUserDao xUserDao = Mockito.mock(XXUserDao.class);
+
+               RangerService rangerService = rangerService();
+               
rangerService.getConfigs().put(ServiceDBStore.CONFIG_KEY_PASSWORD, "*****");
+
+               Mockito.when(daoManager.getXXService()).thenReturn(xServiceDao);
+               Mockito.when(xServiceDao.getById(Id)).thenReturn(xService);
+
+               Mockito.when(daoManager.getXXService()).thenReturn(xServiceDao);
+
+               List<XXServiceConfigDef> xServiceConfigDefList = new 
ArrayList<XXServiceConfigDef>();
+               XXServiceConfigDef serviceConfigDefObj = new 
XXServiceConfigDef();
+               serviceConfigDefObj.setId(Id);
+               xServiceConfigDefList.add(serviceConfigDefObj);
+               Mockito.when(daoManager.getXXServiceConfigDef()).thenReturn(
+                               xServiceConfigDefDao);
+
+               Mockito.when(svcService.update(rangerService))
+                               .thenReturn(rangerService);
+               Mockito.when(daoManager.getXXService()).thenReturn(xServiceDao);
+               Mockito.when(xServiceDao.getById(Id)).thenReturn(xService);
+
+               // the old pass
+               List<XXServiceConfigMap> xConfMapList = new 
ArrayList<XXServiceConfigMap>();
+               XXServiceConfigMap xConfMap = new XXServiceConfigMap();
+               xConfMap.setAddedByUserId(null);
+               xConfMap.setConfigkey(ServiceDBStore.CONFIG_KEY_PASSWORD);
+               //old outdated
+               
xConfMap.setConfigvalue("PBEWithSHA1AndDESede,ENCRYPT_KEY,SALTSALT,4,lXintlvY73rdk3jXvD7CqB5mcSKl0AMhouBbI5m3whrhLdbKddnzxA==");
+               xConfMap.setCreateTime(new Date());
+               xConfMap.setServiceId(null);
+               xConfMap.setUpdatedByUserId(null);
+               xConfMap.setUpdateTime(new Date());
+               xConfMapList.add(xConfMap);
+
+               Mockito.when(daoManager.getXXServiceConfigMap()).thenReturn(
+                       xServiceConfigMapDao);
+       Mockito.when(xServiceConfigMapDao.findByServiceId(Id)).thenReturn(
+                       xConfMapList);
+       Mockito.when(daoManager.getXXServiceConfigMap()).thenReturn(
+                       xServiceConfigMapDao);
+       Mockito.when(xServiceConfigMapDao.remove(xConfMap)).thenReturn(true);
+
+       Mockito.when(daoManager.getXXServiceConfigMap()).thenReturn(
+                       xServiceConfigMapDao);
+       Mockito.when(daoManager.getXXUser()).thenReturn(xUserDao);
+
+       Mockito.when(
+                       rangerAuditFields.populateAuditFields(
+                                       Mockito.isA(XXServiceConfigMap.class),
+                                       
Mockito.isA(XXService.class))).thenReturn(xConfMap);
+
+       Mockito.when(svcService.getPopulatedViewObject(xService)).thenReturn(
+                       rangerService);
+
+       XXServiceResourceDao xServiceResourceDao = 
Mockito.mock(XXServiceResourceDao.class);
+       
Mockito.when(daoManager.getXXServiceResource()).thenReturn(xServiceResourceDao);
+       
Mockito.when(xServiceResourceDao.countTaggedResourcesInServiceId(xService.getId())).thenReturn(0L);
+       Map<String, Object> options = null;
+       RangerService dbRangerService = serviceDBStore
+                       .updateService(rangerService, options);
+
+       Assert.assertNotNull(dbRangerService);
+       Assert.assertEquals(dbRangerService, rangerService);
+       Assert.assertEquals(dbRangerService.getId(), rangerService.getId());
+       Assert.assertEquals(dbRangerService.getName(), rangerService.getName());
+       Assert.assertEquals(dbRangerService.getCreatedBy(),
+                       rangerService.getCreatedBy());
+       Assert.assertEquals(dbRangerService.getDescription(),
+                       rangerService.getDescription());
+       Assert.assertEquals(dbRangerService.getType(), rangerService.getType());
+       Assert.assertEquals(dbRangerService.getVersion(),
+                       rangerService.getVersion());
+       Mockito.verify(daoManager).getXXUser();
+}
     @Test
     public void test41getMetricByTypeusergroup() throws Exception{
        VXGroupList vxGroupList = new VXGroupList();

Reply via email to