You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2013/07/11 14:13:13 UTC

svn commit: r1502199 - in /httpd/httpd/branches/2.4.x: ./ STATUS docs/manual/ docs/manual/expr.xml docs/manual/howto/ docs/manual/mod/ docs/manual/mod/mod_auth_basic.xml docs/manual/mod/mod_ssl.xml docs/manual/rewrite/ modules/aaa/mod_auth_basic.c

Author: jim
Date: Thu Jul 11 12:13:13 2013
New Revision: 1502199

URL: http://svn.apache.org/r1502199
Log:
Merge r1457471, r1457504, r1462266, r1468581 from trunk:

mod_auth_basic: Add a generic mechanism to fake basic authentication
using the ap_expr parser. This allows the administrator to construct
their own username and password for basic authentication based on their
needs. Alternative fix for PR52616.


Remove the Authorization header should either the username or the password
resolve to an empty string.


* Inherit providers during merging

mod_auth_basic: Allow AuthBasicFake to be switched off for an URL space.

Submitted by: minfrin, rpluem, minfrin
Reviewed/backported by: jim

Modified:
    httpd/httpd/branches/2.4.x/   (props changed)
    httpd/httpd/branches/2.4.x/STATUS
    httpd/httpd/branches/2.4.x/docs/manual/   (props changed)
    httpd/httpd/branches/2.4.x/docs/manual/expr.xml
    httpd/httpd/branches/2.4.x/docs/manual/howto/   (props changed)
    httpd/httpd/branches/2.4.x/docs/manual/mod/   (props changed)
    httpd/httpd/branches/2.4.x/docs/manual/mod/mod_auth_basic.xml
    httpd/httpd/branches/2.4.x/docs/manual/mod/mod_ssl.xml
    httpd/httpd/branches/2.4.x/docs/manual/rewrite/   (props changed)
    httpd/httpd/branches/2.4.x/modules/aaa/mod_auth_basic.c

Propchange: httpd/httpd/branches/2.4.x/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk:r1457471,1457504,1462266,1468581

Modified: httpd/httpd/branches/2.4.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/STATUS?rev=1502199&r1=1502198&r2=1502199&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/STATUS (original)
+++ httpd/httpd/branches/2.4.x/STATUS Thu Jul 11 12:13:13 2013
@@ -90,17 +90,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  * mod_auth_basic: Add a generic mechanism to fake basic authentication
-    using the ap_expr parser. This allows the administrator to construct
-    their own username and password for basic authentication based on their
-    needs. Alternative fix for PR52616.
-    trunk patch: http://svn.apache.org/r1457471
-                 http://svn.apache.org/r1457504
-                 http://svn.apache.org/r1462266
-                 http://svn.apache.org/r1468581
-    2.4.x patch: http://people.apache.org/~minfrin/httpd-mod_auth_basic-fake4.patch
-    +1: minfrin, jim, druggeri
-
   * mod_proxy: Connection header clearing issues
     trunk patch: https://svn.apache.org/viewvc?view=revision&revision=1481891
                  https://svn.apache.org/viewvc?view=revision&revision=1482075

Propchange: httpd/httpd/branches/2.4.x/docs/manual/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual:r1457471,1457504,1462266,1468581

Modified: httpd/httpd/branches/2.4.x/docs/manual/expr.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/docs/manual/expr.xml?rev=1502199&r1=1502198&r2=1502199&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/docs/manual/expr.xml (original)
+++ httpd/httpd/branches/2.4.x/docs/manual/expr.xml Thu Jul 11 12:13:13 2013
@@ -41,6 +41,10 @@
 <seealso><directive module="core" type="section">If</directive></seealso>
 <seealso><directive module="core" type="section">ElseIf</directive></seealso>
 <seealso><directive module="core" type="section">Else</directive></seealso>
+<seealso><directive module="mod_auth_basic">AuthBasicFake</directive></seealso>
+<seealso><directive module="mod_auth_form">AuthFormLoginRequiredLocation</directive></seealso>
+<seealso><directive module="mod_auth_form">AuthFormLoginSuccessLocation</directive></seealso>
+<seealso><directive module="mod_auth_form">AuthFormLogoutLocation</directive></seealso>
 <seealso><directive module="mod_rewrite">RewriteCond</directive></seealso>
 <seealso><directive module="mod_setenvif">SetEnvIfExpr</directive></seealso>
 <seealso><directive module="mod_headers">Header</directive></seealso>

