Search Mailing List Archives


Limit search to: Subject & Body Subject Author
Sort by: Reverse Sort
Limit to: All This Week Last Week This Month Last Month
Select Date Range     through    

Determining need for authentication from Application

niklas | brueckenschlaeger niklas at brueckenschlaeger.de
Thu Jan 20 17:23:23 PST 2011




On Thu, 2011-01-20 at 16:51 -0800, Russ Allbery wrote:
> (...)
> Just:
> 
>     conf->web_auth_optional = oconf->web_auth_optional_ex ?
>         oconf->web_auth_optional : bconf->web_auth_optional;
>     conf->web_auth_optional_ex = oconf->web_auth_optional_ex || 
>         bconf->web_auth_optional_ex;
> 
> should do it, I think.
> 

Great, that did the trick!

One more change I had to make though: If just returning DECLINED, apache
would say:
  "configuration error:  couldn't check user.  Check your authn
provider!: /not-so-private"

That is because I had to specify "Require valid-user" in my vhost,
otherwise the webauth code wouldn't even be run. So instead of returning
DECLINED I just set the rc->at.subject to "<anonymous>". That made it
work. However, strangely the REMOTE_USER and WEBAUTH_USER end up being
"" instead of "<anonymous>" later. But that doesn't matter. This was my
required behaviour anyway.

Thank you very much for your help!
It is very nice working with WebAuth code. Attached a patch with my
changes in case s/o is interested (sorry for the massive
trailing-whitespace removal - emacs did that automatically).

 -- niklas
-------------- next part --------------
commit b44d88d1fde72a70ef3186239b6f6127f2d0da59
Author: niklas <niklas at brueckenschlaeger.de>
Date:   Fri Jan 21 02:20:36 2011 +0100

    Added flag WebAuthOptional to dir-config. Use together with Require valid-user and everyone will get in, but already authenticated users will still be seen by the application code.

diff --git a/modules/webauth/mod_webauth.c b/modules/webauth/mod_webauth.c
index d1c49dc..79f8835 100644
--- a/modules/webauth/mod_webauth.c
+++ b/modules/webauth/mod_webauth.c
@@ -140,7 +140,7 @@ find_cookie(MWA_REQ_CTXT *rc, const char *name)
     int len;
 
     c = apr_table_get(rc->r->headers_in, "Cookie");
-    if (c == NULL) 
+    if (c == NULL)
         return NULL;
 
     len = strlen(name);
@@ -187,7 +187,7 @@ nuke_cookie(MWA_REQ_CTXT *rc, const char *name, int if_set)
                           is_https(rc->r) ? "secure" : "");
     if (rc->sconf->debug)
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
-                     "mod_webauth: nuking cookie(%s): (%s)", 
+                     "mod_webauth: nuking cookie(%s): (%s)",
                      name, cookie);
     apr_table_addn(rc->r->err_headers_out, "Set-Cookie", cookie);
 }
@@ -217,13 +217,13 @@ set_pending_cookie_cb(void *rec, const char *key, const char *value)
  * function converts the notes to headers and is called during fixups.
  */
 static void
-set_pending_cookies(MWA_REQ_CTXT *rc) 
+set_pending_cookies(MWA_REQ_CTXT *rc)
 {
     apr_table_t *t;
 
     if (rc->r->main != NULL)
         t = rc->r->main->notes;
-    else 
+    else
         t = rc->r->notes;
 
     /*
@@ -242,7 +242,7 @@ set_pending_cookies(MWA_REQ_CTXT *rc)
 static void
 fixup_setcookie(MWA_REQ_CTXT *rc, const char *name, const char *value)
 {
-    mwa_setn_note(rc->r, 
+    mwa_setn_note(rc->r,
                   "mod_webauth_COOKIE_",
                   name,
                   "%s=%s; path=/;%s",
@@ -265,7 +265,7 @@ mwa_setenv(MWA_REQ_CTXT *rc, const char *name, const char *value)
                      name, value);
     apr_table_setn(rc->r->subprocess_env, name, value);
     if (rc->dconf->var_prefix != NULL) {
-        name = apr_pstrcat(rc->r->pool, 
+        name = apr_pstrcat(rc->r->pool,
                           rc->dconf->var_prefix, name, NULL);
         apr_table_setn(rc->r->subprocess_env, name, value);
     }
@@ -306,8 +306,8 @@ nuke_all_webauth_cookies(MWA_REQ_CTXT *rc)
 
 
 /* FIXME: should we pass some query paramters along with
- *        failure_redirect to indicate what failure occured? 
- *        
+ *        failure_redirect to indicate what failure occured?
+ *
  */
 static int
 failure_redirect(MWA_REQ_CTXT *rc)
@@ -333,7 +333,7 @@ failure_redirect(MWA_REQ_CTXT *rc)
     }
 
     apr_table_setn(rc->r->err_headers_out, "Location", redirect_url);
-                
+
     if (rc->sconf->debug)
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
                      "mod_webauth: %s: redirect(%s)", mwa_func, redirect_url);
@@ -365,7 +365,7 @@ login_canceled_redirect(MWA_REQ_CTXT *rc)
     }
 
     apr_table_setn(rc->r->err_headers_out, "Location", redirect_url);
-                
+
     if (rc->sconf->debug)
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
                      "mod_webauth: %s: redirect(%s)", mwa_func, redirect_url);
@@ -375,7 +375,7 @@ login_canceled_redirect(MWA_REQ_CTXT *rc)
 }
 
 
