baby steps toward keytab
authorclunis <clunis@0d961d1b-a432-0410-8fea-cc29f225fe07>
Thu, 8 May 2003 02:35:05 +0000 (02:35 +0000)
committerclunis <clunis@0d961d1b-a432-0410-8fea-cc29f225fe07>
Thu, 8 May 2003 02:35:05 +0000 (02:35 +0000)
git-svn-id: https://modwaklog.svn.sourceforge.net/svnroot/modwaklog/trunk/modwaklog@10 0d961d1b-a432-0410-8fea-cc29f225fe07

VERSION
mod_waklog.c

diff --git a/VERSION b/VERSION
index d220514..c45feef 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-20030221
+20030507
index 3338e8d..768a945 100644 (file)
@@ -3,6 +3,7 @@
 #include "http_protocol.h"
 #include "http_log.h"
 #include "ap_config.h"
+#include <krb5.h>
 
 #include <sys/ioccom.h>
 #include <stropts.h>
@@ -10,6 +11,9 @@
 #include <kerberosIV/des.h>
 #include <afs/venus.h>
 
+#define KEYTAB_PATH "/usr/local/etc/kerbero/keytab.cosign"
+#define IN_TKT_SERVICE "krbtgt/UMICH.EDU"
+
 module waklog_module;
 
 struct ClearToken {
@@ -21,8 +25,9 @@ struct ClearToken {
 };
 
 typedef struct {
-    int        configured;
-    int        protect;
+    int                configured;
+    int                protect;
+    char       *keytab;
 } waklog_host_config;
 
 
@@ -34,6 +39,7 @@ waklog_create_dir_config( pool *p, char *path )
     cfg = (waklog_host_config *)ap_pcalloc( p, sizeof( waklog_host_config ));
     cfg->configured = 0;
     cfg->protect = 0;
+    cfg->keytab = NULL;
 
     return( cfg );
 }
@@ -47,6 +53,7 @@ waklog_create_server_config( pool *p, server_rec *s )
     cfg = (waklog_host_config *)ap_pcalloc( p, sizeof( waklog_host_config ));
     cfg->configured = 0;
     cfg->protect = 0;
+    cfg->keytab = NULL;
 
     return( cfg );
 }
@@ -81,6 +88,24 @@ set_waklog_protect( cmd_parms *params, void *mconfig, int flag )
 }
 
 
+    static const char *
+set_waklog_use_keytab( cmd_parms *params, void *mconfig, char *file  )
+{
+    waklog_host_config          *cfg;
+
+    if ( params->path == NULL ) {
+        cfg = (waklog_host_config *) ap_get_module_config(
+                params->server->module_config, &waklog_module );
+    } else {
+        cfg = (waklog_host_config *)mconfig;
+    }
+
+    cfg->keytab = file;
+    cfg->configured = 1;
+    return( NULL );
+}
+
+
     static void
 waklog_child_init( server_rec *s, pool *p )
 {
@@ -95,6 +120,10 @@ command_rec waklog_cmds[ ] =
     NULL, RSRC_CONF | ACCESS_CONF, FLAG,
     "enable waklog on a location or directory basis" },
 
+    { "WaklogUseKeytab", set_waklog_use_keytab,
+    NULL, RSRC_CONF, TAKE1,
+    "Use the supplied keytab file rather than the user's TGT" },
+
     { NULL }
 };
 
@@ -121,6 +150,118 @@ pioctl_cleanup( void *data )
 }
 
 
