diff options
| -rw-r--r-- | doc/design-acl | 90 | ||||
| -rw-r--r-- | doc/design-api | 94 | ||||
| -rw-r--r-- | doc/design-schema | 112 | ||||
| -rw-r--r-- | doc/netdb-role-api | 32 | ||||
| -rw-r--r-- | doc/notes | 223 | 
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. | 
