Repository: tomee Updated Branches: refs/heads/master 234d35e95 -> 4baf8a60e
TOMEE-1651 adding SafePasswordCipher Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/4baf8a60 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/4baf8a60 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/4baf8a60 Branch: refs/heads/master Commit: 4baf8a60ef9f1a0a8b5dab7f63bdead0edb231d9 Parents: 234d35e Author: Romain Manni-Bucau <rmann...@gmail.com> Authored: Tue Nov 3 08:37:36 2015 -0800 Committer: Romain Manni-Bucau <rmann...@gmail.com> Committed: Tue Nov 3 08:37:36 2015 -0800 ---------------------------------------------------------------------- .../openejb/cipher/PasswordCipherFactory.java | 1 - .../openejb/cipher/SafePasswordCipher.java | 30 +++++++++ .../openejb/cipher/SafePasswordCipherBase.java | 25 +++++++ .../openejb/util/PropertyPlaceHolderHelper.java | 32 +++++++-- .../apache/openejb/cipher/ArrayCipherTest.java | 68 ++++++++++++++++++++ pom.xml | 2 +- 6 files changed, 150 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/4baf8a60/container/openejb-core/src/main/java/org/apache/openejb/cipher/PasswordCipherFactory.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cipher/PasswordCipherFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/cipher/PasswordCipherFactory.java index fded62b..6d5b1a4 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/cipher/PasswordCipherFactory.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/cipher/PasswordCipherFactory.java @@ -26,7 +26,6 @@ import java.util.Map; @SuppressWarnings("deprecation") public class PasswordCipherFactory { - /** * Create a {@link org.apache.openejb.cipher.PasswordCipher} instance from the * passwordCipher class name. http://git-wip-us.apache.org/repos/asf/tomee/blob/4baf8a60/container/openejb-core/src/main/java/org/apache/openejb/cipher/SafePasswordCipher.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cipher/SafePasswordCipher.java b/container/openejb-core/src/main/java/org/apache/openejb/cipher/SafePasswordCipher.java new file mode 100644 index 0000000..06f4f5f --- /dev/null +++ b/container/openejb-core/src/main/java/org/apache/openejb/cipher/SafePasswordCipher.java @@ -0,0 +1,30 @@ +/* + * 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. + */ + +package org.apache.openejb.cipher; + +// we dont use char[]->char[] for encrypt since it is a tool only method normally (execution time ~ few seconds) +public interface SafePasswordCipher extends PasswordCipher { + /** + * Note: decrypt method is not wired to decryptAsCharArray() by default. You can forbid its usage + * throwing an exception (UnsupportedOperationException) is desired. + * + * @param encryptedPassword + * @return the decrypted password. + */ + char[] decryptAsCharArray(char[] encryptedPassword); +} http://git-wip-us.apache.org/repos/asf/tomee/blob/4baf8a60/container/openejb-core/src/main/java/org/apache/openejb/cipher/SafePasswordCipherBase.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cipher/SafePasswordCipherBase.java b/container/openejb-core/src/main/java/org/apache/openejb/cipher/SafePasswordCipherBase.java new file mode 100644 index 0000000..4df47f2 --- /dev/null +++ b/container/openejb-core/src/main/java/org/apache/openejb/cipher/SafePasswordCipherBase.java @@ -0,0 +1,25 @@ +/* + * 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. + */ + +package org.apache.openejb.cipher; + +public abstract class SafePasswordCipherBase implements SafePasswordCipher { + @Override + public String decrypt(final char[] encryptedPassword) { + throw new UnsupportedOperationException(getClass().getName() + " doesn't support String decryption"); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/4baf8a60/container/openejb-core/src/main/java/org/apache/openejb/util/PropertyPlaceHolderHelper.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/util/PropertyPlaceHolderHelper.java b/container/openejb-core/src/main/java/org/apache/openejb/util/PropertyPlaceHolderHelper.java index 61cbc7c..4015771 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/util/PropertyPlaceHolderHelper.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/util/PropertyPlaceHolderHelper.java @@ -22,6 +22,7 @@ import org.apache.commons.lang3.text.StrSubstitutor; import org.apache.openejb.cipher.PasswordCipher; import org.apache.openejb.cipher.PasswordCipherException; import org.apache.openejb.cipher.PasswordCipherFactory; +import org.apache.openejb.cipher.SafePasswordCipher; import org.apache.openejb.loader.SystemInstance; import java.util.Map; @@ -56,17 +57,32 @@ public final class PropertyPlaceHolderHelper { return null; } if (!raw.contains(PREFIX) || !raw.contains(SUFFIX)) { - return decryptIfNeeded(raw.replace(PREFIX, "").replace(SUFFIX, "")); + return String.class.cast(decryptIfNeeded(raw.replace(PREFIX, "").replace(SUFFIX, ""), false)); } String value = SUBSTITUTOR.replace(raw); if (!value.equals(raw) && value.startsWith("java:")) { value = value.substring(5); } - return decryptIfNeeded(value.replace(PREFIX, "").replace(SUFFIX, "")); + return String.class.cast(decryptIfNeeded(value.replace(PREFIX, "").replace(SUFFIX, ""), false)); } - private static String decryptIfNeeded(final String replace) { + public static Object simpleValueAsStringOrCharArray(final String raw) { + if (raw == null) { + return null; + } + if (!raw.contains(PREFIX) || !raw.contains(SUFFIX)) { + return decryptIfNeeded(raw.replace(PREFIX, "").replace(SUFFIX, ""), true); + } + + String value = SUBSTITUTOR.replace(raw); + if (!value.equals(raw) && value.startsWith("java:")) { + value = value.substring(5); + } + return decryptIfNeeded(value.replace(PREFIX, "").replace(SUFFIX, ""), true); + } + + private static Object decryptIfNeeded(final String replace, final boolean acceptCharArray) { if (replace.startsWith(CIPHER_PREFIX)) { final String algo = replace.substring(CIPHER_PREFIX.length(), replace.indexOf(':', CIPHER_PREFIX.length() + 1)); PasswordCipher cipher; @@ -79,7 +95,11 @@ public final class PropertyPlaceHolderHelper { throw new IllegalArgumentException(e); } } - return cipher.decrypt(replace.substring(CIPHER_PREFIX.length() + algo.length() + 1).toCharArray()); + + final char[] input = replace.substring(CIPHER_PREFIX.length() + algo.length() + 1).toCharArray(); + return acceptCharArray && SafePasswordCipher.class.isInstance(cipher) ? + SafePasswordCipher.class.cast(cipher).decryptAsCharArray(input) : + cipher.decrypt(input); } return replace; } @@ -89,7 +109,7 @@ public final class PropertyPlaceHolderHelper { return null; } if (!aw.contains(PREFIX) || !aw.contains(SUFFIX)) { - return decryptIfNeeded(aw); + return String.class.cast(decryptIfNeeded(aw, false)); } String value = CACHE.getProperty(aw); @@ -121,7 +141,7 @@ public final class PropertyPlaceHolderHelper { final Object rawValue = entry.getValue(); if (rawValue instanceof String) { final String value = (String) rawValue; - updated.put(entry.getKey(), cache ? value(value) : simpleValue(value)); + updated.put(entry.getKey(), cache ? value(value) : simpleValueAsStringOrCharArray(value)); } else { updated.put(entry.getKey(), rawValue); } http://git-wip-us.apache.org/repos/asf/tomee/blob/4baf8a60/container/openejb-core/src/test/java/org/apache/openejb/cipher/ArrayCipherTest.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/test/java/org/apache/openejb/cipher/ArrayCipherTest.java b/container/openejb-core/src/test/java/org/apache/openejb/cipher/ArrayCipherTest.java new file mode 100644 index 0000000..92111cd --- /dev/null +++ b/container/openejb-core/src/test/java/org/apache/openejb/cipher/ArrayCipherTest.java @@ -0,0 +1,68 @@ +/** + * 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. + */ +package org.apache.openejb.cipher; + +import org.apache.openejb.junit.ApplicationComposer; +import org.apache.openejb.testing.Classes; +import org.apache.openejb.testing.ContainerProperties; +import org.apache.openejb.testing.SimpleLog; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.annotation.Resource; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@SimpleLog +@RunWith(ApplicationComposer.class) +@Classes +@ContainerProperties({ + @ContainerProperties.Property(name = "foo", value = "new://Resource?class-name=org.apache.openejb.cipher.ArrayCipherTest$Foo"), + @ContainerProperties.Property(name = "foo.chars", value = "cipher:org.apache.openejb.cipher.ArrayCipherTest$MySafePasswordCipher:ca"), + @ContainerProperties.Property(name = "foo.string", value = "cipher:org.apache.openejb.cipher.ArrayCipherTest$MySafePasswordCipher:string") +}) +public class ArrayCipherTest { + @Resource + private Foo foo; + + @Test + public void run() { + assertNotNull(foo); + assertNotNull(foo.chars); + assertNotNull(foo.string); + assertEquals("stringdaca", foo.string); + assertEquals("cadaca", new String(foo.chars)); + } + + public static class Foo { + private char[] chars; + private String string; + } + + public static class MySafePasswordCipher extends SafePasswordCipherBase { + @Override + public char[] encrypt(final String plainPassword) { + throw new UnsupportedOperationException(); + } + + @Override + public char[] decryptAsCharArray(char[] encryptedPassword) { + return (new String(encryptedPassword) + "daca").toCharArray(); + } + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/4baf8a60/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 8e5084e..3088c46 100644 --- a/pom.xml +++ b/pom.xml @@ -104,7 +104,7 @@ <maven-bundle-plugin.version>2.3.7</maven-bundle-plugin.version> <!-- This is used by a manifest classpath entry --> - <xbeanVersion>4.4</xbeanVersion> + <xbeanVersion>4.5-SNAPSHOT</xbeanVersion> <!-- OSGi bundles properties --> <openejb.bundle.activator/>