Subject | Re: [Firebird-Architect] Security Plugins: An Architecture |
---|---|
Author | Jim Starkey |
Post date | 2004-10-08T14:50:04Z |
Pavel Cisar wrote:
connection through the configuration file:
1. The Y-valve does a lookup for an configuration object of type
"database" and a name that matches the user given database name.
2. The Y-valve looks up the attribute "provider" in the database object.
3. The Y-valve iterations through the provider names looking for an
configuration object of type "provider" that matches the given name
4. The Y-valve looks up the attribute "library" in the provider object
5. The Y-valve iterations through the libraries listed until one loads
6. The Y-valve calls the "attachDatabase" method of the loaded
provider passing it, among other things, the database and provider
configuration objects. ( If the call succeeds, the Y-valve is done)
7. The engine provider (aka The Engine) links the object
configuration object so subsequent attribute lookups will cascade
to the provide configuration if they can't be found the database
configuration.
8. The engine provider (aka the engine) calls to the database manager
with the database name. The database manager either returns an
existing instance of the Database object or creates a new one.
9. The Database constructor receives the chained configuration object
and looks up a SecurityManager attribute
10. If a SecurityManager attribute if found, it looks for a
configuration object of type "SecurityManager" with the name give.
11. If an object is found, the Database looks up "library" and
iterates through the libraries listed (a builtin name match will
short circuit the lookup)
12. If the plugin library can be loaded, it is spliced into the
configuration chain between the database and provider
confiiguration objects
Whew! So, a) lots of plugins can be listed, b) they're loaded in the
order listed, c) there is one chain for the engine, and d) nobody but
the engine uses security plugins. Each plugin has full access to the
configuration chain which will be searched in the order:
1. Database object
2. Security plugins in the order listed
3. Provider object
4. Global attributes
The configuration file subsystem knows nothing of object type or
attribute names until queried, so security plugins can have any
attributes they wish.
[Note: in writing that, it became obvious that a config file
SecurityPlugin is required so an error can be thrown if the plugin can't
be loaded]
plugins. Security plugins are specific to the database engine(s).
chain. At initialization time, it determined the version level of the
aggregate chain (lowest version number of all plugs). All calls to the
security subsystem go through the database object. When a call is made
that wasn't defined in the first version, the database object checks the
chain version number and ignores the call (yes, this means that a very
old security plugin can disable a new one). If the version is OK, it
calls the head of the security provider chain, and somebody does something.
breaks the chain and can't be used. But because every plugin inherits
from SecurityPlugin, it automatically handles all entrypoints defined at
the point in the code base. COM style negotiated interfaces don't bring
anything to the table. Bottom line: any give security plugin doesn't
need to worry about the whole API because it inherits from someone who does.
design is wrong. Single inheritence works just fine in this case.
chain to enable an encryption plugin. Many potential plugins will want
access to the database file name string which they get from the chain.
The encryption plugin will want to encrypt and decryption on page writes
and reads but not do physical I/O. But we may have a plugin that
handles physical I/O for a file on either an encrypted file systems or
something like IBM's intrusion resistent secruity module. Who knows?
The idea is that many guys might handle a single call before or after
passing it down the line. There is no way the engine can possibly
understand this.
Pavel, thanks for your thoughtful comments.
[Non-text portions of this message have been removed]
>Ok, but your spec is more a sketch than complete RFC, so it's a littleThere is also a working prototype in Vulcan. See src/jrd/SecurityDb.cpp.
>bit harder to get a handle on it for us less experienced. Well, let me
>try again to get into it.
>
>
>If it's really as described above, then I like it a lot. This basic ideaThere is the full order of battle for establishing a database
>is very simple but very flexible. Unfortunately, there are some points in
>your spec that are not clear to me.
>
>What's not clear from your spec is how many chains and at what levels
>there could be. Chain of SP instances reflects the particular set of
>configuration values, so if there could be various configuration chains /
>cascades simultaneously applicable on a running system, there definitely
>must be more chains of SP instances (or am I wrong ?)
>
>
connection through the configuration file:
1. The Y-valve does a lookup for an configuration object of type
"database" and a name that matches the user given database name.
2. The Y-valve looks up the attribute "provider" in the database object.
3. The Y-valve iterations through the provider names looking for an
configuration object of type "provider" that matches the given name
4. The Y-valve looks up the attribute "library" in the provider object
5. The Y-valve iterations through the libraries listed until one loads
6. The Y-valve calls the "attachDatabase" method of the loaded
provider passing it, among other things, the database and provider
configuration objects. ( If the call succeeds, the Y-valve is done)
7. The engine provider (aka The Engine) links the object
configuration object so subsequent attribute lookups will cascade
to the provide configuration if they can't be found the database
configuration.
8. The engine provider (aka the engine) calls to the database manager
with the database name. The database manager either returns an
existing instance of the Database object or creates a new one.
9. The Database constructor receives the chained configuration object
and looks up a SecurityManager attribute
10. If a SecurityManager attribute if found, it looks for a
configuration object of type "SecurityManager" with the name give.
11. If an object is found, the Database looks up "library" and
iterates through the libraries listed (a builtin name match will
short circuit the lookup)
12. If the plugin library can be loaded, it is spliced into the
configuration chain between the database and provider
confiiguration objects
Whew! So, a) lots of plugins can be listed, b) they're loaded in the
order listed, c) there is one chain for the engine, and d) nobody but
the engine uses security plugins. Each plugin has full access to the
configuration chain which will be searched in the order:
1. Database object
2. Security plugins in the order listed
3. Provider object
4. Global attributes
The configuration file subsystem knows nothing of object type or
attribute names until queried, so security plugins can have any
attributes they wish.
[Note: in writing that, it became obvious that a config file
SecurityPlugin is required so an error can be thrown if the plugin can't
be loaded]
>I guess that each active database would definitely have it's own SP chainNo, neither the Y-valve, the server, or remote objects use security
>(at lest I read your spec that way). But is it possible for server or
>engine to have its own chain (that doesn't extend to db level) ? It may
>make sense. For example server may have wire comm. encryption SP, and not
>all server comm. is tied to active db attachment, so db level chain can't
>be used.
>
>
plugins. Security plugins are specific to the database engine(s).
>The database object as a pointer to the head of the security plugin
>Next in the pipe is how FB code calls SP's...
>
>If I understood you correctly, a SP chain can contain SP's of different
>types (even those that are not yet invented), hence with different
>interfaces. Is not clear from your spec how it's supposed to be handled.
>
>
chain. At initialization time, it determined the version level of the
aggregate chain (lowest version number of all plugs). All calls to the
security subsystem go through the database object. When a call is made
that wasn't defined in the first version, the database object checks the
chain version number and ignores the call (yes, this means that a very
old security plugin can disable a new one). If the version is OK, it
calls the head of the security provider chain, and somebody does something.
>A detail, of course, but IMO very important one. We can't use one big SPIf you think about, any SecurityPlugin that can't handle an interface
>interface enhanced with new calls whenever we come up with new SP type or
>fix old one. When SP's would support COM interfaces or similar method of
>introspection, then they could be handled by single chain very easily,
>but there are other possibilities.
>
breaks the chain and can't be used. But because every plugin inherits
from SecurityPlugin, it automatically handles all entrypoints defined at
the point in the code base. COM style negotiated interfaces don't bring
anything to the table. Bottom line: any give security plugin doesn't
need to worry about the whole API because it inherits from someone who does.
>Pure class hierarchy should work too,Multiple inheritence is mother nature's way of telling you that your
>but multipurpose SP's would need to use multiple inheritance, and I'm not
>sure how good it would work with late binding and dynamic libraries as
>i'm not a C++ developer. Would be nice to know what method you have in
>mind.
>
>
design is wrong. Single inheritence works just fine in this case.
>Sidenote: That bring us to your proposed general interface for SP. ThereSee above.
>is IMO no point to place userInfo and updateAccountInfo into general SP
>interface as they belong to authentication SP interface, or did I miss
>something here ?
>
>
>What is also important to know is how connection between calling code andNot at all true. When I get to it, all physical I/O will go through the
>SP would be handled. Well, there is a chain of SP's where called SP pass
>the unhandled call to next one, but is it practical to do that on every
>call ? I think that in many cases it's not practical, because once the
>responsibility who will handle the call is sorted out, there is no gain
>to do that again until context changes, so direct binding to particular
>SP entry point is beneficial.
>
chain to enable an encryption plugin. Many potential plugins will want
access to the database file name string which they get from the chain.
The encryption plugin will want to encrypt and decryption on page writes
and reads but not do physical I/O. But we may have a plugin that
handles physical I/O for a file on either an encrypted file systems or
something like IBM's intrusion resistent secruity module. Who knows?
The idea is that many guys might handle a single call before or after
passing it down the line. There is no way the engine can possibly
understand this.
>Here is also the point where the idea of Security Manager comes into playI don't think this is necessary.
>again. SM would act as a single point of call from code to whole SP
>chain. It can handle the pass the call around or direct binding
>transparently (among other thing).
>
>
Pavel, thanks for your thoughtful comments.
[Non-text portions of this message have been removed]