]> granicus.if.org Git - apache/commitdiff
Add authz providers for use with mod_authz_core and its RequireAny/RequireAll
authorStefan Fritsch <sf@apache.org>
Wed, 29 Sep 2010 20:32:23 +0000 (20:32 +0000)
committerStefan Fritsch <sf@apache.org>
Wed, 29 Sep 2010 20:32:23 +0000 (20:32 +0000)
containers:

'ssl' (equivalent to SSLRequireSSL)
'ssl-verify-client' (for use with 'SSLVerifyClient optional')
'ssl-require' (expressions with same syntax as SSLRequire)

We may decide to axe 'ssl-require' again in favor of the generic 'expr'
provider, depending on the development of the ap_expr parser.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1002837 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/ssl/mod_ssl.c
modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_kernel.c
modules/ssl/ssl_expr.c
modules/ssl/ssl_expr.h
modules/ssl/ssl_expr_eval.c
modules/ssl/ssl_private.h

diff --git a/CHANGES b/CHANGES
index 350573e44c3bd340e62aa28c0d79c9a3c44f76de..3fc6f0a19bd12688e3b935d604505f7e46df9e70 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,12 @@
 
 Changes with Apache 2.3.9
 
+  *) mod_ssl: Add authz providers for use with mod_authz_core and its
+     RequireAny/RequireAll containers: 'ssl' (equivalent to SSLRequireSSL),
+     'ssl-verify-client' (for use with 'SSLVerifyClient optional'), and
+     'ssl-require' (expressions with same syntax as SSLRequire).
+     [Stefan Fritsch]
+
   *) mod_ssl: Make the ssl expression parser thread-safe. It now requires
      bison instead of yacc. [Stefan Fritsch]
 
index 603a00e7c7009d6704b299d1ca00fd445ca4ceda..aa2dec8401520b8398a0392bd079870c2934d858 100644 (file)
@@ -554,6 +554,22 @@ static void ssl_register_hooks(apr_pool_t *p)
 
     APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
     APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
+
+    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl",
+                              AUTHZ_PROVIDER_VERSION,
+                              &ssl_authz_provider_require_ssl,
+                              AP_AUTH_INTERNAL_PER_CONF);
+
+    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl-verify-client",
+                              AUTHZ_PROVIDER_VERSION,
+                              &ssl_authz_provider_verify_client,
+                              AP_AUTH_INTERNAL_PER_CONF);
+
+    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl-require",
+                              AUTHZ_PROVIDER_VERSION,
+                              &ssl_authz_provider_sslrequire,
+                              AP_AUTH_INTERNAL_PER_CONF);
+
 }
 
 module AP_MODULE_DECLARE_DATA ssl_module = {
index b9534e56b519b04a5a0dbaaa8027f57f7f5e7a32..b3dbfef63e982a7a6de42be57491285e45f9f2ed 100644 (file)
@@ -1151,7 +1151,7 @@ const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
     ssl_require_t *require;
     const char *errstring;
 
-    if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg, &errstring))) {
+    if (!(expr = ssl_expr_comp(cmd->pool, arg, &errstring))) {
         return apr_pstrcat(cmd->pool, "SSLRequire: ", errstring, NULL);
     }
 
index bc5e64aa09df340c40119fb7a881299abeb29d3a..82fee24daebd89087b71713c25f83ae7dde70015 100644 (file)
@@ -1202,6 +1202,135 @@ int ssl_hook_Fixup(request_rec *r)
     return DECLINED;
 }
 
+/*  _________________________________________________________________
+**
+**  Authz providers for use with mod_authz_core
+**  _________________________________________________________________
+*/
+
+static authz_status ssl_authz_require_ssl_check(request_rec *r,
+                                                const char *require_line,
+                                                const void *parsed)
+{
+    SSLConnRec *sslconn = myConnConfig(r->connection);
+    SSL *ssl = sslconn ? sslconn->ssl : NULL;
+
+    if (ssl)
+        return AUTHZ_GRANTED;
+    else
+        return AUTHZ_DENIED;
+}
+
+static const char *ssl_authz_require_ssl_parse(cmd_parms *cmd,
+                                               const char *require_line,
+                                               const void **parsed)
+{
+    if (require_line && require_line[0])
+        return "'Require ssl' does not take arguments";
+
+    return NULL;
+}
+
+const authz_provider ssl_authz_provider_require_ssl =
+{
+    &ssl_authz_require_ssl_check,
+    &ssl_authz_require_ssl_parse,
+};
+
+static authz_status ssl_authz_verify_client_check(request_rec *r,
+                                                  const char *require_line,
+                                                  const void *parsed)
+{
+    SSLConnRec *sslconn = myConnConfig(r->connection);
+    SSL *ssl = sslconn ? sslconn->ssl : NULL;
+
+    if (!ssl)
+        return AUTHZ_DENIED;
+
+    if (sslconn->verify_error == NULL &&
+        sslconn->verify_info == NULL &&
+        SSL_get_verify_result(ssl) == X509_V_OK)
+    {
+        X509 *xs = SSL_get_peer_certificate(ssl);
+
+        if (xs) {
+            X509_free(xs);
+            return AUTHZ_GRANTED;
+        }
+        else {
+            X509_free(xs);
+        }
+    }
+
+    return AUTHZ_DENIED;
+}
+
+static const char *ssl_authz_verify_client_parse(cmd_parms *cmd,
+                                                 const char *require_line,
+                                                 const void **parsed)
+{
+    if (require_line && require_line[0])
+        return "'Require ssl-verify-client' does not take arguments";
+
+    return NULL;
+}
+
+const authz_provider ssl_authz_provider_verify_client =
+{
+    &ssl_authz_verify_client_check,
+    &ssl_authz_verify_client_parse,
+};
+
+
+static authz_status ssl_authz_sslrequire_check(request_rec *r,
+                                               const char *require_line,
+                                               const void *parsed)
+{
+    const ssl_expr *expr = parsed;
+    const char *errstring;
+    int ok = ssl_expr_exec(r, expr, &errstring);
+
+    if (ok < 0) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                      "Failed to execute SSL requirement expression in "
+                      "'Require ssl-require': %s",
+                      errstring);
+        return AUTHZ_DENIED;
+    }
+
+    if (ok != 1) {
+        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+                      "SSL requirement expression in 'Require ssl-require' "
+                      "not fulfilled");
+        return AUTHZ_DENIED;
+    }
+
+    return AUTHZ_GRANTED;
+}
+
+static const char *ssl_authz_sslrequire_parse(cmd_parms *cmd,
+                                              const char *require_line,
+                                              const void **parsed)
+{
+    const char *errstring;
+    ssl_expr *expr = ssl_expr_comp(cmd->pool, require_line, &errstring);
+
+    if (!expr)
+        return apr_psprintf(cmd->pool, "Error in 'Require require-ssl': %s",
+                            errstring);
+
+    *parsed = expr;
+
+    return NULL;
+}
+
+const authz_provider ssl_authz_provider_sslrequire =
+{
+    &ssl_authz_sslrequire_check,
+    &ssl_authz_sslrequire_parse,
+};
+
+
 /*  _________________________________________________________________
 **
 **  OpenSSL Callback Functions
index 32e3feedfbcbe1903c30cb87e54f80a11e39bed9..04262af1abcead6e7a082a4b73b15c3b3bc3d6aa 100644 (file)
@@ -36,7 +36,7 @@
 */
 
 
