two more debugging messages
[mod_auth_kerb.git] / src / mod_auth_kerb.c
index e4d1dfc..9a6f4db 100644 (file)
@@ -46,7 +46,7 @@
 
 #include "config.h"
 
-#define MODAUTHKERB_VERSION "5.0-rc4"
+#define MODAUTHKERB_VERSION "5.0-rc5"
 
 #include <httpd.h>
 #include <http_config.h>
@@ -120,6 +120,7 @@ typedef struct {
        int krb_verify_kdc;
        char *krb_service_name;
        int krb_authoritative;
+       int krb_delegate_basic;
 #ifdef KRB5
        char *krb_5_keytab;
        int krb_method_gssapi;
@@ -167,7 +168,10 @@ static const command_rec kerb_auth_cmds[] = {
      TAKE1, "Service name to be used by Apache for authentication."),
 
    command("KrbAuthoritative", ap_set_flag_slot, krb_authoritative,
-     FLAG, "Set to 'off' to allow access control to be passed along to lower modules if the UserID is not known to this module."),
+     FLAG, "Set to 'off' to allow access control to be passed along to lower modules iff the UserID is not known to this module."),
+
+   command("KrbDelegateBasic", ap_set_flag_slot, krb_delegate_basic,
+     FLAG, "Always offer Basic authentication regardless of KrbMethodK5Pass and pass on authentication to lower modules if Basic headers arrive."),
 
 #ifdef KRB5
    command("Krb5Keytab", ap_set_file_slot, krb_5_keytab,
@@ -198,13 +202,13 @@ static const command_rec kerb_auth_cmds[] = {
 /* This is our replacement krb5_rc_store function */
 static krb5_error_code
 mod_auth_kerb_rc_store(krb5_context context, krb5_rcache rcache,
-                        krb5_donot_replay *donot_replay)
+                       krb5_donot_replay_internal *donot_replay)
 {
    return 0;
 }
 
 /* And this is the operations vector for our replay cache */
-const krb5_rc_ops mod_auth_kerb_rc_ops = {
+const krb5_rc_ops_internal mod_auth_kerb_rc_ops = {
   0,
   "dfl",
   krb5_rc_dfl_init,
@@ -231,6 +235,7 @@ static void *kerb_dir_create_config(MK_POOL *p, char *d)
         ((kerb_auth_config *)rec)->krb_verify_kdc = 1;
        ((kerb_auth_config *)rec)->krb_service_name = "HTTP";
        ((kerb_auth_config *)rec)->krb_authoritative = 1;
+       ((kerb_auth_config *)rec)->krb_delegate_basic = 0;
 #ifdef KRB5
        ((kerb_auth_config *)rec)->krb_method_k5pass = 1;
        ((kerb_auth_config *)rec)->krb_method_gssapi = 1;
@@ -595,7 +600,7 @@ verify_krb5_user(request_rec *r, krb5_context context, krb5_principal principal,
    if (ret) {
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r, 
                 "generating new memory ccache failed: %s",
-                krb5_get_err_text(kcontext, ret));
+                krb5_get_err_text(context, ret));
       goto end;
    }
 
@@ -995,6 +1000,8 @@ get_gss_creds(request_rec *r,
                 "gss_import_name() failed"));
       return HTTP_INTERNAL_SERVER_ERROR;
    }
+
+   log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Acquiring creds for %s", buf);
    
    major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
                                   GSS_C_NO_OID_SET, GSS_C_ACCEPT,
