From 6e14814eaa2c77f7b89e656891f9a0ab72e0e88b Mon Sep 17 00:00:00 2001 From: "Chris M. Hostetter" Date: Thu, 7 May 2015 17:44:44 +0000 Subject: [PATCH] SOLR-4392: revert r1678195 which breaks forbidden-api git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1678242 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 - .../handler/dataimport/JdbcDataSource.java | 35 +---- .../dataimport/TestJdbcDataSource.java | 33 ---- .../java/org/apache/solr/util/CryptoKeys.java | 144 ------------------ 4 files changed, 1 insertion(+), 213 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index f6c569479e8..c1c1f2aaba1 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -169,8 +169,6 @@ New Features * SOLR-6220: Rule Based Replica Assignment during collection creation (Noble Paul) -* SOLR-4392: Make it possible to specify AES encrypted password in dataconfig.xml (Noble Paul) - Bug Fixes ---------------------- diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/JdbcDataSource.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/JdbcDataSource.java index 3210807ed0b..cb836870573 100644 --- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/JdbcDataSource.java +++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/JdbcDataSource.java @@ -19,16 +19,12 @@ package org.apache.solr.handler.dataimport; import static org.apache.solr.handler.dataimport.DataImportHandlerException.wrapAndThrow; import static org.apache.solr.handler.dataimport.DataImportHandlerException.SEVERE; -import org.apache.solr.common.SolrException; -import org.apache.solr.util.CryptoKeys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.naming.InitialContext; import javax.naming.NamingException; -import java.io.FileReader; -import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.*; @@ -65,7 +61,6 @@ public class JdbcDataSource extends @Override public void init(Context context, Properties initProps) { - initProps = decryptPwd(initProps); Object o = initProps.get(CONVERT_TYPE); if (o != null) convertType = Boolean.parseBoolean(o.toString()); @@ -106,34 +101,6 @@ public class JdbcDataSource extends } } - private Properties decryptPwd(Properties initProps) { - String encryptionKey = initProps.getProperty("encryptKeyFile"); - if (initProps.getProperty("password") != null && encryptionKey != null) { - // this means the password is encrypted and use the file to decode it - try { - try (FileReader fr = new FileReader(encryptionKey)) { - char[] chars = new char[100];//max 100 char password - int len = fr.read(chars); - if (len < 6) - throw new DataImportHandlerException(SEVERE, "There should be a password of length 6 atleast " + encryptionKey); - Properties props = new Properties(); - props.putAll(initProps); - String password = null; - try { - password = CryptoKeys.decodeAES(initProps.getProperty("password"), new String(chars, 0, len)).trim(); - } catch (SolrException se) { - throw new DataImportHandlerException(SEVERE, "Error decoding password", se.getCause()); - } - props.put("password", password); - initProps = props; - } - } catch (IOException e) { - throw new DataImportHandlerException(SEVERE, "Could not load encryptKeyFile " + encryptionKey); - } - } - return initProps; - } - protected Callable createConnectionFactory(final Context context, final Properties initProps) { // final VariableResolver resolver = context.getVariableResolver(); @@ -428,7 +395,7 @@ public class JdbcDataSource extends } } - Connection getConnection() throws Exception { + private Connection getConnection() throws Exception { long currTime = System.nanoTime(); if (currTime - connLastUsed > CONN_TIME_OUT) { synchronized (this) { diff --git a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestJdbcDataSource.java b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestJdbcDataSource.java index 50a116d4172..8e2d5dd1658 100644 --- a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestJdbcDataSource.java +++ b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestJdbcDataSource.java @@ -16,9 +16,6 @@ */ package org.apache.solr.handler.dataimport; -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; @@ -129,36 +126,6 @@ public class TestJdbcDataSource extends AbstractDataImportHandlerTestCase { assertSame("connection", conn, connection); } - @Test - public void testRetrieveFromJndiWithCredentialsWithEncryptedPwd() throws Exception { - MockInitialContextFactory.bind("java:comp/env/jdbc/JndiDB", dataSource); - File tmpdir = File.createTempFile("test", "tmp", createTempDir().toFile()); - Files.delete(tmpdir.toPath()); - tmpdir.mkdir(); - byte[] content = "secret".getBytes(StandardCharsets.UTF_8); - createFile(tmpdir, "enckeyfile.txt", content, false); - - props.put(JdbcDataSource.JNDI_NAME, "java:comp/env/jdbc/JndiDB"); - props.put("user", "Fred"); - props.put("encryptKeyFile", new File(tmpdir, "enckeyfile.txt").getAbsolutePath()); - props.put("password", "U2FsdGVkX18QMjY0yfCqlfBMvAB4d3XkwY96L7gfO2o="); - props.put("holdability", "HOLD_CURSORS_OVER_COMMIT"); - EasyMock.expect(dataSource.getConnection("Fred", "MyPassword")).andReturn( - connection); - jdbcDataSource.init(context, props); - - connection.setAutoCommit(false); - connection.setHoldability(1); - - mockControl.replay(); - - Connection conn = jdbcDataSource.getConnection(); - - mockControl.verify(); - - assertSame("connection", conn, connection); - } - @Test public void testRetrieveFromJndiFailureNotHidden() throws Exception { MockInitialContextFactory.bind("java:comp/env/jdbc/JndiDB", dataSource); diff --git a/solr/core/src/java/org/apache/solr/util/CryptoKeys.java b/solr/core/src/java/org/apache/solr/util/CryptoKeys.java index 847729340bb..73583396f24 100644 --- a/solr/core/src/java/org/apache/solr/util/CryptoKeys.java +++ b/solr/core/src/java/org/apache/solr/util/CryptoKeys.java @@ -17,27 +17,17 @@ package org.apache.solr.util; * limitations under the License. */ -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.KeyFactory; -import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.spec.X509EncodedKeySpec; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import org.apache.solr.common.SolrException; import org.apache.solr.common.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -117,139 +107,5 @@ public final class CryptoKeys { return false; } - private static byte[][] evpBytesTokey(int key_len, int iv_len, MessageDigest md, - byte[] salt, byte[] data, int count) { - byte[][] both = new byte[2][]; - byte[] key = new byte[key_len]; - int key_ix = 0; - byte[] iv = new byte[iv_len]; - int iv_ix = 0; - both[0] = key; - both[1] = iv; - byte[] md_buf = null; - int nkey = key_len; - int niv = iv_len; - int i = 0; - if (data == null) { - return both; - } - int addmd = 0; - for (; ; ) { - md.reset(); - if (addmd++ > 0) { - md.update(md_buf); - } - md.update(data); - if (null != salt) { - md.update(salt, 0, 8); - } - md_buf = md.digest(); - for (i = 1; i < count; i++) { - md.reset(); - md.update(md_buf); - md_buf = md.digest(); - } - i = 0; - if (nkey > 0) { - for (; ; ) { - if (nkey == 0) - break; - if (i == md_buf.length) - break; - key[key_ix++] = md_buf[i]; - nkey--; - i++; - } - } - if (niv > 0 && i != md_buf.length) { - for (; ; ) { - if (niv == 0) - break; - if (i == md_buf.length) - break; - iv[iv_ix++] = md_buf[i]; - niv--; - i++; - } - } - if (nkey == 0 && niv == 0) { - break; - } - } - for (i = 0; i < md_buf.length; i++) { - md_buf[i] = 0; - } - return both; - } - - public static String decodeAES(String base64CipherTxt, String pwd) { - int[] strengths = new int[]{256, 192, 128}; - Exception e = null; - for (int strength : strengths) { - try { - return decodeAES(base64CipherTxt, pwd, strength); - } catch (Exception exp) { - e = exp; - } - } - throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error decoding ", e); - } - - - public static String decodeAES(String base64CipherTxt, String pwd, final int keySizeBits) { - final Charset ASCII = Charset.forName("ASCII"); - final int INDEX_KEY = 0; - final int INDEX_IV = 1; - final int ITERATIONS = 1; - final int SALT_OFFSET = 8; - final int SALT_SIZE = 8; - final int CIPHERTEXT_OFFSET = SALT_OFFSET + SALT_SIZE; - - try { - byte[] headerSaltAndCipherText = Base64.base64ToByteArray(base64CipherTxt); - - // --- extract salt & encrypted --- - // header is "Salted__", ASCII encoded, if salt is being used (the default) - byte[] salt = Arrays.copyOfRange( - headerSaltAndCipherText, SALT_OFFSET, SALT_OFFSET + SALT_SIZE); - byte[] encrypted = Arrays.copyOfRange( - headerSaltAndCipherText, CIPHERTEXT_OFFSET, headerSaltAndCipherText.length); - - // --- specify cipher and digest for evpBytesTokey method --- - - Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding"); - MessageDigest md5 = MessageDigest.getInstance("MD5"); - - // --- create key and IV --- - - // the IV is useless, OpenSSL might as well have use zero's - final byte[][] keyAndIV = evpBytesTokey( - keySizeBits / Byte.SIZE, - aesCBC.getBlockSize(), - md5, - salt, - pwd.getBytes(ASCII), - ITERATIONS); - - SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES"); - IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]); - - // --- initialize cipher instance and decrypt --- - - aesCBC.init(Cipher.DECRYPT_MODE, key, iv); - byte[] decrypted = aesCBC.doFinal(encrypted); - return new String(decrypted, ASCII); - } catch (BadPaddingException e) { - // AKA "something went wrong" - throw new IllegalStateException( - "Bad password, algorithm, mode or padding;" + - " no salt, wrong number of iterations or corrupted ciphertext.", e); - } catch (IllegalBlockSizeException e) { - throw new IllegalStateException( - "Bad algorithm, mode or corrupted (resized) ciphertext.", e); - } catch (GeneralSecurityException e) { - throw new IllegalStateException(e); - } - } }