+    static int
+waklog_ktinit( request_rec *r )
+{
+    krb5_error_code            kerror;
+    krb5_context               kcontext;
+    krb5_principal             kprinc;
+    krb5_principal             sprinc;
+    krb5_get_init_creds_opt    kopts;
+    krb5_creds                 kcreds;
+    krb5_ccache                        kccache;
+    krb5_keytab                        keytab = 0;
+    char                       ktbuf[ MAX_KEYTAB_NAME_LEN + 1 ];
+    char                               krbpath [ 24 ];
+
+    if (( kerror = krb5_init_context( &kcontext ))) {
+       /* Authentication Required ( kerberos error ) */
+       ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+               (char *)error_message( kerror ));
+
+       return;
+    }
+
+    if (( kerror = krb5_parse_name( kcontext, r->connection->user,
+           &kprinc ))) {
+       ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+               (char *)error_message( kerror ));
+
+       return;
+    }
+
+    snprintf( krbpath, sizeof( krbpath ), "/ticket/waklog" );
+
+    if (( kerror = krb5_cc_resolve( kcontext, krbpath, &kccache )) != 0 ) {
+       ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+               (char *)error_message( kerror ));
+
+       return;
+    }
+
+    krb5_get_init_creds_opt_init( &kopts );
+    krb5_get_init_creds_opt_set_tkt_life( &kopts, 10*60*60 );
+    krb5_get_init_creds_opt_set_renew_life( &kopts, 0 );
+    krb5_get_init_creds_opt_set_forwardable( &kopts, 1 );
+    krb5_get_init_creds_opt_set_proxiable( &kopts, 0 );
+
+    if ( KEYTAB_PATH == '\0' ) {
+       if (( kerror = krb5_kt_default_name(
+               kcontext, ktbuf, MAX_KEYTAB_NAME_LEN )) != 0 ) {
+           ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+                   (char *)error_message( kerror ));
+
+           return;
+       }
+    } else {
+       if ( strlen( KEYTAB_PATH ) > MAX_KEYTAB_NAME_LEN ) {
+           ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+                   "server configuration error" );
+
+           return;
+       }
+       strcpy( ktbuf, KEYTAB_PATH );
+    }
+
+    if (( kerror = krb5_kt_resolve( kcontext, ktbuf, &keytab )) != 0 ) {
+       ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+               (char *)error_message( kerror ));
+       
+       return;
+    }
+
+    if (( kerror = krb5_sname_to_principal( kcontext, NULL, "cosign",
+           KRB5_NT_SRV_HST, &sprinc )) != 0 ) {
+       ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+               (char *)error_message( kerror ));
+       
+       return;
+    }
+
+    if (( kerror = krb5_get_init_creds_keytab( kcontext, &kcreds, 
+           kprinc, keytab, NULL, IN_TKT_SERVICE, &kopts ))) {
+
+       ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+               (char *)error_message( kerror ));
+
+       return;
+    }
+
+
+    (void)krb5_kt_close( kcontext, keytab );
+    krb5_free_principal( kcontext, sprinc );
+
+    if (( kerror = krb5_cc_initialize( kcontext, kccache, kprinc )) != 0 ) {
+       ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+               (char *)error_message( kerror ));
+       
+       return;
+    }
+
+    if (( kerror = krb5_cc_store_cred( kcontext, kccache, &kcreds )) != 0 ) {
+       ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+               (char *)error_message( kerror ));
+       
+       return;
+    }
+
+    krb5_free_cred_contents( kcontext, &kcreds );
+    krb5_free_principal( kcontext, kprinc );
+    krb5_cc_close( kcontext, kccache );
+    krb5_free_context( kcontext );
+}
+
+
     static int
 waklog_get_tokens( request_rec *r )
 {
@@ -147,6 +288,21 @@ waklog_get_tokens( request_rec *r )
         return( DECLINED );
     }
 
+    if ( cfg->keytab ) {
+       ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
+               "mod_waklog: keytab is configured: %s", cfg->keytab );
+
+       /* check for afs token? */
+
+       /* authenticate using keytab file */
+
+       /* 524 */
+
+       /* get afs token */
+
+       return OK;
+    }
+
     if (( rc = krb_get_cred( "afs", "", urealm, &cr )) != KSUCCESS ) {
        ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
                "mod_waklog: krb_get_cred: %s", krb_err_txt[ rc ] );
@@ -155,7 +311,7 @@ waklog_get_tokens( request_rec *r )
            ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server,
                    "mod_waklog: get_ad_tkt: %s", krb_err_txt[ rc ] );
 
-           /* user doesn't have tickets: use server's srvtab */
+           /* fail here or just let AFS deny permission? */
 
            return OK;
        }