Propchange: httpd/httpd/branches/2.4.x/docs/manual/howto/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual/howto:r1457471,1457504,1462266,1468581

Propchange: httpd/httpd/branches/2.4.x/docs/manual/mod/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual/mod:r1457471,1457504,1462266,1468581

Modified: httpd/httpd/branches/2.4.x/docs/manual/mod/mod_auth_basic.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/docs/manual/mod/mod_auth_basic.xml?rev=1502199&r1=1502198&r2=1502199&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/docs/manual/mod/mod_auth_basic.xml (original)
+++ httpd/httpd/branches/2.4.x/docs/manual/mod/mod_auth_basic.xml Thu Jul 11 12:13:13 2013
@@ -110,4 +110,75 @@ lower level modules</description>
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>AuthBasicFake</name>
+<description>Fake basic authentication using the given expressions for
+username and password</description>
+<syntax>AuthBasicFake off|username [password]</syntax>
+<default>none</default>
+<contextlist><context>directory</context><context>.htaccess</context>
+</contextlist>
+<override>AuthConfig</override>
+
+<usage>
+    <p>The username and password specified are combined into an
+    Authorization header, which is passed to the server or service
+    behind the webserver. Both the username and password fields are
+    interpreted using the <a href="../expr.html">expression parser</a>,
+    which allows both the username and password to be set based on
+    request parameters.</p>
+
+    <p>If the password is not specified, the default value "password"
+    will be used. To disable fake basic authentication for an URL
+    space, specify "AuthBasicFake off".</p>
+
+    <p>In this example, we pass a fixed username and password to a
+    backend server.</p>
+
+    <example><title>Fixed Example</title>
+    <highlight language="config">
+&lt;Location /demo&gt;
+    AuthBasicFake demo demopass
+&lt;/Location&gt;
+    </highlight>
+    </example>
+
+    <p>In this example, we pass the email address extracted from a client
+    certificate, extending the functionality of the FakeBasicAuth option
+    within the <directive module="mod_ssl">SSLOptions</directive>
+    directive. Like the FakeBasicAuth option, the password is set to the
+    fixed string "password".</p>
+
+    <example><title>Certificate Example</title>
+    <highlight language="config">
+&lt;Location /secure&gt;
+    AuthBasicFake %{SSL_CLIENT_S_DN_Email}
+&lt;/Location&gt;
+    </highlight>
+    </example>
+
+    <p>Extending the above example, we generate a password by hashing the
+    email address with a fixed passphrase, and passing the hash to the
+    backend server. This can be used to gate into legacy systems that do
+    not support client certificates.</p>
+
+    <example><title>Password Example</title>
+    <highlight language="config">
+&lt;Location /secure&gt;
+    AuthBasicFake %{SSL_CLIENT_S_DN_Email} %{sha1:passphrase-%{SSL_CLIENT_S_DN_Email}}
+&lt;/Location&gt;
+    </highlight>
+    </example>
+
+    <example><title>Exclusion Example</title>
+    <highlight language="config">
+&lt;Location /public&gt;
+    AuthBasicFake off
+&lt;/Location&gt;
+    </highlight>
+    </example>
+
+</usage>
+</directivesynopsis>
+
 </modulesynopsis>

