From: Alex P. <pe...@in...> - 2004-09-21 09:06:27
|
Hi! During last two weeks I implemented crypt plugins facility for firebird engine. This work was discussed privately with Paul and Dmitry. It was a part of security review, oriented primary to disable interesting firebird 1.5 "feature" - any user could attach to security.fdb file and read all other user's (inc SYSDBA) password's hashes from it. It was enough to: # isql $FBROOT/security.fdb SQL> select * from USERS; In addition for CS security.fdb may be stolen as file by any user, granted local access to firebird - it's required to give such users at least read access to security database. As a minimum counter-measure there is a well known (I think) patch of Ivan Prenosil, which simultaneously disables ability to read other's data from USERS and let user change his own password. But this absolutely doesn't help with stolen file. Therefore I've decided to implement ability to use any crypting algorythm in a form of "crypt plugin" for firebird. Adding of such plugins to engine itself was not a problem. With existing PluginManager it's really easy to invoke required plugins in a really flexible way. I should mention, that for today each password is hashed twice - once at client side, next at server side. In order not to break remote protocol I keep client-side crypting "as is", moreover - for all clients except posix embedded this makes possible not to use loadable libraries (and firebird.conf) at the client. Old ENC_crypt() remains builtin for both client and server. As a quite real sample I've wrote md5 hash calculating plugin, based on openssl. Which crypt plugin(s) to use is defined by Crypt entry in firebird.conf. As default I suggest to use md5, making new installations secure. Use of multiple crypt plugins may be needed at the step of upgrading from 1.x to 2.0 - sysadmin may copy old database and use special keyword "legacy" (means use builtin ENC_crypt) in firebird.conf: Crypt=md5;legacy In this case both md5 and ENC_crypt are used to try for old hashes, but only the first one (md5) is always used to build new ones. Without this feature it becomes impossible to login to the server with md5 crypting using old security.fdb, which appears not good when upgrading existing installations. Users may be given some period to refresh their passwords, after it sysadmin reverts Crypt back to default. All this already works fine if services are used to work with security database. Unfortunately, even if checking of existing passwords always performed by server, creating new ones may happen in 3 ways: 1. Service manager (already works OK). 2. isc_add/modify_user. 3. gsec. Pay attention, that p.2&3 ran both crypting steps on client and sent complete hash directly to security database. In order not to deal with plugins at client side (and certainly to have centralized control upon which crypt plugin to be used!) I reworked both of them to make them use service manager instead of direct modification of security database. Special case - embedded classic server on posix, there that same client gsec is used by services, and therefore must be able to write to security database, but it's not a problem because on that server we already have required plugin to verify passwords. To implement completely -database switch of gsec it was necessary to be able to pass database name to work with to service manager. This feature was already half-done in firebird, therefore I repaired it. To work correctly with SPB new SPB parameter (isc_spb_sec_database) was added. For today only modification of security database is done via services, user listing is printed scanning database directly by gsec. The reason for it is that current services don't include "line-separators" from user to user, therefore it's hard to get security information in traditional for gsec way from service output. The last known to me problem was that old version of gsec might be occasionally used to modify users, and put old hashes in security database, making it unusable. To prevent it, I've added new dpb parameter, isc_dpb_gsec_attach - we already have such for gbak, gfix, gstat. Don't mix it with isc_dpb_sec_attach, it's used internally to mark SecurityDatabase attachment to this database. If security database (detected by name) is opened, dpb is checked for presence of this parameter. Old versions obviously can't substitute it - they know nothing about. Pay attention, that for today this is not an additional security feature - any application can specify isc_dpb_gsec_attach and get direct access to security database. But if we decide to rework services a bit more, it's quite possible to drop isc_dpb_gsec_attach / isc_dpb_sec_attach from remote connections, making impossible to non-local users to attach to security.fdb directly. This may have one more useful side-effect. For today we support anonymous service, which w/o requesting any login information reports location of security.fdb on server (fullpath). It's used by remote gsec to attach to security database, and as soon as we don't need such attachment this service may be dropped too. I don't want to say that reporting path to security.fdb is really big security problem, but don't like it anyway. As a part of this work I've applied Ivan's patch to security.fdb, and faced one bad result. Thereis problem with it in both 1.5 and HEAD. User can't be deleted, because views having COMPUTED fields from underlying tables may be used to insert/update records (certainly, if this fields are not modified), but before delete check is made for ability to modify ALL fields in view. I fixed it deleting records directly from table, not view, but I think this should be treated as a separate firebird bug. Question: should crypt plugins be added to (frozen !) 2.0 or not ? Alex. |