On Thu, Mar 13, 2003 at 08:37:34AM +0100, Andreas Aardal Hanssen wrote:
> On Wed, 12 Mar 2003, Charlie Brady wrote:
> >On Wed, 12 Mar 2003, Andreas Aardal Hanssen wrote:
> >> Hi, Charlie.
> >> By "invoked similarly" I mean that it is spawned through a tcp wrapper. It
> >> will support privilege seperation. But I am not convinced that the
> >> authenticator should spawn the daemon.
> >These last two statements appear to be contradictory. I think that the
> >authenticator must spawn the daemon to provide the privilege separation.
> 
> Not at all. checkpassword spawns something, but it doesn't have to be the
> daemon. I see the advantages of using checkpassword with pipelining
> commands such as the smtp-after-imap stuff and so on. But this works today
> by throwing in programs in checkpassword's pipeline.

I believe the argument goes something like this for publicly accessible
services:

Definitions
 * Users - the individuals that receive direct benefits from a system
 * Stakeholders - the entities that are affected by the system
 * Implementors - the individuals that construct a system
 * Designers - the individuals that specify a system
 * Public - Anyone and everyone not included above.
 * Framing - that which separates and organizes 'data' enabling meaning
   to be derived from an otherwise unorganized stream of bits
 * bit the only truly indivisible 'unpackable' unit of data
Facts
 * Network protocols are byte oriented
 * Preauth code is executed for untrusted clients (by definition)
 * Framing of bit streams requires either fixed sized records or 'magic'
   information in the data stream (IP:Everything is n*8 bits long,
   Netstring: length encodings, mime data, base64, etc.)
 * All protocols requires framing
 * Framing requires parsing (from the simplest buf[index++] to parse
   bytes out of an array, to the monster of ASN.1)
 * Applications cannot provide more security than the underlying OS
 * A chain is only as strong as its weakest link Corollary: A chain
   of a single link is as weak/strong as all its links.
Assertions:
 * The smaller the codebase the easier to prove correctness.
 * Preauth bugs are more dangerous to services than postauth
   bugs.  (The latter requiring a valid user or a cracked account.
   While the former being ideal fodder for worms, ddoses, etc. )
 * Preauth->postauth transition must necessarily involve privileged
   operations in order to correctly construct a login-specific set
   of reduced privileges (chroot(), setuid(), etc.) for postauth
 * Communication with a privileged system must use as simple and
   foolproof of a protocol as possible (e.g. not ASN.1).
 * Encoding data requires parsing.
 * Parsing is hard.
(A quick Lemma:)
   L: Modern computer systems do not make sub-byte alignment errors.  (i.e.
      you will not ask for array[n] and get less than 8 bits from array[n-1]
      combined with less than 8 bits from array[n]
   L: The only (nearly) foolproof framing is the one used to extract the
      bytes buf[0] and buf[1].  I.e. bytes are effortless and foolproof
      to disambiguate from each other.
 * The level of rigor required in preauth and auth code implementation is
   set by the public and not the stakeholders, users, implementors or
   designers of a system
 * Public, well known and accepted standards are better than private,
   poorly known or accepted standards
Conclusions:
 * An encoding which has no possible overlap between its framing and data
   is better than one which relies upon shift registers or modal
   interpretation of data. (Because the former is presumably simpler to
   implement in code and therefore smaller and easier to prove correct.)
 * It would be desirable to have the most disastrously-exploitable
   part of the codebase be as provably correct as possible.
 * This code cannot run entirely with reduced privileges as it must
   necessarily (somehow) use escalated privileges to properly lose them.
 * Splitting the preauth and postauth code into two programs
   would necessarily produce two smaller programs (though not necessarily
   less overall code.)
 * This smaller preauth portion would be even easier to prove correct.
 * The level of rigor in postauth code need only be so high as the users,
   stakeholders, implementors and designers need it to be.
 * Application of same logic implies that there should be the smallest
   possible privileged program, with the smallest possible preauth
   program running in front of it.
 * Therefore, *given the assertions above*, the best possible arrangement
   of a publicly available service is:

    Preauth(smaller, more correct)
     -> Auth(smallest! most correct)
      -> Postauth(small, as correct as practicable)

I was going to just make a short point, but now I've wasted everyone's
time.  Regardless, I consider the argument to be both valid and sound
anyone is free to disagree with me, of course.

Oh, and yes I realize that my Facts list is really just an extension of
the assertions, but I felt justified in labeling them as such.

C=)

-- 
--------------------------------------------------------------------------
     Better the hard truth than the comforting fantasy. -- Carl Sagan
--------------------------------------------------------------------------
Caskey <caskey*technocage.com>       ///                   TechnoCage Inc.
--------------------------------------------------------------------------
 A presumption on your part does not constitute an obligation on my part.

Reply via email to