How SVN deals with Server Certs

This is a description of a design for issue #1330, which is one of the
last "enhancements" for pre-1.0 subversion, scheduled for svn 0.31. 

The goal here is to essentially toss the existing server-certificate
validation code, and replace it with a totally new system that allows
permanent server-cert disk caching, just like a web browser.

-------------------------------------------------------------------

CURRENT SYSTEM
==============

* neon gets a server cert, signed by some CA.

* neon tries to verify it against trusted CAs that were loaded earlier
  (either the 'default' system CAs, or specific ones listed in the
  'servers' file.)

* if FAILURE, neon calls libsvn_ra_dav/session.c:server_ssl_callback():

    * this function receives the server cert and the reason for
      failure.   the reason can be:  {untrusted CA, expired, not yet
      valid, mismatched name.}

    * our implementation of the callback currently calls the svn auth
      system, looking for a specific "SERVER_SSL" kind of credential
      from the user.  This credential is a set of flags indicating
      what failures the user will allow.

         - the callback (implicitly) passes the failure information to
           our credential providers.

         - the first 'provider' checks the servers file for specifics.

         - if that fails, the 2nd provider prompts the user,
           describing the kind of failure(s).

    * the returned credential is compared to the actual set of
      failures, and the callback either returns "ok" or "not ok" to
      neon.

----------------------------------------------------------------------

NEW PROPOSED SYSTEM
===================

1.  Toss the old SERVER_SSL cred-kind, and both providers.

2.  Create a completely new cred-kind, with two fields:
 
         { 
           const char *server_cert;  /* stringified somehow */
           svn_boolean_t trust_forever;
         }  

3. Write a disk provider for the new cred-kind:

   - get_cred() takes a realmstring as input, as always.  The
     realmstring (key) is based on the certificate fingerprint.  It
     then searches the auth caching area in ~/.subversion/auth/, and
     returns a server cert credential, with trust_forever=TRUE.

   - save_cred() writes the server_cert into the auth caching area,
     with filename equal to the realmstring.  There's no point in
     saving the 'trust_forever' field in the disk cache.  :-)

4. Write a prompt provider for the new cred-kind:

   - "The server cert could not be trusted, due to problem XXXXX.
      The server cert is YYYYY.  [probably print a fingerprint]
      Trust (t)emporarily, (f)orever, (n)ot at all?"

   - this provider assumes the auth_baton hash contains XXXX and YYYY
     already.  (the caller places the info there.)

   - if XXXXX is 'unknown CA', then give the (f)orever or (t)emporary options.
     if XXXXX is 'invalid date' or 'host mismatch', *only* give
     (t)emporary option.

   - if the user answers (t) or (f), return a credential struct with
     YYYY as the first field, and trust_forever={true|false} set accordingly.

5. When to call the new providers:

   Put new logic into the main server_ssl_callback().

     * Put the server-cert into the auth_baton hash, so
       providers can see it, along with the error type.

     * call svn_auth_first_creds with properly constructed realmstring:

        * if we get a credential back from the disk provider, match it
          to the current fingerprint of the incoming server cert.  if
          they match, we have success. tell neon it's ok to proceed.

        * if we get nothing back, call svn_auth_next_creds(), which
          should invoke the prompt provider.  If a cred comes back, we
          know the fingerprint will match, instant success for neon.
          Also, if trust_forever=true, call svn_auth_save_creds(),
          which will cause the disk provider's save function to kick in.

6. Destroy all three of the ssl-ignore-* variables in
   ~/.subversion/servers.  We no longer need them.  For unknown-CA
   errors, we give users the option to cache the cert permanently.
   For invalid-date or host-mismatch errors, we give users the option
   to ignore temporarily.  The subversion client will behave the same
   way a web browser does, which is Good.

