Access control of files in afs with certificates
------------------------------------------------ 
[/afs/sipb/user/jdaniel/user-bdm/README]

I'd like to make this eventually available to users.  Please try it
out and let me know what you think and any suggestions you have.

I've rigged up a DBM in /afs/sipb/user/jdaniel/user-dbm/DBM and
configured it to have control over things in the sipb locker accessed
through https://webzephyr.mit.edu:8003/afs/sipb/ Apache is running
with tokens of rcmd.anxiety-closet which are automatically renewed
twice daily.  My test directory has been
https://webzephyr.mit.edu:8003/afs/sipb/user/jdaniel/www-secure/

I've given authuser write access to the database which I created
through the perl script /afs/sipb/user/jdaniel/user-dbm/dbm_create
(see comments at the beginning of the script for how to change the
database).  My eventual plan is to write a script which will create
the dbm file by looking up names and groups in moira.  (Suggestions on
how to best do this welcome.)

Once this is all set up the only thing a user would have to do is
grant the server read permission on the directory.  Then create a
.htaccess file specifying one of the following.  

require user foo bar
require group baz quux
require valid-user

(see http://webzephyr.mit.edu/htdocs/manual/mod/core.html#require for
full explanation)

problems: 

  Instead of giving a proper deny page netscape asks the user to retry
autth entry which is always wrong.

  Symlinks have to be set to not-followable otherwise someone can
change access restrictions on a file by making a symlink and giving
the new location different directives

other: 

Access can also be done through normal mod_auth: AuthUserFile and
AuthGroupFile

--------
FakeBasicAuth normally uses the full certificate as the user field:

/C=US/ST=Massachusetts/O=Massachusetts Institute of Technology/OU=Client CA v1/CN=Jeremy C Daniel/Email=jdaniel@MIT.EDU

But I've made a small change to the code (see below) to allow simple
usernames (i.e jdaniel) to work (much easier to deal with)

FakeAuth usses the dummy password "xxj31ZMTZzkVA" because of a "feature"
which forbids that field from being empty.

*** ssl_engine_kernel.c.orig	Thu May 20 06:41:44 1999
--- ssl_engine_kernel.c	Tue Jun  8 01:49:21 1999
***************
*** 951,958 ****
  {
      SSLSrvConfigRec *sc = mySrvConfig(r->server);
      SSLDirConfigRec *dc = myDirConfig(r);
!     char b1[MAX_STRING_LEN], b2[MAX_STRING_LEN];
!     char *clientdn;
  
      /*
       * Additionally forbid access (again)
--- 951,958 ----
  {
      SSLSrvConfigRec *sc = mySrvConfig(r->server);
      SSLDirConfigRec *dc = myDirConfig(r);
!     char b1[MAX_STRING_LEN], b2[MAX_STRING_LEN], clientemail[20];
!     char *clientdn, *p, *p2;
  
      /*
       * Additionally forbid access (again)
***************
*** 975,980 ****
--- 975,986 ----
          return DECLINED;
      if ((clientdn = (char *)ap_ctx_get(r->connection->client->ctx, "ssl::client::dn")) == NULL)
          return DECLINED;
+     if (((p = strstr(clientdn, "/Email=")) == NULL) ||
+ 	((p2 = strchr(p, '@')) == NULL))
+       return DECLINED;
+     p+=7;
+     strcpy(clientemail,"");
+     strncat(clientemail, p, p2-p);
  
      /*
       * Fake a password - which one would be immaterial, as, it seems, an empty
***************
*** 987,993 ****
       * adding the string "xxj31ZMTZzkVA" as the password in the user file.
       * This is just the crypted variant of the word "password" ;-)
       */
!     ap_snprintf(b1, sizeof(b1), "%s:password", clientdn);
      ssl_util_uuencode(b2, b1, FALSE);
      ap_snprintf(b1, sizeof(b1), "Basic %s", b2);
      ap_table_set(r->headers_in, "Authorization", b1);
--- 993,1000 ----
       * adding the string "xxj31ZMTZzkVA" as the password in the user file.
       * This is just the crypted variant of the word "password" ;-)
       */
!     /*    ap_snprintf(b1, sizeof(b1), "%s:password", clientdn);*/
!     ap_snprintf(b1, sizeof(b1), "%s:password", clientemail);
      ssl_util_uuencode(b2, b1, FALSE);
      ap_snprintf(b1, sizeof(b1), "Basic %s", b2);
      ap_table_set(r->headers_in, "Authorization", b1);