I've completed most of the coding for this small feature. Now I need to
figure out a way to get the "encrypted" meta-information from GAttributeInfo
in the GBeanOverride class so that it will encrypt attributes according to
the meta-information when saved to config.xml. This turns out to be a
non-trivial work, as GBeanOverride does not maintain any direct/indirect
reference to GAttributeInfo! It does contain a "gbeanInfo" field, but its
type is String and I cannot understand how its value could be used in any
way.

One possible solution is to duplicate the "encrypted“ meta-information in
the config.xml, in a similar way as what we are doing with "null"
attributes. But apparently this is not the ideal way. Does anybody have a
better idea? Thanks a lot!

-Jack


On Wed, May 13, 2009 at 4:04 PM, Jack Cai <greensi...@gmail.com> wrote:

> Thanks Jarek for your comments! I should have provided more description
> about the fix -
>
> 1. setAttribute() is usually called by the unmarshaller, so it should
> actually do the decryption. Since the decryption will automatically bypass
> unecrypted values, it won't do any harm if the passed-in attribute value is
> not encrypted.
>
> 2. getAttribute() is usually called by various consumers that wants to read
> the real value (decrypted), so it just returns what is stored in the
> GBeanData (already decrypted value).
>
> 3. The current patch does do encryption for writeExternal(). The reason
> decryption is not done for readExternal() directly is because readExternal()
> calls setAttribute() which does the decryption.
>
> I agree that it's not optimal to hard-code to encrypt "password"
> attributes, and better to use the GAttributeInfo to make this configurable.
> My suggestion is to set encryption on for all attributes whose name contains
> "password" and off for the rest. We can thus eliminate the hard-code logic
> in GBeanOverride too (for encrption in config.xml).
>
> I'm going to create a patch if no objection.
>
> -Jack
>
> 2009/5/13 Jarek Gawor <jga...@gmail.com>
>
> Jack,
>>
>> I was thinking about this a while ago and had a slightly different
>> approach. I was thinking of adding a 'protected' or 'encrypted'
>> attribute to the GAttributeInfo (for example, just like the
>> 'persistent' attribute) to indicate that this attribute should be
>> "encrypted" in the serialized file. I wanted to allow for any
>> attribute to be encrypted even if it doesn't have the "password" name
>> in it. And I think with this way we could also expose that setting via
>> our GBean annotations.
>>
>> Btw, hmm... shouldn't encrypt be called in setAttribute() and decrypt
>> in getAttribute() or at least encrypt in writeExternal() and decrypt
>> in readExternal() ?
>>
>> Jarek
>>
>> On Tue, May 12, 2009 at 4:06 AM, Jack Cai <greensi...@gmail.com> wrote:
>> > Recently someone pointed out to us that password specified in the
>> deployment
>> > plan is stored in clear text in the config.ser after deployment, for
>> > example, when deploying a datasource with the database password
>> specified in
>> > the deployment plan. I notice that there was another user mentioning
>> exactly
>> > the same problem in the geronimo-user list two years ago [1].
>> >
>> > I did a little more dig and also found this JIRA [2] along with this
>> > discussion [3] on encrypting passwords in deployment plans.
>> >
>> > I understand that there are different arguments on what is "real"
>> security.
>> > But I also well appreciate users' concerns on having clear text password
>> > appearing in the system. In China, we have a saying "guard against the
>> good
>> > guys but not the bad guys", meaning the guard is there just to prevent
>> the
>> > good guys from doing bad. Taking the same example as in the old thread
>> [3],
>> > if we lock a bicycle, then the good guys won't steal it, while the bad
>> guys
>> > with the intention to steal it can still find ways to steal it. But if
>> we
>> > leave the bicycle unlocked, then the good guys are tempted to steal the
>> > bicycle too, because it's so easy.
>> >
>> > Back to JIRA [2], I think an alternative is to let user input the
>> password
>> > in encrypted form in the deployment plan at the very beginning. We can
>> > provide a small command line tool to let user ecrypt the password
>> > beforehands. If this is acceptable, then there is a very simple way to
>> > satisfy requirement [1] & [2]. We can simply add a little encryption
>> logic
>> > in the class org.apache.geronimo.gbean.GBeanData [4], similar to what we
>> did
>> > in GBeanOverride for config.xml.
>> >
>> > Comments are welcome.
>> >
>> > -Jack
>> >
>> >
>> > [1]
>> http://www.nabble.com/plaintext-password-in-config.ser-to9834211.html
>> > [2] http://issues.apache.org/jira/browse/GERONIMO-3003
>> > [3]
>> >
>> http://www.nabble.com/Plaintext-passwords-in-Geronimo-plans-and-config-files-td9100565s134.html
>> > [4]
>> > Index:
>> >
>> D:/Dev/s/wasce_v2.1.0.1/server/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/gbean/GBeanData.java
>> > ===================================================================
>> > ---
>> >
>> D:/Dev/s/wasce_v2.1.0.1/server/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/gbean/GBeanData.java
>> > (revision 111111)
>> > +++
>> >
>> D:/Dev/s/wasce_v2.1.0.1/server/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/gbean/GBeanData.java
>> > (working copy)
>> > @@ -27,6 +27,8 @@
>> >  import java.util.Map;
>> >  import java.util.Set;
>> >
>> > +import org.apache.geronimo.crypto.EncryptionManager;
>> > +
>> >  /**
>> >   * @version $Rev: 556119 $ $Date: 2007-07-13 15:34:02 -0400 (Fri, 13
>> Jul
>> > 2007) $
>> >   */
>> > @@ -112,6 +114,10 @@
>> >      }
>> >
>> >      public void setAttribute(String name, Object value) {
>> > +        if (name.toLowerCase().indexOf("password") > -1
>> > +                && value instanceof String) {
>> > +            value = EncryptionManager.decrypt((String) value);
>> > +        }
>> >          attributes.put(name, value);
>> >      }
>> >
>> > @@ -207,6 +213,10 @@
>> >          for (Map.Entry<String, Object> entry : attributes.entrySet()) {
>> >              String name = entry.getKey();
>> >              Object value = entry.getValue();
>> > +            if (name.toLowerCase().indexOf("password") > -1
>> > +                    && value instanceof String) {
>> > +                value = EncryptionManager.encrypt((String) value);
>> > +            }
>> >              try {
>> >                  out.writeObject(name);
>> >                  out.writeObject(value);
>> >
>> >
>> >
>>
>
>

Reply via email to