Password quality pluggable interface scope
mdw at umich.edu
Fri Aug 27 12:06:50 EDT 2010
> Date: Fri, 27 Aug 2010 11:19:38 EDT
> To: krbdev at MIT.EDU
> From: ghudson at MIT.EDU
> Subject: Password quality pluggable interface scope
> Before I even write up a project for the password quality interface, I
> want to discuss what it should be capable of.
> Currently, when you change your password, kadmind applies various
> 1. It rejects empty passwords. This is the only check if the
> principal has no associated policy.
> 2. It checks against the realm's configured dictionary file.
> 3. It checks against elements of the principal name.
> 4. If built with hesiod support (I kind of hope no one does this), it
> looks up the Hesiod passwd information for each principal component
> and checks against the GECOS information therein.
> 5. It enforces the minimum length and minimum number of character
> classes as determined by the password policy.
> 6. It checks password history against one or more recent keys, and
> stores a password history entry for the current key set.
> Russ's krb5-strength package contains a patch adding pluggability to
> krb5 1.4. It ties into the infrastructure for (2), so plugin modules
> using this interface only run if the principal has a password policy.
> Plugin modules get access to the realm's dictionary filename at init
> time, and the principal name (as a string) and new password at check
> time. Modules using this interface could perform checks in the style
> of (1)-(4) easily, but doing anything like (5)-(6) would be difficult
> and probably unsafe.
> I'm considering several options for the scope of the 1.9 password
> quality pluggable interface. In all cases, the interface will have
> init, check, and cleanup methods, where the purpose of init/cleanup is
> to allow the module to read in the realm's dictionary file and store
> it in memory.
> * The most basic: the module gets access to a krb5 context, the
> dictionary filename at init time, and the principal name (as a
> krb5_principal) and new password at check time. This has similar
> properties to Russ's interface, allowing checks in the style of
> (1)-(4). There are three sub-options here:
> - Only invoke check method if there's a password policy.
> - Invoke check method whether or not there's a policy.
> - Pass a boolean argument indicating whether there's a policy.
> * The module's check method could also be given access to the password
> policy structure. This makes the interface dependent on kadmin.h
> and kdb.h and thus inherently less stable, but allows checks in the
> style of (5).
> * The module's check method could be given access to the KDB entry and
> be allowed to change it. This allows checks in the style of (6),
> but provides the least isolation and safety between core code and
> Any current checks which fit within the scope of the interface would
> likely become built-in modules (which could then be disabled through
> plugin configuration directives, although that's not important since
> almost all of them can already be disabled in other ways). Checks
> which do not fit would be considered out of scope for the pluggable
> krbdev mailing list krbdev at mit.edu
I worked on something very like this a while back with Russ Allbery.
I took Russ's original framework (which was more stanford specific),
and extended it out to satisfy the requirements for the password quality
checking logic we had in place at the time for UMICH.EDU .
I also took the hesiod logic that was in the base code, and
moved into a plugin that fit with this framework. So that meant
I had 2 plugins - the hesiod one, and the 'umich policy' one.
The production folks since implemented different quality checking
logic, so now there is the "old" umich checking code, and the
"new" umich checking code, which is quite different.
For (5)-(6) - length & such. I put in some hooks here to interact with
the existing built-in logic. I don't recall anything that meant it
had to be "unsafe". I do recall thinking that the built-in parameter
logic was pretty limited and unduly specific. In my particular case,
I didn't care about the lengths (the logic I had estimated "overall"
entropy), but I did want to cause the history mechanism to reject the
old password (but not to store any additional depth).
Russ's logic only applied if a policy existed. The precessor umich
logic I was looking at applied in all cases and didn't care if there was
a policy record. I reworked the containing logic to apply even if there
was no policy, and passed the policy *name* (or a null ptr if no policy)
into the plugin in case the pw quality plugin wanted to do something
different depending on the policy.
I put a fair bit of effort into one other thing you don't list above:
configuring the plugins, and providing 'system' parameters for the plugins.
Examples of parameters one might want to configure:
list of dictionaries against which to check
pw quality plugin behavior based on policy name / existance.
actual entropy limits
password phase decomposition rules
For configuration, I specifically wanted to allow for:
/1/ keeping all plugin configuration inside of kdc.conf
and not needing separate files or logic to handle that.
/2/ loading the same plugin more than once with different configuration.
... so I wasn't very interested in "zero configuration" rules.
As I said before, I think the built-in parameters for policy records
is unduly restrictive. I'd like to see a much more extensible format here.
In particular, I'd like to see it be possible for a pw quality plugin
to provide a new parameter, and for kadmin to be able to set that parameter
on individual principals. That means there's going to have to be something
here that the cli can use to do stuff.
Somewhere I have design notes for this which I had sent Russ, and
I also have a patch (for 1.6.3) that implements this, plus the
"old" umich pw quality checking plugin.
More information about the krbdev