| 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. |
| |