aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2007-03-08 23:58:28 +0000
committerRuss Allbery <rra@stanford.edu>2007-03-08 23:58:28 +0000
commitaf5baf462cf17cd53c7df44e6d63d95db2dcb266 (patch)
treebb2c6678ac75de0c9f8c49e1c401d0bbfb22573e /doc
parent7d50b9887901466994b9fe3af4d79624959217ff (diff)
Renamed to docs for consistency with other packages.
Diffstat (limited to 'doc')
-rw-r--r--doc/design-acl90
-rw-r--r--doc/design-api94
-rw-r--r--doc/design-schema112
-rw-r--r--doc/netdb-role-api32
-rw-r--r--doc/notes223
5 files changed, 0 insertions, 551 deletions
diff --git a/doc/design-acl b/doc/design-acl
deleted file mode 100644
index cb07247..0000000
--- a/doc/design-acl
+++ /dev/null
@@ -1,90 +0,0 @@
- ACL Layer Design for the Wallet
-
-Introduction
-
- This is a description of the ACL layer of the wallet implementation.
- This is a specification of the expected behavior of the ACL
- implementation and includes the syntax and semantics of ACL strings
- used in the database. The ACL strings used by the wallet are intended
- to be an extensible format to which additional ACL backends may be
- added as needed. When new ACL backends are added, they should be
- described here.
-
-Syntax
-
- An ACL in the wallet consists of two pieces of data, a <scheme> and an
- <instance>. <scheme> is one or more characters in the set [a-z0-9-]
- that identifies the ACL backend to use when interpreting this ACL.
- <identifier> is zero or more characters including all printable ASCII
- characters except whitespace. Only the implementation of <scheme>
- knows about the meaning of <identifier>. <identifier> may include
- zero or more users.
-
-Semantics
-
- All users are authenticated to the wallet by Kerberos and are
- therefore represented by a Kerberos principal, which follows the
- normal Kerberos rules for string representation.
-
- Whenever there is a question about whether a user is permitted an
- action by a particular ACL, the following verification algorithm is
- used: Iterate through each ACL string on the ACL in question. If the
- ACL string is malformatted or the scheme is not recognized, skip it.
- Otherwise, dispatch the question to the check function of the ACL
- implementation, passing it the principal identifying the client and
- the <identifier> portion of the ACL string. This function returns
- either authorized or unauthorized. If authorized, end the search; if
- unauthorized, continue to the next ACL string.
-
- There is no support in this scheme for negative ACLs.
-
- There is one slight complication, namely that some ACL methods need to
- maintain persistant state for performance reasons (consider, for
- example, an ACL layer implemented with LDAP queries). Therefore, each
- ACL handler should be represented by an object, and when the ACL code
- discovers it doesn't already have an object on hand for a given ACL
- scheme, it should construct one before querying it. If construction
- fails, it should fail that scheme and any ACL that uses that scheme,
- but still allow access if an ACL not using that scheme grants access
- to the user.
-
-ACL Schemes
-
- krb5
-
- The <identifier> is a fully-qualified Kerberos principal. Access is
- granted if the principal of the client matches <identifier>.
-
- krb5-group
-
- <identifier> is the name of a group that contains a list of Kerberos
- principals. (Storage of this group is left to the discretion of the
- backend, but will probably either be a MySQL table or a file on disk.)
- Access is granted if the principal of the client matches one of the
- principals contained in the group.
-
- ldap-entitlement
-
- <identifier> is an entitlement. If the entitlement attribute of the
- LDAP entry corresponding to the given principal contains the
- entitlement specified in <identifier>, access is granted.
-
- netdb
-
- This ACL type is a special case that right now can't be used through
- the normal ACL mechanism because access depends on the name of the
- object being accessed through logic peculiar to the backend. It is
- included here as a placeholder, but will normally only be used via the
- backend-specific fallback used when the ACL is not present.
-
- Access is granted if the action performed is one of the normal owner
- actions, the object being accessed corresponds to a system key, and
- the user is an administrator of that system in NetDB (Stanford's
- system management database).
-
- For this ACL, <identifier> is empty.
-
- pts
-
- <identifier> is the name of an AFS PTS group. Access is granted if
- the principal of the user is a member of that AFS PTS group.
diff --git a/doc/design-api b/doc/design-api
deleted file mode 100644
index 0af6862..0000000
--- a/doc/design-api
+++ /dev/null
@@ -1,94 +0,0 @@
- Wallet Server API
-
-Introduction
-
- Here is the specification for the API that components of the wallet
- server will implement. There are two pluggable components in the
- wallet server: the implementation of a particular object type (which
- amounts mostly to storage and retrieval), and the ACL implementation.
-
-Object API
-
- new(NAME, DBH)
-
- Creates a new object with the given object name. Takes a database
- handle, which should be stored with the object and used for any
- further operations. This method should inherit from the generic
- Wallet::Object object, which implements the following methods:
-
- new(NAME, DBH)
- create(NAME, DBH)
- owner([ACL-ID])
- acl(TYPE [, ACL-ID])
- expires([DATETIME])
- get(PRINCIPAL, HOSTNAME [, DATETIME])
- store(DATA, PRINCIPAL, HOSTNAME [, DATETIME])
- show()
- error()
-
- that manipulate the basic object data. Generally all this function
- needs to do is call the parent new() constructor, but if there are
- additional database tables used by this object type, it may load
- additional data.
-
- create(NAME, DBH, PRINCIPAL, HOSTNAME [, DATETIME])
-
- Like new(), but instead creates a new entry in the database with the
- given name. As with new(), the generic function will normally do all
- of the work. Takes some additional information to put into the
- created fields in the database.
-
- get(PRINCIPAL, HOSTNAME [, DATETIME])
-
- Applied to a returned object, retrieves the data contained in the
- object in question. Takes the information about who is doing the
- retrieval so that the database metadata can be updated. The result is
- either the relevant data or undef in the event of an error. On error,
- the caller should call error() to get the error text.
-
- store(DATA, PRINCIPAL, HOSTNAME [, DATETIME])
-
- Store user-supplied data into the given object. This may not be
- supported by all backends (for instance, backends that automatically
- generate the data will not support this). Takes the information about
- who is doing the store so that the database metadata can be updated.
- The result is true on success and false on failure. On error, the
- caller should call error() to get the error text.
-
- show()
-
- Returns a formatted text description of the object suitable for human
- display, or undef on error. On error, the caller should call error()
- to get the error text.
-
- default_check(PRINCIPAL)
-
- Applies the default authorization rules for this object type, if any,
- and returns 1 if those default authorization rules allow access. If
- there are no authorization rules or if they don't allow access,
- returns 0. On error, returns undef; the caller should call error() to
- get the error text.
-
- error()
-
- Returns the error text from the last failed get(), store(), show(), or
- default_check() call.
-
-ACL API
-
- new()
-
- Creates a persistant ACL verifier for the given ACL type. This may do
- nothing, but some ACL verifiers require some persistant data, like a
- persistant LDAP connection.
-
- check(PRINCIPAL, ACL)
-
- Checks whether the given PRINCIPAL should be allowed access given ACL.
- Returns 1 if access is granted, 0 if access is declined, and undef on
- error. On error, the caller should call error() to get the error text
- but generally should continue with checking other ACLs.
-
- error()
-
- Returns the error text of the last error.
diff --git a/doc/design-schema b/doc/design-schema
deleted file mode 100644
index c82c387..0000000
--- a/doc/design-schema
+++ /dev/null
@@ -1,112 +0,0 @@
- Database Schema for the Wallet
-
-Introduction
-
- Here should be a comprehensive list of the tables used by the wallet,
- the SQL to create those tables, and a specification of what they're
- for. It's possible that this file will later be written in some other
- format to make extraction of the SQL easier. Please do not copy this
- data into some other file that could get out of sync with this
- documentation; instead, if it's necessary to change the format, please
- move this file elsewhere and keep the documentation with the schema.
-
-Object Metadata
-
- Each object stored in the wallet is represented by an entry in the
- objects table:
-
- create table objects
- (ob_name varchar(255) not null,
- ob_type varchar(16)
- not null references types(ty_name),
- ob_owner integer default null references acls(ac_id),
- ob_acl_get integer default null references acls(ac_id),
- ob_acl_store integer default null references acls(ac_id),
- ob_acl_show integer default null references acls(ac_id),
- ob_acl_delete integer default null references acls(ac_id),
- ob_acl_flags integer default null references acls(ac_id),
- ob_expires datetime,
- ob_created_by varchar(255) not null,
- ob_created_from varchar(255) not null,
- ob_created_on datetime not null,
- ob_stored_by varchar(255),
- ob_stored_from varchar(255),
- ob_stored_on datetime,
- ob_downloaded_by varchar(255),
- ob_downloaded_from varchar(255),
- ob_downloaded_on datetime,
- primary key (ob_name, ob_type));
-
- Object names are not globally unique but only unique within their
- type, so the table has a joint primary key. I haven't yet decided
- what indices the table will need.
-
- Each object has an owner and then up to five more specific ACLs. The
- ob_acl_flags ACL controls who can set flags on this object. Each ACL
- references entries in the following table:
-
- create table acls
- (ac_id integer auto_increment primary key);
-
- This just keeps track of unique ACL identifiers. The data is then
- stored in:
-
- create table acl_entry
- (ae_id integer not null references acls(ac_id),
- ae_scheme varchar(32)
- not null references acl_schemes(as_name),
- ae_identifier varchar(255));
-
- Finally, each object may have zero or more flags associated with it.
-
- create table flags
- (fl_object varchar(255)
- not null references objects(ob_name),
- fl_type varchar(16)
- not null references objects(ob_type),
- fl_flag varchar(32)
- not null references flag_names(fn_name));
-
- The following are normalization tables used to constrain the values
-
- create table types
- (ty_name varchar(16) primary key);
-
- create table acl_schemes
- (as_name varchar(32) primary key);
-
- create table flag_names
- (fn_name varchar(32) primary key);
-
-ACL Backend Data
-
- To support the krb5-group ACL type, groups are stored in the following
- table:
-
- create table krb5_groups
- (kg_name varchar(255) primary key,
- kg_owner integer default null references acls(ac_id));
-
- Each group contains zero or more principals:
-
- create table krb5_members
- (km_group varchar(255)
- not null references krb5_groups(kg_name),
- km_principal varchar(255) not null);
-
-Storage Backend Data
-
- To support restricting the allowable enctypes for a given keytab, the
- keytab backend will use the following table:
-
- create table keytab_enctypes
- (ke_principal varchar(255)
- not null references objects(ob_name),
- ke_enctype varchar(255)
- not null references enctypes(en_name));
-
- There is a normalization table to ensure that only supported enctypes
- are configured:
-
- create table enctypes
- (en_name varchar(255) primary key);
diff --git a/doc/netdb-role-api b/doc/netdb-role-api
deleted file mode 100644
index 6dbcfa4..0000000
--- a/doc/netdb-role-api
+++ /dev/null
@@ -1,32 +0,0 @@
- NetDB Role API
-
-Basic API
-
- remctl netdb-node-roles-rc netdb node-roles <sunetid> <node>
-
- Note that the remctl principal used here is actually the underlying
- host principal, not the principal for that alias. <node> must be
- fully qualified. This will return a list of all roles that <sunetid>
- has with <node>, chosen from admin, team, or user. For our purposes,
- we probably want to look at admin and team, but we may want user as
- well.
-
- You must be a current NetDB user to use it. It just sucks rows out of
- a view matching on the SUNet ID and node name, so getting no result
- can mean "no such SUNet ID," "no such node," or "SUNet ID isn't
- associated with node."
-
-Examples
-
- % remctl netdb-node-roles-rc netdb node-roles riepel zathras.stanford.edu
- admin
- team
- user
- % remctl netdb-node-roles-rc netdb node-roles riepel calgon.stanford.edu
- admin
- %
-
-Wallet Issues
-
- We'll need to get a principal registered to use it that can query
- anything for any node but isn't otherwise authorized to use NetDB.
diff --git a/doc/notes b/doc/notes
deleted file mode 100644
index eaa6e5b..0000000
--- a/doc/notes
+++ /dev/null
@@ -1,223 +0,0 @@
- Wallet Implementation Notes
-
-Introduction
-
- Collected here are implementation notes about design decisions,
- external interfaces, integration, internal structure, and related
- issues. This document will mostly be of interest to people who want
- to modify the wallet code or who are curious about its design. This
- is not user documentation or protocol specifications; see elsewhere
- for that.
-
-Server Issues
-
- Interface
-
- We need two interfaces for retrieving items, one which retrieves the
- current stored item and one which generates a new item. This
- particularly applies to keytabs. We also don't want new keytabs to be
- generated for certain keys even by accident without an explicit action
- taken, but for most keytabs we want to generate new keys each time.
- So we need an interface like:
-
- get keytab
-
- Generates a new keytab normally, but retrieves the existing keytab
- if we've marked the key as unchanging.
-
- flag unchanging
- flag -unchanging
-
- Change the state to generate new keytabs each time or always try to
- pull the existing key. This operation should probably be
- privileged.
-
- So if you want to generate a new key for a keytab that would otherwise
- be persistant, mark it changing, download the new key, and then mark
- it unchanging again.
-
- Possibly need to do something about occasionally changing keys of
- keytabs that are otherwise marked unchanging, or we're going to open
- ourselves to brute force attacks.
-
- ACL Management
-
- Supported operations are: get, store, create (triggered by a get or
- store of something that didn't already exist), delete, show, and
- setting or clearing flags. Each of these need a separate ACL
- potentially. Not sure if we're going to need separate ACLs for each
- flag operation.
-
- Administrators get implicit access to do anything. There does need to
- be an ACL on create, but that should probably be implemented per
- backend class (keytabs and certs will use NetDB roles, files will use
- some namespace limitation based on a separate table, etc.). There may
- also need to be a class-specific fallback when no ACL is set to deal
- with, for instance, ACL management via NetDB roles for systems that
- have no more specific ACL.
-
- Owner rights provides get, store, and show, but not delete or setting
- or clearing flags (not delete because it's too destructive and we
- don't want it done accidentally). This can be overridden by more
- precise ACL settings. So the ACL logic would go like this:
-
- * If the user is an administrator, operation is permitted.
-
- * Otherwise, check the object. If it exists and has a setting for
- that specific ACL, apply that ACL.
-
- * If the object exists but with no specific ACL setting and the
- operation is one of get, store, or show, apply the owner ACL.
-
- * If there is no listed owner ACL, punt to the backend and see if it
- can apply a default ACL.
-
- * If the object doesn't exist, punt to the backend, which will do its
- own ACL check against backend-specific rules.
-
- I think the owner abstraction is worth it over just setting the ACL
- for get, store, and show.
-
- We also need to provide an interface to manage certain types of ACLs,
- in particular the krb5-group ACL scheme, at least in the short term
- until we standardize on using LDAP for all of those ACLs. We're
- probably going to continue to use krb5-group ACLs for the forseeable
- future in at least some cases, since we'll want to be able to do
- things when LDAP or AFS is down or we'll want a higher level of
- security than either can ensure.
-
- Flags
-
- locked -- No operations permitted except show
- unchanging -- Pull existing value from file store
-
- For backends like secure files, all values are unchanging implicitly,
- but I don't think we should represent this by setting flags on every
- instance of those backends; it's just confusing and doesn't provide
- more information.
-
- Expiration
-
- The database has a field to store an expiration date for every object.
- We can implement expiration methods in the backend to automatically
- delete some objects (or perhaps lock them) when they pass their
- expiration date, but a more useful method might be to provide warnings
- when objects are about to expire via warning methods for a backend
- that take the object name and the expiration date. This would be
- great for certificates, for instance.
-
- Keytab Backend
-
- As of the deployment of the wallet, we want to stop limiting nearly
- all keytabs from being forced to single DES keys. We're probably
- still going to have some keys for which only particular enctypes are
- permitted, however. This means keeping a side table of allowable
- enctypes per keytab name, where if there are no entries in the table
- we allow any enctype. We can pass a list of enctypes into kadmin when
- doing the principal creation or randomization, separated by spaces and
- enclosed in double quotes.
-
- When creating a new principal with addprinc, pass the -clearpolicy
- flag. Otherwise, the principal will be placed in the default policy
- and will be subject to password strength checking, and the initial
- password used with -randkey will fail.
-
- Whenever we generate a new keytab, we may need to push the key into
- K4. We could make the client send a flag saying whether they want
- synchronization with K4, but it's easier to just always do it (except
- maybe for some exception cases). The user doesn't have to ask the
- client program for the srvtab if they don't want it, and it doesn't
- hurt to create the KDC entry.
-
- This means that we need the gen_srvtab program from the old srvtab
- backend on the server end to push the key into K4. That program
- already has the capability to take a srvtab containing the DES key and
- push it into the K4 database. It could probably stand some cleanup
- and simplification for inclusion in the wallet source. I'm probably
- going to rename it to k4changekey or something similar in the process.
-
- Certificate Creation
-
- We probably want to handle all requested certificates from Comodo
- using this interface since we can use its expiration handling to do
- warnings and since that way users can re-download the certificate any
- time they want. Certificates are actually pairs of certificate and
- key, though, and we need to figure out what we're storing. There is
- the key, which we want to be able to store but we don't really do
- anything with (except ideally it's associated with a certificate),
- there's the CSR (which we could reuse for renewals although that
- doesn't get people to change their key), and there's the certificate
- itself (which is actually public data). Should there be some method
- for someone to request that their previous CSR be reused to request a
- new Comodo certificate? Maybe more work than needed.
-
- Cleanup of Old Entries
-
- We should periodically scan the wallet for host-based entries for hosts
- that aren't in NetDB. Rather than removing them immediately, wait
- until we haven't seen the host for several consecutive passes and then
- purge them. Send notification of the hosts that are being purged (and
- maybe of the hosts that will be purged soon if nothing happens).
-
-Client Issues
-
- Command-Line Options
-
- Some of the specific data types are going to need their own flags to
- operations like get. As an example, the keytab get operation will
- need an optional flag to specify the srvtab file to which to also
- write the key, and will need an optional flag specifying the time
- delta at which old kvnos should be pruned from the keytab. These
- flags need to be globally unique in the wallet client so that we can
- use a naive option parser, although at least for starters we'll
- probably require that all the options be given after the operation.
-
- Keytab Handling
-
- The server is going to hand the client a keytab that contains the
- current keys for the given service. Unless the keytab was marked as
- unchanging, these entries will have a higher kvno than any keys
- already in the keytab on the local system.
-
- The only interfaces to read keytabs require a file, so the client will
- need to save the keytab to a temporary file in order to extract
- individual keys. If there is no keytab on the local system in the
- path given to the wallet, this is simple; just write the keytab as
- returned by the server into the file.
-
- If the keytab already exists, we want the following behavior:
-
- * Add the keys from the new keytab.
-
- * Retain in the keytab keys for the previous kvno, but not for any
- older kvno older than the maximum lifetime of Kerberos tickets. So
- scan the keytab for keys with an older kvno and a timestamp older
- than one day (maybe make it a week just in case) and delete them.
- (Possibly make this configurable.)
-
- * Delete any keys in the keytab matching the current kvno, just to be
- sure we don't get any strange issues.
-
- We want to try to add the new keys first to minimize the outage window
- where service tickets handed out by the KDC aren't recognized by the
- host. Adding the keys does just append them to the end, but we
- probably have to clean out any keys with the same kvno first. That's
- a rare case, so I don't think we have to worry about the outage window
- there.
-
- Srvtab Handling
-
- If a srvtab was requested, we search for the key in the new keytab
- that has an enctype of ENCTYPE_DES_CBC_CRC and then write it out to a
- srvtab file. The MIT Kerberos library doesn't support writable
- srvtabs in the keytab backend, so we roll that ourselves.
-
- Look at src/lib/krb5/keytab/kt_srvtab.c in the MIT Kerberos source for
- the format of a srvtab file (see the end of that file).
-
- The kvno that we get from K5 may have no bearing on the kvno in K4.
- In order to get the K4 kvno, use the new key to obtain a K4 service
- ticket for ourselves and then read the kvno off that service ticket.
- There are other approaches, but the other approaches all require
- changes to the server side as well, whereas this is self-contained in
- the client and can be more easily dropped when we drop K4.