|
[
Permalink
| « Hide
]
Rick Hillegas added a comment - 30/Jul/09 07:27 PM
Attaching derby-4328-01-aa-removeFalseReencryptionClaim.diff. This removes the misleading section. Committed at subversion revision 799420.
Ported 799420 from docs trunk to 10.5 branch at subversion revision 799428.
Sorry for the late response.
I'm reopening the issue because the code used to demonstrate that the developer's guide is wrong, does not do what the developer's guide says. The developer's guide says that SYSCS_SET_DATABASE_PROPERTY should be called with two arguments. First argument should be 'bootPassword" and second argument should be on the form 'oldbpw , newbpw'. The code in the bug description calls SYSCS_SET_DATABASE_PROPERTY with three arguments, and it's therefore expected to fail. I haven't tested if the documented syntax works, but it looks like there is code to handle it. See the code path SystemProcedures.SYSCS_SET_DATABASE_PROPERTY -> PropertyInfo.setDatabaseProperty -> RAMTransaction.setProperty -> PropertyConglomerate.setProperty -> PropertyConglomerate.bootPasswordChange. Thanks for pointing this out, Knut. I can verify that the following script runs as expected:
connect 'jdbc:derby:memory:encdbcbc_128;create=true;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday'; create table t1(i1 int); insert into t1 values ( 1); select * from t1; call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('bootPassword', 'Thursday , Saturday'); disconnect; connect 'jdbc:derby:memory:encdbcbc_128;shutdown=true'; -- should fail connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday'; -- should succeed connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Saturday'; select * from t1; disconnect; But now I don't understand how the passwords are supposed to be escaped if they contain commas or end in whitespace. It doesn't appear to me that the code addresses this issue. The second argument is parsed into old and new passwords by JCECipherFactory.changeBootPassword(). That method seems to just look for the first comma, then trims all the trailing whitespace off of the first boot password. See this script: connect 'jdbc:derby:memory:encdbcbc_128;create=true;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday ,'; create table t1(i1 int); insert into t1 values ( 1); select * from t1; -- this fails to parse the old boot password call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('bootPassword', 'Thursday , , Saturday'); disconnect; connect 'jdbc:derby:memory:encdbcbc_128;shutdown=true'; -- succeeds connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday ,'; select * from t1; disconnect; -- fails connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Saturday'; If someone wants to re-instate this documentation, then I think that the new documentation should address the escaping topic. I can see a couple resolutions of this issue: 1) Leave the situation as it is. Don't re-instate this documentation. Users can continue to change the boot password using the currently documented technique. The currently documented technique may have its own escaping issues involving semicolons. 2) Re-instate the documentation with a note that this technique will not work for boot passwords which contain commas or end in whitespace. 3) Invent some escaping syntax, wire it into JCECipherFactory, then describe that in the re-instated documentation. If we go this route, then we may want to make the escaping syntax work for the other (currently documented) technique for changing boot passwords. Option 2 sounds good for now.
One possible future enhancement could be to introduce a system procedure for changing the boot password, which would help us around the quoting issues with both of the existing approaches. Something like this: PreparedStatement ps = conn.prepareStatement("SYSCS_UTIL.SYSCS_CHANGE_BOOT_PASSWORD(?,?)"); ps.setString(1, " good, old password "); ps.setString(2, "new, even better password ; 1,2,3,4 "); ps.execute(); Thanks, Knut. I think (1) or (2) would be adequate and I incline more toward (1). I don't see much value in the procedural api since there is another way to change the boot password. Given the escaping issues, I think that this procedural api is a little hokey. Does (2) support an important use-case?
My problem with (1) is that it would leave some functionality undocumented, and the code will probably live forever because no one understands why it's there. If we choose (1) I feel that we should also remove the code that implements it, but that could cause backward compatibility issues.
You mentioned that the alternative way to change the boot password may also have escaping issues, so I don't quite see why one should be left in the documentation and the other one removed. Changing the password by using the newBootPassword attribute requires that the database is not booted. Doesn't that make it vulnerable to race conditions if others connect the database while we're attempting to change the boot password? In that case using the set-property method might be preferable. Thanks, Knut. I agree that the code supporting (2) should be left in place for compatibility reasons. I think that the escaping issue involving the semicolon is a general issue for all components of the connection url. If that issue isn't documented somewhere, I agree that we should address it in such a way that we cover all of those components. I don't think I understand the race condition: are you worried that the dbo will try to change the boot password to two different values simultaneously?
I think that you cannot escape the semicolons in the connection url. That is, components of the connection url simply can't have semicolons in them. This creates another problem for using SYSCS_UTIL.SYSCS_CHANGE_BOOT_PASSWORD. Using that procedure, you can set the boot password to be an illegal password with an embedded semicolon. You then can't boot the database. The following script shows this behavior:
connect 'jdbc:derby:memory:encdbcbc_128;create=true;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday'; create table t1(i1 int); insert into t1 values ( 1); select * from t1; call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('bootPassword', 'Thursday , Thurs;day'); disconnect; connect 'jdbc:derby:memory:encdbcbc_128;shutdown=true'; -- fails connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thurs;day'; Note: Until DERBY-2409 is fixed, there is a concern that changing password using the URL may fail silently.
The race condition I'm talking about is the following: If you shut down the database and reboot it with the newBootPassword attribute, this may or may not actually change the password, depending on whether or not someone else has rebooted the database in the meantime. As Dag mentions, this may even go unnoticed because of DERBY-2409.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||