-ssl_expr *ssl_expr_comp(apr_pool_t *p, char *expr, const char **err)
+ssl_expr *ssl_expr_comp(apr_pool_t *p, const char *expr, const char **err)
 {
     ssl_expr_info_type context;
     int rc;
@@ -72,7 +72,7 @@ ssl_expr *ssl_expr_make(ssl_expr_node_op op, void *a1, void *a2,
     return node;
 }
 
-int ssl_expr_exec(request_rec *r, ssl_expr *expr, const char **err)
+int ssl_expr_exec(request_rec *r, const ssl_expr *expr, const char **err)
 {
     BOOL rc;
 
index d1391c84e0fba1065fd07a8834fb524259b734ba..049efefd02e0377e94d0ccd0d48b08cd7bd2056c 100644 (file)
@@ -85,9 +85,9 @@ typedef ssl_expr_node ssl_expr;
 
 typedef struct {
     apr_pool_t *pool;
-    char       *inputbuf;
+    const char *inputbuf;
     int         inputlen;
-    char       *inputptr;
+    const char *inputptr;
     ssl_expr   *expr;
     void       *scanner;
     char       *error;
@@ -99,11 +99,11 @@ int  ssl_expr_yylex_init(void **scanner);
 int  ssl_expr_yylex_destroy(void *scanner);
 void ssl_expr_yyset_extra(ssl_expr_info_type *context, void *scanner);
 
-ssl_expr *ssl_expr_comp(apr_pool_t *p, char *exprstr, const char **err);
-int       ssl_expr_exec(request_rec *r, ssl_expr *expr, const char **err);
+ssl_expr *ssl_expr_comp(apr_pool_t *p, const char *exprstr, const char **err);
+int       ssl_expr_exec(request_rec *r, const ssl_expr *expr, const char **err);
 ssl_expr *ssl_expr_make(ssl_expr_node_op op, void *arg1, void *arg2,
                         ssl_expr_info_type *context);
-BOOL      ssl_expr_eval(request_rec *r, ssl_expr *expr, const char **err);
+BOOL      ssl_expr_eval(request_rec *r, const ssl_expr *expr, const char **err);
 
 #endif /* __SSL_EXPR_H__ */
 /** @} */
index ccc86e28cd88cc47af4f1511b61741b947fb45dc..9480048d8906de511c2a5f631ef003fb2b1e6c72 100644 (file)
@@ -41,7 +41,7 @@ static BOOL  ssl_expr_eval_oid(request_rec *r, const char *word,
 static char *ssl_expr_eval_func_file(request_rec *, char *, const char **err);
 static int   ssl_expr_eval_strcmplex(char *, char *, const char **err);
 
-BOOL ssl_expr_eval(request_rec *r, ssl_expr *node, const char **err)
+BOOL ssl_expr_eval(request_rec *r, const ssl_expr *node, const char **err)
 {
     switch (node->node_op) {
         case op_True: {
index 5ead74678e041ebb4996a12afd9da2af1a72d4ab..abf34a223ba2e787e9d4996ec6de91cf0e1c4fc4 100644 (file)
@@ -51,6 +51,7 @@
 #include "apr_global_mutex.h"
 #include "apr_optional.h"
 #include "ap_socache.h"
+#include "mod_auth.h"
 
 #define MOD_SSL_VERSION AP_SERVER_BASEREVISION
 
@@ -613,6 +614,11 @@ int          ssl_hook_ReadReq(request_rec *);
 int          ssl_hook_Upgrade(request_rec *);
 void         ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s);
 
+/** Apache authz provisders */
+extern const authz_provider ssl_authz_provider_require_ssl;
+extern const authz_provider ssl_authz_provider_verify_client;
+extern const authz_provider ssl_authz_provider_sslrequire;
+
 /**  OpenSSL callbacks */
 RSA         *ssl_callback_TmpRSA(SSL *, int, int);
 DH          *ssl_callback_TmpDH(SSL *, int, int);