You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mi...@apache.org on 2013/03/17 17:02:42 UTC

svn commit: r1457471 - in /httpd/httpd/trunk: docs/log-message-tags/next-number docs/manual/expr.xml docs/manual/mod/mod_auth_basic.xml docs/manual/mod/mod_ssl.xml modules/aaa/mod_auth_basic.c

Author: minfrin
Date: Sun Mar 17 16:02:41 2013
New Revision: 1457471

URL: http://svn.apache.org/r1457471
Log:
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.

Modified:
    httpd/httpd/trunk/docs/log-message-tags/next-number
    httpd/httpd/trunk/docs/manual/expr.xml
    httpd/httpd/trunk/docs/manual/mod/mod_auth_basic.xml
    httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
    httpd/httpd/trunk/modules/aaa/mod_auth_basic.c

Modified: httpd/httpd/trunk/docs/log-message-tags/next-number
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/log-message-tags/next-number?rev=1457471&r1=1457470&r2=1457471&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/log-message-tags/next-number (original)
+++ httpd/httpd/trunk/docs/log-message-tags/next-number Sun Mar 17 16:02:41 2013
@@ -1 +1 @@
-2455
+2460

Modified: httpd/httpd/trunk/docs/manual/expr.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/expr.xml?rev=1457471&r1=1457470&r2=1457471&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/expr.xml (original)
+++ httpd/httpd/trunk/docs/manual/expr.xml Sun Mar 17 16:02:41 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>

Modified: httpd/httpd/trunk/docs/manual/mod/mod_auth_basic.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_auth_basic.xml?rev=1457471&r1=1457470&r2=1457471&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_auth_basic.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_auth_basic.xml Sun Mar 17 16:02:41 2013
@@ -109,4 +109,63 @@ 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 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>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} password
+&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>
+
+</usage>
+</directivesynopsis>
+
 </modulesynopsis>

Modified: httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml?rev=1457471&r1=1457470&r2=1457471&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml Sun Mar 17 16:02:41 2013
@@ -1292,6 +1292,11 @@ The available <em>option</em>s are:</p>
     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>

Modified: httpd/httpd/trunk/modules/aaa/mod_auth_basic.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_auth_basic.c?rev=1457471&r1=1457470&r2=1457471&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/aaa/mod_auth_basic.c (original)
+++ httpd/httpd/trunk/modules/aaa/mod_auth_basic.c Sun Mar 17 16:02:41 2013
@@ -28,26 +28,51 @@
 #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;
+
+    return newconf;
+}
+
 static const char *add_authn_provider(cmd_parms *cmd, void *config,
                                       const char *arg)
 {
@@ -93,15 +118,50 @@ 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;
+
+    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_TAKE2("AuthBasicFake", add_basic_fake, NULL, OR_AUTHCFG,
+                  "Fake basic authentication using the given expressions for "
+                  "username and password"),
     {NULL}
 };
 
@@ -294,10 +354,62 @@ 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->fake_set) {
+        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);
+        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);
+        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);
 }
@@ -306,7 +418,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 */



Re: svn commit: r1457471 - in /httpd/httpd/trunk: docs/log-message-tags/next-number docs/manual/expr.xml docs/manual/mod/mod_auth_basic.xml docs/manual/mod/mod_ssl.xml modules/aaa/mod_auth_basic.c

Posted by Graham Leggett <mi...@sharp.fm>.
On 17 Mar 2013, at 6:54 PM, Eric Covener <co...@gmail.com> wrote:

> If we maintain the use of a password here, like mod_ssl does, wouldn't
> we need to make sure it doesn't come in over the wire?

We use apr_table_setn() which replaces anything that is there already, although if either the username or the password resolve to an empty string it is possible for a user to inject their own.

I think to be safe, we should unset the header in the two empty string cases. Done in r1457504.

Regards,
Graham
--


Re: svn commit: r1457471 - in /httpd/httpd/trunk: docs/log-message-tags/next-number docs/manual/expr.xml docs/manual/mod/mod_auth_basic.xml docs/manual/mod/mod_ssl.xml modules/aaa/mod_auth_basic.c

Posted by Eric Covener <co...@gmail.com>.
On Sun, Mar 17, 2013 at 12:02 PM,  <mi...@apache.org> wrote:
> Author: minfrin
> Date: Sun Mar 17 16:02:41 2013
> New Revision: 1457471
>
> URL: http://svn.apache.org/r1457471
> Log:
> 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.

If we maintain the use of a password here, like mod_ssl does, wouldn't
we need to make sure it doesn't come in over the wire?

(Maybe better to have AuthBasicProvider fake and not have to deal with
a dummy password)