-static int 
+static int
 die(const char *message, server_rec *s)
 {
     if (s) {
@@ -387,18 +387,18 @@ die(const char *message, server_rec *s)
 }
 
 
-static void 
+static void
 die_directive(server_rec *s, const char *dir, apr_pool_t *ptemp)
 {
     char *msg;
 
     if (s->is_virtual) {
-        msg = apr_psprintf(ptemp, 
-                          "directive %s must be set for virtual host %s:%d", 
+        msg = apr_psprintf(ptemp,
+                          "directive %s must be set for virtual host %s:%d",
                           dir, s->defn_name, s->defn_line_number);
     } else {
-        msg = apr_psprintf(ptemp, 
-                          "directive %s must be set in main config", 
+        msg = apr_psprintf(ptemp,
+                          "directive %s must be set in main config",
                           dir);
     }
     die(msg, s);
@@ -427,7 +427,7 @@ mod_webauth_cleanup(void *data)
 
         if (tconf->ring && tconf->free_ring) {
             if (sconf->debug) {
-                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                              "mod_webauth: cleanup ring: %s",
                              tconf->keyring_path);
             }
@@ -443,7 +443,7 @@ mod_webauth_cleanup(void *data)
             apr_pool_destroy(tconf->service_token->pool);
             tconf->service_token = NULL;
             if (sconf->debug) {
-                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                              "mod_webauth: cleanup service_token: %s",
                              tconf->st_cache_path);
             }
@@ -458,7 +458,7 @@ mod_webauth_cleanup(void *data)
  * also cache keyring
  */
 static void
-init_sconf(server_rec *s, MWA_SCONF *bconf, 
+init_sconf(server_rec *s, MWA_SCONF *bconf,
            apr_pool_t *pconf, apr_pool_t *ptemp)
 {
     MWA_SCONF *sconf;
@@ -504,7 +504,7 @@ init_sconf(server_rec *s, MWA_SCONF *bconf,
     if (unlink(sconf->st_cache_path) == -1) {
         if (errno != ENOENT) {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
-                         "mod_webauth: init_sconf: unlink(%s) errno(%d)", 
+                         "mod_webauth: init_sconf: unlink(%s) errno(%d)",
                          sconf->st_cache_path, errno);
         }
     }
@@ -513,7 +513,7 @@ init_sconf(server_rec *s, MWA_SCONF *bconf,
     /* if'd out, since we are now unlinking the service token cache */
     /* load service token cache. must be done after we init keyring  */
     (void)mwa_get_service_token(s, sconf, ptemp, 1);
-#endif 
+#endif
 
 }
 
@@ -538,7 +538,7 @@ mod_webauth_init(apr_pool_t *pconf, apr_pool_t *plog UNUSED,
     if (sconf->debug)
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_webauth: initializing");
 
-    apr_pool_cleanup_register(pconf, s, 
+    apr_pool_cleanup_register(pconf, s,
                               mod_webauth_cleanup,
                               apr_pool_cleanup_null);
 
@@ -549,13 +549,13 @@ mod_webauth_init(apr_pool_t *pconf, apr_pool_t *plog UNUSED,
     version = apr_pstrcat(ptemp, "WebAuth/", webauth_info_version(), NULL);
     ap_add_version_component(pconf, version);
 
-    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, 
+    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
                  "mod_webauth: initialized (%s)%s",
                  webauth_info_version(),
                  sconf->debug ?
-                 apr_pstrcat(ptemp," (", webauth_info_build(), ")", NULL) : 
+                 apr_pstrcat(ptemp," (", webauth_info_build(), ")", NULL) :
                  "");
- 
+
     return OK;
 }
 
@@ -637,27 +637,27 @@ config_server_merge(apr_pool_t *p, void *basev, void *overv)
 
     conf->debug = oconf->debug_ex ? oconf->debug : bconf->debug;
 
-    conf->require_ssl = oconf->require_ssl_ex ? 
+    conf->require_ssl = oconf->require_ssl_ex ?
         oconf->require_ssl : bconf->require_ssl;
 
-    conf->ssl_redirect = oconf->ssl_redirect_ex ? 
+    conf->ssl_redirect = oconf->ssl_redirect_ex ?
         oconf->ssl_redirect : bconf->ssl_redirect;
 
     conf->extra_redirect = oconf->extra_redirect_ex ?
         oconf->extra_redirect : bconf->extra_redirect;
-    conf->extra_redirect_ex = oconf->extra_redirect_ex || 
+    conf->extra_redirect_ex = oconf->extra_redirect_ex ||
         bconf->extra_redirect_ex;
 
-    conf->webkdc_cert_check = oconf->webkdc_cert_check_ex ? 
+    conf->webkdc_cert_check = oconf->webkdc_cert_check_ex ?
         oconf->webkdc_cert_check : bconf->webkdc_cert_check;
 
-    conf->keyring_auto_update = oconf->keyring_auto_update_ex ? 
+    conf->keyring_auto_update = oconf->keyring_auto_update_ex ?
         oconf->keyring_auto_update : bconf->keyring_auto_update;
 
-    conf->keyring_key_lifetime = oconf->keyring_key_lifetime_ex ? 
+    conf->keyring_key_lifetime = oconf->keyring_key_lifetime_ex ?
         oconf->keyring_key_lifetime : bconf->keyring_key_lifetime;
 
-    conf->ssl_redirect_port = oconf->ssl_redirect_port_ex ? 
+    conf->ssl_redirect_port = oconf->ssl_redirect_port_ex ?
         oconf->ssl_redirect_port : bconf->ssl_redirect_port;
 
     MERGE_PTR(webkdc_url);
@@ -667,7 +667,7 @@ config_server_merge(apr_pool_t *p, void *basev, void *overv)
     MERGE_PTR(auth_type);
     MERGE_PTR(keyring_path);
     MERGE_PTR(keytab_path);
-    /* always use oconf's keytab_principal if 
+    /* always use oconf's keytab_principal if
        oconf's keytab_path is specified */
     if (oconf->keytab_path)
         conf->keytab_principal = oconf->keytab_principal;
@@ -688,32 +688,37 @@ config_dir_merge(apr_pool_t *p, void *basev, void *overv)
     bconf = (MWA_DCONF*) basev;
     oconf = (MWA_DCONF*) overv;
 
-    conf->force_login = oconf->force_login_ex ? 
+    conf->force_login = oconf->force_login_ex ?
         oconf->force_login : bconf->force_login;
     conf->force_login_ex = oconf->force_login_ex || bconf->force_login_ex;
 
-    conf->use_creds = oconf->use_creds_ex ? 
+    conf->use_creds = oconf->use_creds_ex ?
         oconf->use_creds : bconf->use_creds;
     conf->use_creds_ex = oconf->use_creds_ex || bconf->use_creds_ex;
 
-    conf->do_logout = oconf->do_logout_ex ? 
+    conf->do_logout = oconf->do_logout_ex ?
         oconf->do_logout : bconf->do_logout;
     conf->do_logout_ex = oconf->do_logout_ex || bconf->do_logout_ex;
 
     conf->extra_redirect = oconf->extra_redirect_ex ?
         oconf->extra_redirect : bconf->extra_redirect;
-    conf->extra_redirect_ex = oconf->extra_redirect_ex || 
+    conf->extra_redirect_ex = oconf->extra_redirect_ex ||
         bconf->extra_redirect_ex;
 
     conf->ssl_return = oconf->ssl_return_ex ?
         oconf->ssl_return : bconf->ssl_return;
-    conf->ssl_return_ex = oconf->ssl_return_ex || 
+    conf->ssl_return_ex = oconf->ssl_return_ex ||
         bconf->ssl_return_ex;
 
-    conf->dont_cache = oconf->dont_cache_ex ? 
+    conf->dont_cache = oconf->dont_cache_ex ?
         oconf->dont_cache : bconf->dont_cache;
     conf->dont_cache_ex = oconf->dont_cache_ex || bconf->dont_cache_ex;
 
+    conf->web_auth_optional = oconf->web_auth_optional_ex ?
+      oconf->web_auth_optional : bconf->web_auth_optional;
+    conf->web_auth_optional_ex = oconf->web_auth_optional_ex ||
+      bconf->web_auth_optional_ex;
+
     MERGE_INT(app_token_lifetime);
     MERGE_INT(inactive_expire);
     MERGE_INT(last_use_update_interval);
@@ -761,7 +766,7 @@ status_check_access(const char *path, apr_int32_t flag, request_rec *r)
 
 
 static void
-dt_str(const char *n, const char *v, request_rec *r) 
+dt_str(const char *n, const char *v, request_rec *r)
 {
     ap_rprintf(r, "<dt><strong>%s:</strong> "
                /*"<tt>%s</tt></dt>\n", n, v);*/
@@ -770,7 +775,7 @@ dt_str(const char *n, const char *v, request_rec *r)
 
 
 static void
-dd_dir_str(const char *n, const char *v, request_rec *r) 
+dd_dir_str(const char *n, const char *v, request_rec *r)
 {
     if (v == NULL) {
         return;
@@ -784,7 +789,7 @@ dd_dir_str(const char *n, const char *v, request_rec *r)
 
 
 static void
-dd_dir_int(const char *n, int v, request_rec *r) 
+dd_dir_int(const char *n, int v, request_rec *r)
 {
     ap_rprintf(r, "<dd><tt>%s %d</tt></dd>",
                ap_escape_html(r->pool, n),
@@ -793,7 +798,7 @@ dd_dir_int(const char *n, int v, request_rec *r)
 
 
 static void
-dd_dir_time(const char *n, time_t t, request_rec *r) 
+dd_dir_time(const char *n, time_t t, request_rec *r)
 {
     char buffer[APR_CTIME_LEN+1];
 
@@ -803,7 +808,7 @@ dd_dir_time(const char *n, time_t t, request_rec *r)
 
 
 /* The content handler */
-static int 
+static int
 handler_hook(request_rec *r)
 {
     MWA_DCONF *dconf;
@@ -816,7 +821,7 @@ handler_hook(request_rec *r)
 
     r->allowed |= (AP_METHOD_BIT << M_GET);
     if (r->method_number != M_GET)
-	return DECLINED;
+        return DECLINED;
 
     dconf = (MWA_DCONF*)ap_get_module_config(r->per_dir_config,
                                                 &webauth_module);
@@ -824,7 +829,7 @@ handler_hook(request_rec *r)
     sconf = (MWA_SCONF*)ap_get_module_config(r->server->module_config,
                                                 &webauth_module);
 
-    r->content_type = "text/html";      
+    r->content_type = "text/html";
 
     if (!sconf->debug) {
         ap_rputs(DOCTYPE_HTML_3_2
@@ -837,21 +842,21 @@ handler_hook(request_rec *r)
     }
 
     ap_rputs(DOCTYPE_HTML_3_2
-	     "<html><head><title>mod_webauth status</title></head>\n", r);
+             "<html><head><title>mod_webauth status</title></head>\n", r);
     ap_rputs("<body><h1 align=\"center\">mod_webauth status</h1>\n", r);
     ap_rputs("<hr/>", r);
 
     ap_rputs("<dl>", r);
     dt_str("Server Version", ap_get_server_version(), r);
     dt_str("Server Built",   ap_get_server_built(), r);
-    dt_str("Hostname/port", 
+    dt_str("Hostname/port",
            apr_psprintf(r->pool, "%s:%u",
                         ap_get_server_name(r), ap_get_server_port(r)), r);
     ap_rputs("</dl>", r);
     ap_rputs("<hr/>", r);
 
     ap_rputs("<dl>", r);
-    
+
     dt_str("WebAuth Info Version", webauth_info_version(), r);
     dt_str("WebAuth Info Build", webauth_info_build(), r);
 
@@ -863,13 +868,13 @@ handler_hook(request_rec *r)
     dd_dir_str("WebAuthDebug", sconf->debug ? "on" : "off", r);
     dd_dir_str("WebAuthKeyRing", sconf->keyring_path, r);
     dd_dir_str("WebAuthKeyRingAutoUpdate", sconf->keyring_auto_update ? "on" : "off", r);
-    dd_dir_str("WebAuthKeyRingKeyLifetime", 
+    dd_dir_str("WebAuthKeyRingKeyLifetime",
                apr_psprintf(r->pool, "%ds", sconf->keyring_key_lifetime), r);
     if (sconf->keytab_principal == NULL) {
         dd_dir_str("WebAuthKeytab", sconf->keytab_path, r);
     } else {
         dd_dir_str("WebAuthKeytab",
-                   apr_psprintf(r->pool, "%s %s", 
+                   apr_psprintf(r->pool, "%s %s",
                                 sconf->keytab_path,
                                 sconf->keytab_principal), r);
     }
@@ -878,14 +883,14 @@ handler_hook(request_rec *r)
     dd_dir_str("WebAuthSubjectAuthType", sconf->subject_auth_type, r);
     dd_dir_str("WebAuthSSLRedirect", sconf->ssl_redirect ? "on" : "off", r);
     if (sconf->ssl_redirect_port != 0) {
-        dd_dir_str("WebAuthSSLRedirectPort", 
+        dd_dir_str("WebAuthSSLRedirectPort",
                    apr_psprintf(r->pool, "%d", sconf->ssl_redirect_port), r);
     }
-    dd_dir_str("WebAuthTokenMaxTTL", 
+    dd_dir_str("WebAuthTokenMaxTTL",
                apr_psprintf(r->pool, "%ds", sconf->token_max_ttl), r);
     dd_dir_str("WebAuthWebKdcPrincipal", sconf->webkdc_principal, r);
     dd_dir_str("WebAuthWebKdcSSLCertFile", sconf->webkdc_cert_file, r);
-    dd_dir_str("WebAuthWebKdcSSLCertCheck", 
+    dd_dir_str("WebAuthWebKdcSSLCertCheck",
                sconf->webkdc_cert_check ? "on" : "off", r);
     dd_dir_str("WebAuthWebKdcURL", sconf->webkdc_url, r);
 
@@ -893,7 +898,7 @@ handler_hook(request_rec *r)
     ap_rputs("<hr/>", r);
 
     ap_rputs("<dl>", r);
-    dt_str("Keyring read check", 
+    dt_str("Keyring read check",
            status_check_access(sconf->keyring_path, APR_READ, r), r);
     ap_rputs("<dt><strong>Keyring info:</strong></dt>\n", r);
 
@@ -919,7 +924,7 @@ handler_hook(request_rec *r)
 
     ap_rputs("<dl>", r);
 
-    dt_str("Keytab read check", 
+    dt_str("Keytab read check",
            status_check_access(sconf->keytab_path, APR_READ, r), r);
     ap_rputs("</dl>", r);
     ap_rputs("<hr/>", r);
@@ -928,11 +933,11 @@ handler_hook(request_rec *r)
 
     st = mwa_get_service_token(r->server, sconf, r->pool, 0);
 
-    dt_str("Service Token Cache read/write check", 
-           status_check_access(sconf->st_cache_path, 
+    dt_str("Service Token Cache read/write check",
+           status_check_access(sconf->st_cache_path,
                                APR_READ|APR_WRITE|APR_CREATE, r), r);
     ap_rputs("<dt><strong>Service Token info:</strong></dt>\n", r);
-    
+
     if (st == NULL) {
         ap_rputs("<dd>"
                  "service_token is NULL. This usually indicates a permissions "
@@ -965,22 +970,22 @@ app_cookie_name(void)
 
 
 /*
- * given the proxy_type return the cookie name to use 
+ * given the proxy_type return the cookie name to use
  */
 static char *
-proxy_cookie_name(const char *proxy_type, MWA_REQ_CTXT *rc) 
+proxy_cookie_name(const char *proxy_type, MWA_REQ_CTXT *rc)
 {
     return apr_pstrcat(rc->r->pool, "webauth_pt_", proxy_type, NULL);
 }
 
 
 /*
- * given the proxy_type return the cookie name to use 
+ * given the proxy_type return the cookie name to use
  */
 static char *
-cred_cookie_name(const char *cred_type, 
+cred_cookie_name(const char *cred_type,
                  const char *cred_server,
-                 MWA_REQ_CTXT *rc) 
+                 MWA_REQ_CTXT *rc)
 {
     char *p;
     /* if cred_server has an '=' in it we need to change it to '-'
@@ -1006,10 +1011,10 @@ cred_cookie_name(const char *cred_type,
  */
 static int
 make_proxy_cookie(const char *proxy_type,
-                  const char *subject, 
+                  const char *subject,
                   void *wpt,
                   size_t wpt_len,
-                  time_t expiration_time, 
+                  time_t expiration_time,
                   MWA_REQ_CTXT *rc)
 {
     WEBAUTH_ATTR_LIST *alist;
@@ -1024,7 +1029,7 @@ make_proxy_cookie(const char *proxy_type,
     alist = webauth_attr_list_new(10);
     if (alist == NULL) {
         ap_log_error(APLOG_MARK, APLOG_EMERG, 0, rc->r->server,
-                     "mod_webauth: %s: webauth_attr_list_new failed", 
+                     "mod_webauth: %s: webauth_attr_list_new failed",
                      mwa_func);
         return 0;
     }
@@ -1037,7 +1042,7 @@ make_proxy_cookie(const char *proxy_type,
     SET_WEBKDC_TOKEN(wpt, wpt_len);
     SET_EXPIRATION_TIME(expiration_time);
     SET_CREATION_TIME(creation_time);
-    
+
     tlen = webauth_token_encoded_length(alist);
     token = (char*)apr_palloc(rc->r->pool, tlen);
 
@@ -1058,8 +1063,8 @@ make_proxy_cookie(const char *proxy_type,
     apr_base64_encode(btoken, token, olen);
 
     fixup_setcookie(rc, proxy_cookie_name(proxy_type, rc), btoken);
-    
-    rc->pt = 
+
+    rc->pt =
         (MWA_PROXY_TOKEN*)apr_pcalloc(rc->r->pool, sizeof(MWA_PROXY_TOKEN));
     rc->pt->proxy_type = apr_pstrdup(rc->r->pool, proxy_type);
     rc->pt->subject = apr_pstrdup(rc->r->pool, subject);
@@ -1090,7 +1095,7 @@ make_cred_cookie(MWA_CRED_TOKEN *ct,
     alist = webauth_attr_list_new(10);
     if (alist == NULL) {
         ap_log_error(APLOG_MARK, APLOG_EMERG, 0, rc->r->server,
-                     "mod_webauth: %s: webauth_attr_list_new failed", 
+                     "mod_webauth: %s: webauth_attr_list_new failed",
                      mwa_func);
         return 0;
     }
@@ -1104,7 +1109,7 @@ make_cred_cookie(MWA_CRED_TOKEN *ct,
     SET_CRED_DATA(ct->cred_data, ct->cred_data_len);
     SET_EXPIRATION_TIME(ct->expiration_time);
     SET_CREATION_TIME(ct->creation_time);
-    
+
     tlen = webauth_token_encoded_length(alist);
     token = (char*)apr_palloc(rc->r->pool, tlen);
 
@@ -1137,9 +1142,9 @@ make_cred_cookie(MWA_CRED_TOKEN *ct,
  * existing one.
  */
 static int
-make_app_cookie(const char *subject, 
+make_app_cookie(const char *subject,
                 time_t creation_time,
-                time_t expiration_time, 
+                time_t expiration_time,
                 time_t last_used_time,
                 MWA_REQ_CTXT *rc)
 {
@@ -1164,7 +1169,7 @@ make_app_cookie(const char *subject,
         if (rc->dconf->app_token_lifetime) {
             expiration_time = creation_time + rc->dconf->app_token_lifetime;
         }
-        last_used_time = 
+        last_used_time =
             rc->dconf->last_use_update_interval ? creation_time : 0;
     }
 
@@ -1172,7 +1177,7 @@ make_app_cookie(const char *subject,
     SET_SUBJECT(subject);
     SET_EXPIRATION_TIME(expiration_time);
     SET_CREATION_TIME(creation_time);
-    
+
     if (last_used_time) {
         SET_LASTUSED_TIME(last_used_time);
     }
@@ -1183,7 +1188,7 @@ make_app_cookie(const char *subject,
     if (rc->sconf->ring == NULL)
         return 0;
 
-    status = webauth_token_create(alist, 0, token, 
+    status = webauth_token_create(alist, 0, token,
                                   &olen, tlen, rc->sconf->ring);
     webauth_attr_list_free(alist);
 
@@ -1215,7 +1220,7 @@ app_token_maint(MWA_REQ_CTXT *rc)
 {
     time_t curr;
 
-    if (!rc->dconf->inactive_expire && 
+    if (!rc->dconf->inactive_expire &&
         !rc->dconf->last_use_update_interval) {
         return 1;
     }
@@ -1228,7 +1233,7 @@ app_token_maint(MWA_REQ_CTXT *rc)
     curr = time(NULL);
 
     /* see if its inactive */
-    if (rc->dconf->inactive_expire && 
+    if (rc->dconf->inactive_expire &&
         (rc->at.last_used_time + rc->dconf->inactive_expire < curr)) {
         if (rc->sconf->debug)
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
@@ -1254,15 +1259,15 @@ app_token_maint(MWA_REQ_CTXT *rc)
 
     /* FIXME: hum, if this fails, should we expire cookie? */
     make_app_cookie(rc->at.subject,
-                   rc->at.creation_time, 
-                   rc->at.expiration_time, 
+                   rc->at.creation_time,
+                   rc->at.expiration_time,
                    rc->at.last_used_time, rc);
     return 1;
 }
 
 
 /*
- * parse an app-token, store in rc->at. 
+ * parse an app-token, store in rc->at.
  * return 0 on failure, 1 on success
  */
 static int
@@ -1307,7 +1312,7 @@ parse_app_token(char *token, MWA_REQ_CTXT *rc)
 
     /* pull out subject */
     sub = mwa_get_str_attr(alist, WA_TK_SUBJECT, rc->r, mwa_func, NULL);
-    
+
     if (sub == NULL) {
         goto cleanup;
     }
@@ -1328,7 +1333,7 @@ parse_app_token(char *token, MWA_REQ_CTXT *rc)
     result = app_token_maint(rc);
     if (result == 0) {
         /* clear out rc->at, since we couldn't use this app-token */
-        memset(&rc->at, 0, sizeof(rc->at));        
+        memset(&rc->at, 0, sizeof(rc->at));
     }
 
  cleanup:
@@ -1359,7 +1364,7 @@ parse_app_token_cookie(MWA_REQ_CTXT *rc)
     }  else {
         if (rc->sconf->debug)
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
-                         "mod_webauth: %s: found valid %s cookie for (%s)", 
+                         "mod_webauth: %s: found valid %s cookie for (%s)",
                          mwa_func, cname, rc->at.subject);
         return 1;
     }
@@ -1367,7 +1372,7 @@ parse_app_token_cookie(MWA_REQ_CTXT *rc)
 
 
 /*
- * parse a proxy-token from a cookie. 
+ * parse a proxy-token from a cookie.
  * return pointer to it on success, NULL on failure.
  */
 static MWA_PROXY_TOKEN *
@@ -1411,7 +1416,7 @@ parse_proxy_token(char *token, MWA_REQ_CTXT *rc)
 
     /* pull out subject */
     pt.subject = mwa_get_str_attr(alist, WA_TK_SUBJECT, rc->r, mwa_func, NULL);
-    
+
     if (pt.subject == NULL) {
         goto cleanup;
     }
@@ -1480,7 +1485,7 @@ parse_proxy_token_cookie(MWA_REQ_CTXT *rc, char *proxy_type)
     }  else {
         if (rc->sconf->debug)
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
-                         "mod_webauth: %s: found valid %s cookie for (%s)", 
+                         "mod_webauth: %s: found valid %s cookie for (%s)",
                          mwa_func, cname, rc->at.subject);
     }
     return pt;
@@ -1531,7 +1536,7 @@ get_session_key(char *token, MWA_REQ_CTXT *rc)
     /* pull out session key */
     status = webauth_attr_list_find(alist, WA_TK_SESSION_KEY, &i);
     if (i == -1) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, rc->r->server, 
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, rc->r->server,
                     "mod_webauth: %s: can't find session key in token",
                      mwa_func);
         goto cleanup;
@@ -1539,10 +1544,10 @@ get_session_key(char *token, MWA_REQ_CTXT *rc)
 
     klen = alist->attrs[i].length;
 
-    if (klen != WA_AES_128 && 
+    if (klen != WA_AES_128 &&
         klen != WA_AES_192 &&
         klen != WA_AES_256) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, rc->r->server, 
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, rc->r->server,
                      "mod_webauth: get_session_key: invalid key length: %lu",
                      (unsigned long) klen);
         goto cleanup;
@@ -1596,7 +1601,7 @@ handle_id_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc)
                      mwa_func, sa);
         subject = NULL;
     }
-        
+
     if (subject != NULL) {
         time_t expiration_time;
 
@@ -1615,7 +1620,7 @@ handle_id_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc)
 
         if (rc->sconf->debug)
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
-                         "mod_webauth: %s: got subject(%s) from id token", 
+                         "mod_webauth: %s: got subject(%s) from id token",
                          mwa_func,subject);
 
         make_app_cookie(subject, 0, expiration_time, 0, rc);
@@ -1627,7 +1632,7 @@ handle_id_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc)
 
 
 static int
-handle_proxy_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc) 
+handle_proxy_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc)
 {
     char *sub, *pt;
     void *wpt;
@@ -1671,7 +1676,7 @@ handle_proxy_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc)
 
     if (rc->sconf->debug)
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
-                     "mod_webauth: %s: got subject(%s) from proxy token", 
+                     "mod_webauth: %s: got subject(%s) from proxy token",
                      mwa_func, sub);
 
     /* FIXME: app-tokens where subject-auth-type is krb5 to need to
@@ -1699,9 +1704,9 @@ handle_error_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc)
 
     error_code = atoi(ec);
 
-    if (rc->sconf->debug) 
+    if (rc->sconf->debug)
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
-                     "mod_webauth: %s: parsed an error token(%d, %s)", 
+                     "mod_webauth: %s: parsed an error token(%d, %s)",
                      mwa_func, error_code, em);
 
     switch (error_code) {
@@ -1722,7 +1727,7 @@ handle_error_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc)
     ap_log_error(APLOG_MARK, APLOG_ALERT, 0, rc->r->server,
                  "mod_webauth: %s: %s: %s (%d)",
                          mwa_func, log_message, em, error_code);
-        
+
     return failure_redirect(rc);
 
 }
@@ -1731,7 +1736,7 @@ handle_error_token(WEBAUTH_ATTR_LIST *alist, MWA_REQ_CTXT *rc)
 /*
  * return OK or an HTTP_* code.
  */
-static int 
+static int
 parse_returned_token(char *token, WEBAUTH_KEY *key, MWA_REQ_CTXT *rc)
 {
     WEBAUTH_ATTR_LIST *alist;
@@ -1747,7 +1752,7 @@ parse_returned_token(char *token, WEBAUTH_KEY *key, MWA_REQ_CTXT *rc)
     blen = apr_base64_decode(token, token);
 
     status = webauth_token_parse_with_key(token, blen,
-                                          rc->sconf->token_max_ttl, 
+                                          rc->sconf->token_max_ttl,
                                           key, &alist);
 
     if (status != WA_ERR_NONE) {
@@ -1757,7 +1762,7 @@ parse_returned_token(char *token, WEBAUTH_KEY *key, MWA_REQ_CTXT *rc)
     }
 
     /* get the token-type to see what we should do with it */
-    token_type = mwa_get_str_attr(alist, WA_TK_TOKEN_TYPE, rc->r, 
+    token_type = mwa_get_str_attr(alist, WA_TK_TOKEN_TYPE, rc->r,
                                   mwa_func, NULL);
     if (token_type == NULL) {
         webauth_attr_list_free(alist);
@@ -1766,14 +1771,14 @@ parse_returned_token(char *token, WEBAUTH_KEY *key, MWA_REQ_CTXT *rc)
 
     if (strcmp(token_type, WA_TT_ID) == 0) {
         if (!handle_id_token(alist, rc)) {
-            /* FIXME: WHAT DO WE DO? failure redirect or ...? 
-               doing nothing will cause another redirect for auth... 
+            /* FIXME: WHAT DO WE DO? failure redirect or ...?
+               doing nothing will cause another redirect for auth...
              */
         }
     } else if (strcmp(token_type, WA_TT_PROXY) == 0) {
         if (!handle_proxy_token(alist, rc)) {
-            /* FIXME: WHAT DO WE DO? failure redirect or ...? 
-               doing nothing will cause another redirect for auth... 
+            /* FIXME: WHAT DO WE DO? failure redirect or ...?
+               doing nothing will cause another redirect for auth...
              */
         }
     } else if (strcmp(token_type, WA_TT_ERROR) == 0) {
@@ -1839,7 +1844,7 @@ check_url(MWA_REQ_CTXT *rc, int *in_url)
 
 
 static char *
-make_return_url(MWA_REQ_CTXT *rc, 
+make_return_url(MWA_REQ_CTXT *rc,
                 int check_dconf_return_url)
 {
     char *uri = rc->r->unparsed_uri;
@@ -1849,15 +1854,15 @@ make_return_url(MWA_REQ_CTXT *rc,
         if (rc->r->method_number == M_GET && rc->dconf->return_url) {
             if (rc->dconf->return_url[0] != '/')
                 return rc->dconf->return_url;
-            else 
-                return ap_construct_url(rc->r->pool, 
+            else
+                return ap_construct_url(rc->r->pool,
                                         rc->dconf->return_url, rc->r);
-        } else if (rc->r->method_number == M_POST && 
+        } else if (rc->r->method_number == M_POST &&
                    rc->dconf->post_return_url) {
             if (rc->dconf->post_return_url[0] != '/')
                 return rc->dconf->post_return_url;
-            else 
-                return ap_construct_url(rc->r->pool, 
+            else
+                return ap_construct_url(rc->r->pool,
                                         rc->dconf->post_return_url, rc->r);
         }
     }
@@ -1934,7 +1939,7 @@ redirect_request_token(MWA_REQ_CTXT *rc)
         int fl = rc->dconf->force_login;
         int lc = rc->dconf->login_canceled_url != NULL;
 
-        SET_REQUEST_OPTIONS(apr_pstrcat(rc->r->pool, 
+        SET_REQUEST_OPTIONS(apr_pstrcat(rc->r->pool,
                                         fl ? "fa" : "",
                                         fl && lc ? "," : "",
                                         lc ? "lc" : "",
@@ -2007,7 +2012,7 @@ redirect_request_token(MWA_REQ_CTXT *rc)
                                "?RT=", btoken,
                                ";ST=", st->token,
                                NULL);
-    
+
     apr_table_setn(rc->r->err_headers_out, "Location", redirect_url);
 
     if (rc->sconf->debug)
@@ -2059,11 +2064,11 @@ ssl_redirect(MWA_REQ_CTXT *rc)
     if (strcmp(uri.scheme, "http") == 0) {
         uri.scheme = (char *) "https";
         if (rc->sconf->ssl_redirect_port) {
-            uri.port_str = apr_psprintf(rc->r->pool, 
+            uri.port_str = apr_psprintf(rc->r->pool,
                                         "%d", rc->sconf->ssl_redirect_port);
             uri.port = rc->sconf->ssl_redirect_port;
         } else {
-            uri.port_str = apr_psprintf(rc->r->pool, 
+            uri.port_str = apr_psprintf(rc->r->pool,
                                         "%d", APR_URI_HTTPS_DEFAULT_PORT);
             uri.port = APR_URI_HTTPS_DEFAULT_PORT;
         }
@@ -2115,7 +2120,7 @@ parse_cred_token_cookie(MWA_REQ_CTXT *rc, MWA_WACRED *cred)
     }  else {
         if (rc->sconf->debug)
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, rc->r->server,
-                         "mod_webauth: %s: found valid %s cookie for (%s)", 
+                         "mod_webauth: %s: found valid %s cookie for (%s)",
                          mwa_func, cname, rc->at.subject);
     }
     return ct;
@@ -2145,13 +2150,13 @@ add_proxy_type(apr_array_header_t *a, char *type)
  * prepare them. i.e., for krb5 this means creating
  * a credential cache file and setting KRB5CCNAME.
  */
-static int 
+static int
 prepare_creds(MWA_REQ_CTXT *rc, char *proxy_type,
               MWA_CRED_TOKEN **creds, size_t num_creds)
 {
     const char *mwa_func="prepare_creds";
 
-    MWA_CRED_INTERFACE *mci = 
+    MWA_CRED_INTERFACE *mci =
         mwa_find_cred_interface(rc->r->server, proxy_type);
 
     if (mci != NULL) {
@@ -2171,7 +2176,7 @@ prepare_creds(MWA_REQ_CTXT *rc, char *proxy_type,
  * the specified proxy_type, we'll need to do a redirect to
  * get it.
  */
-static int 
+static int
 acquire_creds(MWA_REQ_CTXT *rc, char *proxy_type,
               MWA_WACRED *creds, size_t num_creds,
               apr_array_header_t **acquired_creds)
@@ -2233,7 +2238,7 @@ acquire_creds(MWA_REQ_CTXT *rc, char *proxy_type,
  * use_creds is on, so we need to gather creds (from cookies and/or
  * webkdc, redirecting if we don't have a proxy-token)
  */
-static int 
+static int
 gather_creds(MWA_REQ_CTXT *rc)
 {
     int i, code;
@@ -2244,9 +2249,9 @@ gather_creds(MWA_REQ_CTXT *rc)
     apr_array_header_t *acquired_creds = NULL; /* (MWA_CRED_TOKEN*) */
     MWA_WACRED *ncred, *cred;
     MWA_CRED_TOKEN *ct, **nct;
- 
+
     cred = (MWA_WACRED*) rc->dconf->creds->elts;
-    
+
     for (i = 0; i < rc->dconf->creds->nelts; i++) {
         if (cred[i].service) {
 
@@ -2261,7 +2266,7 @@ gather_creds(MWA_REQ_CTXT *rc)
             if (ct != NULL) {
                 /* save in gathered creds */
                 if (gathered_creds == NULL)
-                    gathered_creds = apr_array_make(rc->r->pool, 
+                    gathered_creds = apr_array_make(rc->r->pool,
                                                     rc->dconf->creds->nelts,
                                                     sizeof(MWA_CRED_TOKEN*));
                 nct = apr_array_push(gathered_creds);
@@ -2282,7 +2287,7 @@ gather_creds(MWA_REQ_CTXT *rc)
         }
     }
 
-    /* now, for each proxy type that has needed credentials, 
+    /* now, for each proxy type that has needed credentials,
        try and acquire them from the webkdc. */
     if (needed_proxy_types != NULL) {
         char **proxy = (char**)needed_proxy_types->elts;
@@ -2290,7 +2295,7 @@ gather_creds(MWA_REQ_CTXT *rc)
 
         /* foreach proxy type, attempt to acquire the needed creds */
         for (i=0; i < needed_proxy_types->nelts; i++) {
-            code = acquire_creds(rc, proxy[i], cred, 
+            code = acquire_creds(rc, proxy[i], cred,
                                  needed_creds->nelts,
                                  &acquired_creds);
             if (code != OK)
@@ -2308,7 +2313,7 @@ gather_creds(MWA_REQ_CTXT *rc)
     /* now go through all_proxy_types, and for do any special
        handling for the proxy type and all its credentials.
        for example, for krb5, we'll want to create the cred file,
-       dump in all the creds, and point KRB%CCNAME at it for 
+       dump in all the creds, and point KRB%CCNAME at it for
        cgi programs.
     */
 
@@ -2322,7 +2327,7 @@ gather_creds(MWA_REQ_CTXT *rc)
                 /* FIXME: similar as case where we can't get
                    creds from the webkdc. prepare_creds will log
                    any errors. For now, we continue and let the
-                   app cope. 
+                   app cope.
                 */
             }
         }
@@ -2333,11 +2338,11 @@ gather_creds(MWA_REQ_CTXT *rc)
 
 
 /*
- * go through cookies first. If we don't have a valid 
+ * go through cookies first. If we don't have a valid
  * app-token and/or proxy-token cookie, check URL and
  * process the token if present.
  */
-static int 
+static int
 gather_tokens(MWA_REQ_CTXT *rc)
 {
     int code, in_url;
@@ -2355,7 +2360,15 @@ gather_tokens(MWA_REQ_CTXT *rc)
         parse_app_token_cookie(rc);
 
         /* if its still NULL, time for a redirect */
+        /* (unless WebAuthOptional was specified) */
         if (rc->at.subject == NULL)
+          if(rc->dconf->web_auth_optional_ex == 1 &&
+             rc->dconf->web_auth_optional == 1)
+            /* (the subject of <anonymous> will be forgotten later on.
+             *  I don't know where, though. Any CGIs get only the empty
+             *  string as REMOTE_USER and WEBAUTH_USER) */
+            rc->at.subject = "<anonymous>";
+          else
             return redirect_request_token(rc);
     }
 
@@ -2400,12 +2413,12 @@ check_user_id_hook(request_rec *r)
     if (rc.sconf->debug)
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                      "mod_webauth: in check_user_id hook(%s)",
-                     rc.r->unparsed_uri != NULL ? 
+                     rc.r->unparsed_uri != NULL ?
                      rc.r->unparsed_uri : "null-uri");
 
     if ((at == NULL) ||
         ((strcmp(at, "WebAuth") != 0) &&
-         (rc.sconf->auth_type == NULL || 
+         (rc.sconf->auth_type == NULL ||
           strcmp(at, rc.sconf->auth_type) != 0))) {
         return DECLINED;
     }
@@ -2423,7 +2436,7 @@ check_user_id_hook(request_rec *r)
     }
 
     /* first check if we've already validated the user */
-    rc.at.subject = mwa_get_note(r, N_SUBJECT); 
+    rc.at.subject = mwa_get_note(r, N_SUBJECT);
 
     if (rc.at.subject == NULL) {
         int code = gather_tokens(&rc);
@@ -2463,21 +2476,21 @@ check_user_id_hook(request_rec *r)
 
     /* set environment variables */
 
-    wte = rc.at.expiration_time ? 
+    wte = rc.at.expiration_time ?
         apr_psprintf(rc.r->pool, "%d", (int)rc.at.expiration_time) : NULL;
-    
-    wtc = rc.at.creation_time ? 
+
+    wtc = rc.at.creation_time ?
         apr_psprintf(rc.r->pool, "%d", (int)rc.at.creation_time) : NULL;
 
     wtlu = rc.at.last_used_time ?
         apr_psprintf(rc.r->pool, "%d", (int)rc.at.last_used_time) : NULL;
 
     mwa_setenv(&rc, ENV_WEBAUTH_USER, rc.at.subject);
-    if (wte != NULL) 
+    if (wte != NULL)
         mwa_setenv(&rc, ENV_WEBAUTH_TOKEN_EXPIRATION, wte);
     if (wtc != NULL)
         mwa_setenv(&rc, ENV_WEBAUTH_TOKEN_CREATION, wtc);
-    if (wtlu != NULL) 
+    if (wtlu != NULL)
         mwa_setenv(&rc, ENV_WEBAUTH_TOKEN_LASTUSED, wtlu);
 
     if (rc.dconf->dont_cache_ex && rc.dconf->dont_cache)
@@ -2489,7 +2502,7 @@ check_user_id_hook(request_rec *r)
         /* always deny access in this case */
         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server,
                      "mod_webauth: denying access due to use of unsupported "
-                     "StanfordAuthGroups directive: %s", 
+                     "StanfordAuthGroups directive: %s",
                      rc.dconf->su_authgroups);
         return HTTP_UNAUTHORIZED;
     }
@@ -2498,17 +2511,17 @@ check_user_id_hook(request_rec *r)
         mwa_setenv(&rc, "SU_AUTH_USER", rc.at.subject);
         if (rc.at.creation_time) {
             time_t age = time(NULL) - rc.at.creation_time;
-            if (age < 0) 
+            if (age < 0)
                 age = 0;
-            mwa_setenv(&rc, "SU_AUTH_AGE", 
+            mwa_setenv(&rc, "SU_AUTH_AGE",
                        apr_psprintf(rc.r->pool, "%d", (int) age));
         }
     }
-#endif 
+#endif
 
     if (rc.sconf->debug) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                     "mod_webauth: check_user_id_hook: no_cache(%d) dont_cache(%d) dont_cache_ex(%d)", r->no_cache, 
+                     "mod_webauth: check_user_id_hook: no_cache(%d) dont_cache(%d) dont_cache_ex(%d)", r->no_cache,
                      rc.dconf->dont_cache, rc.dconf->dont_cache_ex);
     }
 
@@ -2524,9 +2537,9 @@ check_user_id_hook(request_rec *r)
 
 /*
  * this hook will attempt to find the returned-token and the
- * state-token in the URL (r->the_request). If we find them and stash them in 
- * the notes for the master request, and then remove them from 
- * everywhere we find them, so they 
+ * state-token in the URL (r->the_request). If we find them and stash them in
+ * the notes for the master request, and then remove them from
+ * everywhere we find them, so they
  * don't show up in access_logs.
  *
  *  we strip them in the following places:
@@ -2542,9 +2555,9 @@ check_user_id_hook(request_rec *r)
  *
  *  we'll stick the tokens in the notes table for the initial
  *  request
- *  
+ *
  */
-static int 
+static int
 translate_name_hook(request_rec *r)
 {
     char *p, *s, *rp;
@@ -2579,7 +2592,7 @@ translate_name_hook(request_rec *r)
     wr = apr_pstrmemdup(r->pool, s, p-s);
     /*
      * if (sconf->debug)
-     * ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, 
+     * ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
      * "mod_webauth: stash wr(%s)", wr);
      */
     mwa_setn_note(r, N_WEBAUTHR, NULL, "%s", wr);
@@ -2607,8 +2620,8 @@ translate_name_hook(request_rec *r)
     if (sconf->strip_url) {
         /* move over remaining */
         strcpy(rp, s);
-    
-        /* these are easier, we strip rmagic and everything after it, 
+
+        /* these are easier, we strip rmagic and everything after it,
            which might include smagic */
 
         strip_end(r->unparsed_uri, rmagic);
@@ -2646,7 +2659,7 @@ translate_name_hook(request_rec *r)
  * we're doing logout, we'll also ensure that the headers saying not to cache
  * the response are set properly.
  */
-static int 
+static int
 fixups_hook(request_rec *r)
 {
     MWA_REQ_CTXT rc;
@@ -2679,7 +2692,7 @@ seconds(const char *value, const char **error_str)
 {
     char temp[32];
     size_t mult, len;
-    
+
     len = strlen(value);
     if (len > (sizeof(temp) - 1)) {
         *error_str = "error: value too long!";
@@ -2689,27 +2702,27 @@ seconds(const char *value, const char **error_str)
     strcpy(temp, value);
 
     switch(temp[len-1]) {
-        case 's': 
+        case 's':
             mult = 1;
             break;
         case 'm':
             mult = 60;
             break;
-        case 'h': 
-            mult = 60*60; 
+        case 'h':
+            mult = 60*60;
             break;
-        case 'd': 
-            mult = 60*60*24; 
+        case 'd':
+            mult = 60*60*24;
             break;
-        case 'w': 
-            mult = 60*60*24*7; 
+        case 'w':
+            mult = 60*60*24*7;
             break;
         default:
             *error_str = "error: invalid units specified";
             return 0;
             break;
     }
-    
+
     temp[len-1] = '\0';
     return atoi(temp) * mult;
 }
@@ -2724,7 +2737,7 @@ cfg_str(cmd_parms *cmd, void *mconf, const char *arg)
 
     MWA_SCONF *sconf = (MWA_SCONF *)
         ap_get_module_config(cmd->server->module_config, &webauth_module);
-    
+
     switch (e) {
         /* server configs */
         case E_WebKdcURL:
@@ -2818,7 +2831,7 @@ cfg_str(cmd_parms *cmd, void *mconf, const char *arg)
             break;
 #endif
         default:
-            error_str = 
+            error_str =
                 apr_psprintf(cmd->pool,
                              "Invalid value cmd->info(%d) for directive %s",
                              (int) e,
@@ -2839,7 +2852,7 @@ cfg_flag(cmd_parms *cmd, void *mconfig, int flag)
 
     MWA_SCONF *sconf = (MWA_SCONF *)
         ap_get_module_config(cmd->server->module_config, &webauth_module);
-    
+
     switch (e) {
         /* server configs */
         case E_Debug:
@@ -2897,6 +2910,10 @@ cfg_flag(cmd_parms *cmd, void *mconfig, int flag)
             dconf->dont_cache = flag;
             dconf->dont_cache_ex = 1;
             break;
+        case E_WebAuthOptional:
+            dconf->web_auth_optional = flag;
+            dconf->web_auth_optional_ex = 1;
+            break;
 #ifndef NO_STANFORD_SUPPORT
         case SE_DoConfirm:
             if (flag) {
@@ -2915,7 +2932,7 @@ cfg_flag(cmd_parms *cmd, void *mconfig, int flag)
             break;
 #endif
         default:
-            error_str = 
+            error_str =
                 apr_psprintf(cmd->pool,
                              "Invalid value cmd->info(%d) for directive %s",
                              (int) e,
@@ -2937,18 +2954,18 @@ cfg_take12(cmd_parms *cmd, void *mconfig, const char *w1, const char *w2)
 
     MWA_SCONF *sconf = (MWA_SCONF *)
         ap_get_module_config(cmd->server->module_config, &webauth_module);
-    
+
     switch (e) {
         /* server configs */
         case E_Keytab:
             sconf->keytab_path = ap_server_root_relative(cmd->pool, w1);
-            sconf->keytab_principal = 
+            sconf->keytab_principal =
                 (w2 != NULL) ? apr_pstrdup(cmd->pool, w2) : NULL;
             break;
         /* start of dconfigs */
         case E_Cred:
             if (dconf->creds == NULL) {
-                dconf->creds = 
+                dconf->creds =
                     apr_array_make(cmd->pool, 5, sizeof(MWA_WACRED));
             }
             cred = apr_array_push(dconf->creds);
@@ -2956,7 +2973,7 @@ cfg_take12(cmd_parms *cmd, void *mconfig, const char *w1, const char *w2)
             cred->service = (w2 == NULL) ? NULL : apr_pstrdup(cmd->pool, w2);
             break;
         default:
-            error_str = 
+            error_str =
                 apr_psprintf(cmd->pool,
                              "Invalid value cmd->info(%d) for directive %s",
                              (int) e,
@@ -3039,6 +3056,9 @@ static const command_rec cmds[] = {
     DSTR(CD_PostReturnURL, E_PostReturnURL, CM_PostReturnURL),
     DSTR(CD_LoginCanceledURL, E_LoginCanceledURL, CM_LoginCanceledURL),
     DSTR(CD_VarPrefix, E_VarPrefix, CM_VarPrefix),
+    DFLAG(CD_WebAuthOptional, E_WebAuthOptional, CM_WebAuthOptional),
+
+    /*  */
 
 #ifndef NO_STANFORD_SUPPORT
     DSTR(SCD_ConfirmMsg, SE_ConfirmMsg, SCM_ConfirmMsg),
@@ -3048,7 +3068,7 @@ static const command_rec cmds[] = {
     DSTR(SCD_ReturnURL, SE_ReturnURL, SCM_ReturnURL),
     DFLAG(SCD_DontCache, SE_DontCache, SCM_DontCache),
     DFLAG(SCD_ForceReload, SE_ForceReload, SCM_ForceReload),
-#endif 
+#endif
     { NULL, { NULL }, NULL, 0, 0, NULL }
 };
 
@@ -3079,10 +3099,10 @@ static int webauth_access_checker(request_rec *r)
                  "mod_webauth: in accesss_checker hook");
     return DECLINED;
 }
-#endif 
+#endif
 
 
-static void 
+static void
 register_hooks(apr_pool_t *p UNUSED)
 {
     /* get our module called before the basic authentication stuff */
@@ -3093,7 +3113,7 @@ register_hooks(apr_pool_t *p UNUSED)
 
     /* we need to get run before anyone else, so we can clean up the URL
        if need be */
-    ap_hook_translate_name(translate_name_hook, NULL, NULL, 
+    ap_hook_translate_name(translate_name_hook, NULL, NULL,
                            APR_HOOK_REALLY_FIRST);
 
     ap_hook_check_user_id(check_user_id_hook, NULL, mods, APR_HOOK_MIDDLE);
@@ -3108,7 +3128,7 @@ register_hooks(apr_pool_t *p UNUSED)
 
 /* Dispatch list for API hooks */
 module AP_MODULE_DECLARE_DATA webauth_module = {
-    STANDARD20_MODULE_STUFF, 
+    STANDARD20_MODULE_STUFF,
     config_dir_create,     /* create per-dir    config structures */
     config_dir_merge,      /* merge  per-dir    config structures */
     config_server_create,  /* create per-server config structures */
diff --git a/modules/webauth/mod_webauth.h b/modules/webauth/mod_webauth.h
index 300c046..078eaa5 100644
--- a/modules/webauth/mod_webauth.h
+++ b/modules/webauth/mod_webauth.h
@@ -45,13 +45,13 @@
 
 #include <lib/webauth.h>
 
-/* how long to wait between trying for a new token when 
+/* how long to wait between trying for a new token when
  * a renewal attempt fails
  */
 #define TOKEN_RETRY_INTERVAL  600
 
-/* 
- * how long into the tokens lifetime do we attempt our first revnewal 
+/*
+ * how long into the tokens lifetime do we attempt our first revnewal
  */
 #define START_RENEWAL_ATTEMPT_PERCENT (0.90)
 
@@ -181,6 +181,9 @@
 #define CD_DontCache "WebAuthDontCache"
 #define CM_DontCache "sets Expires header to current date"
 
+#define CD_WebAuthOptional "WebAuthOptional"
+#define CM_WebAuthOptional "Make authentication in the current directory optional."
+
 #ifndef NO_STANFORD_SUPPORT
 
 /* Stanford WebAuth 2.5 compat */
@@ -211,7 +214,7 @@
 #define N_WEBAUTHS "mod_webauth_WEBAUTHS"
 #define N_SUBJECT  "mod_webauth_SUBJECT"
 
-/* attr list macros to make code easier to read and audit 
+/* attr list macros to make code easier to read and audit
  * we don't need to check error codes since we are using
  * WA_F_NONE, which doesn't allocate any memory.
  */
@@ -295,6 +298,7 @@ enum {
     SE_ReturnURL,
     SE_Groups,
 #endif
+    E_WebAuthOptional
 };
 
 /* a service token and associated data, all memory (including key)
@@ -338,13 +342,13 @@ typedef struct {
     int extra_redirect_ex; /* if it was explicitly specified in conf file */
     const char *subject_auth_type;
     int strip_url;
-    int strip_url_ex; 
+    int strip_url_ex;
     int keyring_auto_update;
     int keyring_auto_update_ex;
     int keyring_key_lifetime;
     int keyring_key_lifetime_ex;
     int subject_auth_type_ex;
-    int token_max_ttl; 
+    int token_max_ttl;
     int token_max_ttl_ex;
     /* stuff we need to clean up on restarts and what not */
     WEBAUTH_KEYRING *ring; /* our keyring */
@@ -376,6 +380,8 @@ typedef struct {
     apr_array_header_t *creds; /* array of MWA_WACRED's */
     int dont_cache;
     int dont_cache_ex;
+    int web_auth_optional;
+    int web_auth_optional_ex;
 #ifndef NO_STANFORD_SUPPORT
     char *su_authgroups;
 #endif
@@ -453,19 +459,19 @@ typedef struct {
     const char *type;
 
     /* function to validate subject-authenticator-data */
-    const char *(*validate_sad) (MWA_REQ_CTXT *rc, 
-                                 void *sad, 
+    const char *(*validate_sad) (MWA_REQ_CTXT *rc,
+                                 void *sad,
                                  size_t sad_len);
 
     /* function to run through all the cred tokens and prepare any
        cred tokens that are the same as our type for use by CGI */
     int (*prepare_creds)(MWA_REQ_CTXT *rc,
-                         MWA_CRED_TOKEN **creds, 
+                         MWA_CRED_TOKEN **creds,
                          size_t num_creds);
 
     /* get the base64'd blob that we would send to the WebKDC
        in the <requesterCredential> element. */
-    const char *(*webkdc_credential)(server_rec *server, 
+    const char *(*webkdc_credential)(server_rec *server,
                                      MWA_SCONF *sconf,
                                      apr_pool_t *pool);
 
@@ -475,7 +481,7 @@ typedef struct {
 /* webkdc.c */
 
 MWA_SERVICE_TOKEN *
-mwa_get_service_token(server_rec *server, 
+mwa_get_service_token(server_rec *server,
                       MWA_SCONF *sconf, apr_pool_t *pool,
                       int local_cache_only);
 
@@ -495,11 +501,11 @@ mwa_get_creds_from_webkdc(MWA_REQ_CTXT *rc,
  */
 
 char *
-mwa_get_str_attr(WEBAUTH_ATTR_LIST *alist, const char *name, 
+mwa_get_str_attr(WEBAUTH_ATTR_LIST *alist, const char *name,
                  request_rec *r, const char *func, size_t *vlen);
 
 /*
- * get note from main request 
+ * get note from main request
  */
 const char *
 mwa_get_note(request_rec *r, const char *note);
@@ -528,15 +534,15 @@ mwa_setn_note(request_rec *r,
 /*
  * log interesting stuff from the request
  */
-void 
+void
 mwa_log_request(request_rec *r, const char *msg);
 
 /*
  * log a webauth-related error
  */
 void
-mwa_log_webauth_error(server_rec *r, 
-                      int status, 
+mwa_log_webauth_error(server_rec *r,
+                      int status,
                       const char *mwa_func,
                       const char *func,
                       const char *extra);
@@ -547,7 +553,7 @@ mwa_log_webauth_error(server_rec *r,
 int
 mwa_cache_keyring(server_rec *serv, MWA_SCONF *sconf);
 
-/* 
+/*
  * get all cookies that start with webauth_
  */
 apr_array_header_t *
@@ -558,12 +564,12 @@ mwa_get_webauth_cookies(request_rec *r);
  * if ring is non-null use it, otherwise log an error and return NULL.
  */
 MWA_CRED_TOKEN *
-mwa_parse_cred_token(char *token, 
+mwa_parse_cred_token(char *token,
                      WEBAUTH_KEYRING *ring,
-                     WEBAUTH_KEY *key, 
+                     WEBAUTH_KEY *key,
                      MWA_REQ_CTXT *rc);
 
-void 
+void
 mwa_log_apr_error(server_rec *server,
                   apr_status_t astatus,
                   const char *mwa_func,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://mailman.stanford.edu/pipermail/webauth-info/attachments/20110121/c139739c/attachment.asc>


More information about the webauth-info mailing list