Modified: httpd/httpd/branches/2.4.x/docs/manual/mod/mod_ssl.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/docs/manual/mod/mod_ssl.xml?rev=1502199&r1=1502198&r2=1502199&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/docs/manual/mod/mod_ssl.xml (original)
+++ httpd/httpd/branches/2.4.x/docs/manual/mod/mod_ssl.xml Thu Jul 11 12:13:13 2013
@@ -1293,6 +1293,11 @@ The available <em>option</em>s are:</p>
     word `<code>password</code>''. Those who live under MD5-based encryption
     (for instance under FreeBSD or BSD/OS, etc.) should use the following MD5
     hash of the same word: ``<code>$1$OXLyS...$Owx8s2/m9/gfkcRVXzgoE/</code>''.</p>
+
+    <p>Note that the <directive module="mod_auth_basic">AuthBasicFake</directive>
+    directive within <module>mod_auth_basic</module> can be used as a more
+    general mechanism for faking basic authentication, giving control over the
+    structure of both the username and password.</p>
 </li>
 <li><code>StrictRequire</code>
     <p>

Propchange: httpd/httpd/branches/2.4.x/docs/manual/rewrite/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual/rewrite:r1457471,1457504,1462266,1468581

Modified: httpd/httpd/branches/2.4.x/modules/aaa/mod_auth_basic.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/aaa/mod_auth_basic.c?rev=1502199&r1=1502198&r2=1502199&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/aaa/mod_auth_basic.c (original)
+++ httpd/httpd/branches/2.4.x/modules/aaa/mod_auth_basic.c Thu Jul 11 12:13:13 2013
@@ -29,26 +29,53 @@
 #include "http_protocol.h"
 #include "http_request.h"
 #include "ap_provider.h"
+#include "ap_expr.h"
 
 #include "mod_auth.h"
 
 typedef struct {
     authn_provider_list *providers;
-    char *dir;
+    char *dir; /* unused variable */
     int authoritative;
+    ap_expr_info_t *fakeuser;
+    ap_expr_info_t *fakepass;
+    int fake_set:1;
+    int authoritative_set:1;
 } auth_basic_config_rec;
 
 static void *create_auth_basic_dir_config(apr_pool_t *p, char *d)
 {
     auth_basic_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
 
-    conf->dir = d;
     /* Any failures are fatal. */
     conf->authoritative = 1;
 
     return conf;
 }
 
+static void *merge_auth_basic_dir_config(apr_pool_t *p, void *basev, void *overridesv)
+{
+    auth_basic_config_rec *newconf = apr_pcalloc(p, sizeof(*newconf));
+    auth_basic_config_rec *base = basev;
+    auth_basic_config_rec *overrides = overridesv;
+
+    newconf->authoritative =
+            overrides->authoritative_set ? overrides->authoritative :
+                    base->authoritative;
+    newconf->authoritative_set = overrides->authoritative_set
+            || base->authoritative_set;
+
+    newconf->fakeuser =
+            overrides->fake_set ? overrides->fakeuser : base->fakeuser;
+    newconf->fakepass =
+            overrides->fake_set ? overrides->fakepass : base->fakepass;
+    newconf->fake_set = overrides->fake_set || base->fake_set;
+
+    newconf->providers = overrides->providers ? overrides->providers : base->providers;
+
+    return newconf;
+}
+
 static const char *add_authn_provider(cmd_parms *cmd, void *config,
                                       const char *arg)
 {
@@ -94,15 +121,72 @@ static const char *add_authn_provider(cm
     return NULL;
 }
 
+static const char *set_authoritative(cmd_parms * cmd, void *config, int flag)
+{
+    auth_basic_config_rec *conf = (auth_basic_config_rec *) config;
+
+    conf->authoritative = flag;
+    conf->authoritative_set = 1;
+
+    return NULL;
+}
+
+static const char *add_basic_fake(cmd_parms * cmd, void *config,
+        const char *user, const char *pass)
+{
+    auth_basic_config_rec *conf = (auth_basic_config_rec *) config;
+    const char *err;
+
+    if (!strcasecmp(user, "off")) {
+
+        conf->fakeuser = NULL;
+        conf->fakepass = NULL;
+        conf->fake_set = 1;
+
+    }
+    else {
+
+        /* if password is unspecified, set it to the fixed string "password" to
+         * be compatible with the behaviour of mod_ssl.
+         */
+        if (!pass) {
+            pass = "password";
+        }
+
+        conf->fakeuser =
+                ap_expr_parse_cmd(cmd, user, AP_EXPR_FLAG_STRING_RESULT,
+                        &err, NULL);
+        if (err) {
+            return apr_psprintf(cmd->pool,
+                    "Could not parse fake username expression '%s': %s", user,
+                    err);
+        }
+        conf->fakepass =
+                ap_expr_parse_cmd(cmd, pass, AP_EXPR_FLAG_STRING_RESULT,
+                        &err, NULL);
+        if (err) {
+            return apr_psprintf(cmd->pool,
+                    "Could not parse fake password expression '%s': %s", user,
+                    err);
+        }
+        conf->fake_set = 1;
+
+    }
+
+    return NULL;
+}
+
 static const command_rec auth_basic_cmds[] =
 {
     AP_INIT_ITERATE("AuthBasicProvider", add_authn_provider, NULL, OR_AUTHCFG,
                     "specify the auth providers for a directory or location"),
-    AP_INIT_FLAG("AuthBasicAuthoritative", ap_set_flag_slot,
-                 (void *)APR_OFFSETOF(auth_basic_config_rec, authoritative),
-                 OR_AUTHCFG,
+    AP_INIT_FLAG("AuthBasicAuthoritative", set_authoritative, NULL, OR_AUTHCFG,
                  "Set to 'Off' to allow access control to be passed along to "
                  "lower modules if the UserID is not known to this module"),
+    AP_INIT_TAKE12("AuthBasicFake", add_basic_fake, NULL, OR_AUTHCFG,
+                  "Fake basic authentication using the given expressions for "
+                  "username and password, 'off' to disable. Password defaults "
+                  "to 'password' if missing."),
     {NULL}
 };
 
@@ -295,10 +379,68 @@ static int authenticate_basic_user(reque
     return OK;
 }
 
+/* If requested, create a fake basic authentication header for the benefit
+ * of a proxy or application running behind this server.
+ */
+static int authenticate_basic_fake(request_rec *r)
+{
+    const char *auth_line, *user, *pass, *err;
+    auth_basic_config_rec *conf = ap_get_module_config(r->per_dir_config,
+                                                       &auth_basic_module);
+
+    if (!conf->fakeuser) {
+        return DECLINED;
+    }
+
+    user = ap_expr_str_exec(r, conf->fakeuser, &err);
+    if (err) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02455)
+                      "AuthBasicFake: could not evaluate user expression for URI '%s': %s", r->uri, err);
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }
+    if (!user || !*user) {
+        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02458)
+                      "AuthBasicFake: empty username expression for URI '%s', ignoring", r->uri);
+
+        apr_table_unset(r->headers_in, "Authorization");
+
+        return DECLINED;
+    }
+
+    pass = ap_expr_str_exec(r, conf->fakepass, &err);
+    if (err) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02456)
+                      "AuthBasicFake: could not evaluate password expression for URI '%s': %s", r->uri, err);
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }
+    if (!pass || !*pass) {
+        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02459)
+                      "AuthBasicFake: empty password expression for URI '%s', ignoring", r->uri);
+
+        apr_table_unset(r->headers_in, "Authorization");
+
+        return DECLINED;
+    }
+
+    auth_line = apr_pstrcat(r->pool, "Basic ",
+                            ap_pbase64encode(r->pool,
+                                             apr_pstrcat(r->pool, user,
+                                                         ":", pass, NULL)),
+                            NULL);
+    apr_table_setn(r->headers_in, "Authorization", auth_line);
+
+    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02457)
+                  "AuthBasicFake: \"Authorization: %s\"",
+                  auth_line);
+
+    return OK;
+}
+
 static void register_hooks(apr_pool_t *p)
 {
     ap_hook_check_authn(authenticate_basic_user, NULL, NULL, APR_HOOK_MIDDLE,
                         AP_AUTH_INTERNAL_PER_CONF);
+    ap_hook_fixups(authenticate_basic_fake, NULL, NULL, APR_HOOK_LAST);
     ap_hook_note_auth_failure(hook_note_basic_auth_failure, NULL, NULL,
                               APR_HOOK_MIDDLE);
 }
@@ -307,7 +449,7 @@ AP_DECLARE_MODULE(auth_basic) =
 {
     STANDARD20_MODULE_STUFF,
     create_auth_basic_dir_config,  /* dir config creater */
-    NULL,                          /* dir merger --- default is to override */
+    merge_auth_basic_dir_config,   /* dir merger --- default is to override */
     NULL,                          /* server config */
     NULL,                          /* merge server config */
     auth_basic_cmds,               /* command apr_table_t */