@@ -1020,7 +1027,8 @@ get_gss_creds(request_rec *r,
    {
       krb5_gss_cred_id_t gss_creds = (krb5_gss_cred_id_t) *server_creds;
 
-      if (gss_creds && gss_creds->rcache && gss_creds->ops->type &&
+      if (gss_creds && gss_creds->rcache && gss_creds->rcache->ops &&
+         gss_creds->rcache->ops->type &&  
          memcmp(gss_creds->rcache->ops->type, "dfl", 3) == 0)
           /* Override the rcache operations */
         gss_creds->rcache->ops = &mod_auth_kerb_rc_ops;
@@ -1121,6 +1129,11 @@ authenticate_user_gss(request_rec *r, kerb_auth_config *conf,
   accept_sec_token = (cmp_gss_type(&input_token, &spnego_oid) == 0) ?
                        gss_accept_sec_context_spnego : gss_accept_sec_context;
 
+  log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Verifying client data using %s",
+            (accept_sec_token == gss_accept_sec_context)
+              ? "KRB5 GSS-API"
+              : "SPNEGO GSS-API");
+
   major_status = accept_sec_token(&minor_status,
                                  &context,
                                  server_creds,
@@ -1148,6 +1161,9 @@ authenticate_user_gss(request_rec *r, kerb_auth_config *conf,
      ap_base64encode(token, output_token.value, output_token.length);
      token[len] = '\0';
      *negotiate_ret_value = token;
+     log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+               "Verification suceeded, GSS-API token of length %d bytes will be sent back",
+               output_token.length);
      gss_release_buffer(&minor_status2, &output_token);
   }
 
@@ -1238,14 +1254,15 @@ set_kerb_auth_headers(request_rec *r, const kerb_auth_config *conf,
    /* get the user realm specified in .htaccess */
    auth_name = ap_auth_name(r);
 
-   /* XXX should the WWW-Authenticate header be cleared first? */
+   /* XXX should the WWW-Authenticate header be cleared first?
+    * apache in the proxy mode should retain client's authN headers? */
 #ifdef KRB5
    if (negotiate_ret_value != NULL && conf->krb_method_gssapi) {
       negoauth_param = (*negotiate_ret_value == '\0') ? "Negotiate" :
                  ap_pstrcat(r->pool, "Negotiate ", negotiate_ret_value, NULL);
       ap_table_add(r->err_headers_out, header_name, negoauth_param);
    }
-   if (use_krb5pwd && conf->krb_method_k5pass) {
+   if ((use_krb5pwd && conf->krb_method_k5pass) || conf->krb_delegate_basic) {
       ap_table_add(r->err_headers_out, header_name,
                   ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
       set_basic = 1;
@@ -1253,7 +1270,8 @@ set_kerb_auth_headers(request_rec *r, const kerb_auth_config *conf,
 #endif
 
 #ifdef KRB4
-   if (use_krb4 && conf->krb_method_k4pass && !set_basic)
+   if (!set_basic && 
+       ((use_krb4 && conf->krb_method_k4pass) || conf->krb_delegate_basic))
       ap_table_add(r->err_headers_out, header_name,
                  ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
 #endif
@@ -1285,17 +1303,27 @@ int kerb_authenticate_user(request_rec *r)
       return DECLINED;
 
    /* get what the user sent us in the HTTP header */
-   auth_line = MK_TABLE_GET(r->headers_in, "Authorization");
+   auth_line = MK_TABLE_GET(r->headers_in, (r->proxyreq == PROXYREQ_PROXY)
+                                           ? "Proxy-Authorization"
+                                           : "Authorization");
    if (!auth_line) {
-       auth_line = MK_TABLE_GET(r->headers_in, "Proxy-Authorization");
-       if (!auth_line) {
-               set_kerb_auth_headers(r, conf, use_krb4, use_krb5,
-                                    (use_krb5) ? "\0" : NULL);
-               return HTTP_UNAUTHORIZED;
-       }
+      set_kerb_auth_headers(r, conf, use_krb4, use_krb5, 
+                           (use_krb5) ? "\0" : NULL);
+      return HTTP_UNAUTHORIZED;
    }
    auth_type = ap_getword_white(r->pool, &auth_line);
 
+   /* If we are delegating Basic to other modules, DECLINE the request */
+   if (conf->krb_delegate_basic &&
+#ifdef KRB5
+       !conf->krb_method_k5pass &&
+#endif
+#ifdef KRB4
+       !conf->krb_method_k4pass &&
+#endif
+       (strcasecmp(auth_type, "Basic") == 0))
+       return DECLINED;
+
    if (already_succeeded(r))
       return last_return;
 
@@ -1351,6 +1379,12 @@ module MODULE_VAR_EXPORT auth_kerb_module = {
        NULL,                           /*      process initialization        */
        NULL,                           /*      process exit/cleanup          */
        NULL                            /* [ 1] post read_request handling    */
+#ifdef EAPI
+       ,NULL,                          /* EAPI: add_module                   */
+       NULL,                           /* EAPI: remove_module                */
+       NULL,                           /* EAPI: rewrite_command              */
+       NULL                            /* EAPI: new_connection               */
+#endif
 };
 #else
 static int